Aller au contenu

Gouvernance — RBAC

AKKO applique un seul modèle RBAC qui circule depuis Keycloak via OPA jusqu'à chaque service qui touche la donnée. Cette page est la synthèse gouvernance. Pour le guide opérationnel complet (ajout d'utilisateurs, exemples Rego, scripts API, tests), voir Admin / RBAC.

Un modèle, quatre points d'application

flowchart LR
    KC[Keycloak realm akko<br/>5 rôles realm + groupes] --> JWT[JWT avec claim groups]
    JWT --> S1[Service OIDC<br/>Superset, Airflow, Grafana, JupyterHub, MLflow]
    JWT --> OPA[OPA<br/>row filters + column masks]
    JWT --> LLM[LiteLLM<br/>clés virtuelles par rôle]
    OPA --> TR[Trino]
    S1 --> TR
    LLM --> OLL[Ollama]

Quatre points d'application consomment la même identité :

  1. Service OIDC — Superset, Airflow, Grafana, JupyterHub, MLflow mappent le claim groups vers leurs rôles internes.
  2. OPA — Trino délègue l'autorisation, les row filters et les column masks.
  3. Règles fichier Trino — ACL catalogue/schéma/table rechargées toutes les 5 minutes.
  4. LiteLLM — clés API virtuelles scope-limitées par rôle, routage de modèles et rate limits qui suivent l'utilisateur.

Les six rôles effectifs

AKKO livre cinq rôles realm dans Keycloak, plus un rôle implicite service-account pour les identités non humaines. Chaque rôle est la source de vérité — mappé automatiquement vers chaque service aval.

Rôle Persona Visibilité données PII Pouvoir SQL
akko-admin SRE / propriétaire plateforme (Alice) tous catalogues, tous schémas clair DDL, DML, SELECT
akko-engineer Ingénieur data (Bob) raw, staging, analytics, sandbox clair DDL sur schémas désignés, INSERT, SELECT
akko-analyst Analyste sénior (Carol) lecture seule tous schémas clair SELECT uniquement
akko-user Utilisateur standard / conformité (Eve) lecture seule tous schémas masqués (email, phone, ssn, dob, mrn) SELECT uniquement
akko-viewer Exécutif / visualiseur (Dave) analytics, reporting, public masqués SELECT, row-filtered
service-account Jobs CI, dbt, DAGs Airflow scope projet par projet selon token

Mapping par service

Service akko-admin akko-engineer akko-analyst akko-user akko-viewer
Trino DDL + DML DDL sur raw/staging/analytics/sandbox SELECT SELECT + mask PII SELECT + row filter + mask PII
Superset Admin Alpha Gamma Gamma Public
Airflow Admin User Viewer Viewer Viewer
Grafana Admin Editor Viewer Viewer Viewer
JupyterHub admin panel + spawn spawn spawn spawn spawn
MLflow total total total total total
LiteLLM tous modèles, 1000 rpm tous modèles, 200 rpm tous modèles, 100 rpm chat + embed, 50 rpm chat + embed, 20 rpm
OpenMetadata admin navigation + édition navigation + édition navigation navigation
MinIO root root root root root

MinIO, MLflow et Spark utilisent encore des credentials partagés ; l'application par utilisateur est tracée dans le Stream 19 de la roadmap.

OPA — row filters et column masks

OPA est l'autorité pour la sécurité ligne et le caviardage colonne au-dessus des ACL fichier Trino. Les politiques sont rechargées à chaud depuis une ConfigMap, sans redémarrage.

# package trino — extrait

default allow := false

allow if { "akko-admin" in input.context.identity.groups }

# akko-user : SELECT uniquement
allow if {
    "akko-user" in input.context.identity.groups
    input.action.operation in {
        "ExecuteQuery","AccessCatalog","FilterCatalogs","FilterSchemas",
        "FilterTables","FilterColumns","SelectFromColumns",
        "ShowSchemas","ShowTables","ShowColumns","ShowStats"
    }
}

# Column mask PII — s'applique à akko-user et akko-viewer
columnMask := {"expression": "'***MASKED***'", "identity": "mask_pii"} if {
    input.action.resource.column.columnName in {"email","phone","ssn","medical_record_number"}
    not "akko-admin"    in input.context.identity.groups
    not "akko-engineer" in input.context.identity.groups
    not "akko-analyst"  in input.context.identity.groups
}

# Row filter : viewers ne voient que les comptes actifs
rowFilters contains {"expression": "status = 'active'", "identity": "viewer_active_only"} if {
    "akko-viewer" in input.context.identity.groups
    input.action.resource.table.tableName == "accounts"
}

Synchronisation des tags PII depuis OpenMetadata

Un sidecar (opa-sync) interroge OpenMetadata toutes les 5 minutes et pousse les tags PII comme data OPA. Les nouvelles colonnes taguées PII sont masquées automatiquement sans redéploiement de politique. Voir Flux de sécurité.

RBAC LLM

LiteLLM applique des clés virtuelles, des routages et des rate limits par rôle. Voir Admin / RBAC LLM pour la matrice complète.

Rôle Modèles autorisés Rate limit Contexte max
akko-admin tous 1000 rpm 128 k
akko-engineer tous 200 rpm 64 k
akko-analyst chat + embed 100 rpm 32 k
akko-user chat + embed 50 rpm 16 k
akko-viewer chat uniquement 20 rpm 8 k

Fonctions AI Trino — application par UDF

Les 17 UDF ai_* exposées par le plugin Trino contournent la vérification OPA native ExecuteFunction (les UDF de plugin ne passent pas par le SPI d'access-control). Le RBAC est donc appliqué au niveau AI Service :

  1. Le plugin Trino propage X-Trino-User + X-Akko-Ai-Function: ai_<nom> sur chaque appel HTTP.
  2. AI Service résout le rôle realm de l'utilisateur forwarded via l'API Admin Keycloak (cache 5 min) puis vérifie la matrice par fonction.
  3. Les refus renvoient HTTP 403 → SQL NULL (fail-closed) ; chaque décision est journalisée dans Loki (audit_type=AI_RBAC) et comptée dans Prometheus.

Matrice complète 17×5 : voir AI / Fonctions Trino. Source de vérité : helm/akko/charts/akko-ai-service/values.yaml, alignée avec helm/akko/charts/akko-opa/templates/configmap.yaml.

Fédération entreprise

Quand global.auth.mode=enterprise, les utilisateurs de démo sont désactivés et Keycloak fédère :

  • un LDAP corporate (LLDAP ou externe),
  • ou un fournisseur OIDC amont (Azure AD, Okta, Google Workspace, Keycloak, Authentik),
  • ou SAML (ADFS, PingFederate).

Voir Admin / Fournisseur d'identité externe et Admin / Fédération entreprise.

Piste d'audit

Trois flux de logs atterrissent dans Grafana pour la revue forensique :

Source Format Exemples
Événements Keycloak JSON via keycloak-event-listener-http LOGIN, LOGOUT, UPDATE_PASSWORD, TOKEN_REFRESH
Decision log OPA JSON console decision log {user, input, result, policy}
Query log Trino JSON event listener {queryId, user, sql, bytes_scanned, duration}
audit_log ADEN JSON vers Loki aden_query_received, aden_opa_denied, aden_pii_masked

Voir Admin / Playbook d'audit.

Dépannage (top 5)

Symptôme Vérification Correctif
L'utilisateur ne voit aucune donnée dans Superset claim groups dans le JWT, mapping de rôle Superset Se reconnecter ; vérifier l'assignation Keycloak
Colonne visible en clair Rôle admin/engineer/analyst Attendu — le masquage ne s'applique qu'à user/viewer
OAuth2-Proxy rejette l'utilisateur emailVerified à false Activer dans Keycloak
Rôle Airflow / Grafana bloqué après changement Token caché 5 min L'utilisateur doit se déconnecter et se reconnecter
Nouvelle règle OPA non prise en compte ConfigMap pas synchronisée kubectl rollout restart deploy/akko-akko-opa (rare) ou attendre 30 s

Voir aussi