Aller au contenu

Fédération utilisateurs en entreprise

AKKO est conçu pour se brancher directement sur votre infrastructure d'identité existante. Vous n'avez pas à maintenir un jeu de comptes parallèle pour votre équipe data — AKKO délègue l'authentification à Keycloak qui fait le pont avec votre annuaire d'entreprise, et mappe vos groupes corporate sur les rôles de la plateforme.

Cette page est la source unique de vérité pour les clients qui apportent leurs propres utilisateurs. Pour la configuration pas-à-pas d'IdP spécifiques (Azure AD, Okta, Google, LDAP), voir Intégration avec un IdP externe.


Vue d'ensemble — Trois modes d'authentification

AKKO supporte trois modes de déploiement, pilotés par global.auth.mode dans votre fichier de values Helm :

Mode Qui gère les utilisateurs ? Quand l'utiliser
demo (par défaut) directory service embarqué avec comptes seed (alice, bob, carol, eve, dave) Première évaluation, démos, POC interne
enterprise-ldap Votre AD / OpenLDAP / FreeIPA interne Entreprises on-premises avec annuaire
enterprise-oidc IdP OIDC externe (Azure AD / Entra ID, Okta, Auth0, Keycloak externe) SSO cloud-native, fédération multi-tenants

Les trois modes donnent la même expérience dans AKKO : les utilisateurs se connectent une fois, reçoivent un JWT avec leurs rôles plateforme, et chaque service (Trino, Superset, Airflow, Dashboards, JupyterHub, MLflow, ADEN, ...) respecte la même matrice RBAC.

Flux d'authentification

sequenceDiagram
    autonumber
    actor User as Utilisateur corporate
    participant IdP as Votre IdP (AD / Azure / Okta)
    participant KC as Keycloak (AKKO)
    participant OP as oauth2-proxy
    participant CP as Cockpit / UI
    participant TR as Trino + OPA

    User->>CP: 1. GET https://cockpit.<votre-domaine>
    CP->>OP: 2. Requête non authentifiée
    OP->>KC: 3. Redirection vers l'endpoint OIDC authorize
    KC->>IdP: 4. Délégation à l'IdP corporate (brokering ou fédération)
    IdP-->>User: 5. Prompt (mot de passe / MFA / cookie SSO)
    User-->>IdP: 6. Identifiants
    IdP-->>KC: 7. ID token + claim groups
    KC-->>OP: 8. JWT AKKO (sub, email, rôles, attributs)
    OP-->>CP: 9. Pose le cookie de session, transmet les en-têtes X-Auth-*
    CP-->>User: 10. Rend le cockpit

    User->>TR: 11. Requête SQL via Trino JDBC (Bearer token)
    TR->>OPA: 12. Décision OPA (rôle, column mask, row filter)
    OPA-->>TR: 13. Allow / deny / mask
    TR-->>User: 14. Résultats (PII masquée selon le rôle)

Chaque service protégé par oauth2-proxy ou OIDC (Superset, Airflow, Dashboards, Trino, MLflow, JupyterHub, object storage, OpenMetadata) suit le même flux. Les attributs ABAC (data-scope, column-mask, row-filter, ai-tier) se propagent du claim IdP jusqu'à la décision Trino + OPA.


Mode 1 — demo (par défaut)

Quand l'utiliser : première installation, évaluation locale, démos air-gapped, POC interne, environnements de formation.

Ce que vous obtenez :

  • Pod directory service embarqué avec 5 utilisateurs seed : alice (admin), bob (engineer), carol (analyst), eve (user), dave (viewer)
  • 2 comptes de service (svc-aden, svc-superset)
  • Keycloak est fédéré automatiquement avec directory service par le job d'init akko-lldap-federation
  • Les mots de passe sont générés à l'installation, stockés dans le Secret Kubernetes akko-demo-users, et exposés via bash helm/scripts/show-dev-credentials.sh

Values Helm (valeur par défaut — rien à changer) :

global:
  auth:
    mode: "demo"

akko-lldap:
  enabled: true

Dépannage

Symptôme Cause Correction
alice ne peut pas se connecter Le job akko-lldap-federation n'est pas complété kubectl logs -n akko job/akko-lldap-federation; relancer helm upgrade
Mot de passe rejeté Secret pivoté, Keycloak a encore l'ancien hash bash helm/scripts/rotate-secrets.sh --reset-demo-users
Lockout admin Keycloak Mot de passe admin bootstrap perdu Recréer le secret akko-keycloak-admin, redémarrage roulant
Sidebar vide après login Aucun rôle attaché au groupe directory service Ajouter l'utilisateur au groupe directory service akko-admin / akko-engineer / ..., relancer le job de fédération
Login sensible à la casse échoue caseInsensitive: true inactif dans le realm Vérifier global.auth.caseInsensitive et l'attribut realm Keycloak

Ne jamais conserver le mode demo en production

Les comptes seed ont des noms bien connus. Avant tout passage en production, positionner mode: enterprise-ldap ou mode: enterprise-oidc, désactiver akko-lldap, et dérouler la checklist de mise en production (section "Checklist — Déploiement entreprise" plus bas).


Mode 2 — enterprise-ldap

Quand l'utiliser : organisations on-premises avec Active Directory, OpenLDAP, FreeIPA ou autre annuaire LDAP v3.

Ce qu'AKKO fait pour vous :

  • La User Federation Keycloak est configurée via le job d'init configure-federation (API REST Admin Keycloak, idempotent).
  • Un mapper group-to-role est créé depuis global.auth.ldap.roleMapping.
  • directory service embarqué est désactivé.
  • L'admin initial (initialAdmin.username) est conservé comme compte break-glass local.

Values Helm :

global:
  auth:
    mode: "enterprise-ldap"

    initialAdmin:
      enabled: true
      username: "admin-akko"
      email: "admin-akko@corp.example.com"
      # password : fourni via le Secret akko-admin-bootstrap (clé=password)

    ldap:
      connectionUrl: "ldaps://ad.corp.example.com:636"
      bindDn: "cn=svc-akko,ou=service,dc=corp,dc=com"
      bindCredentialSecret: "akko-ldap-bind"     # clé du Secret : password
      usersDn: "ou=employees,dc=corp,dc=com"
      groupsDn: "ou=groups,dc=corp,dc=com"
      usernameLDAPAttribute: "sAMAccountName"    # "uid" pour OpenLDAP/FreeIPA
      vendor: "ad"                                # "other" pour OpenLDAP/FreeIPA
      syncPeriodSeconds: 300
      roleMapping:
        akko-admin:    ["IT-Admins", "Platform-Admins"]
        akko-engineer: ["Data-Engineers", "DevOps"]
        akko-analyst:  ["Business-Analysts", "BI-Team"]
        akko-steward:  ["Data-Stewards"]
        akko-user:     ["Compliance", "Finance"]
        akko-viewer:   ["Management", "Executives"]

akko-lldap:
  enabled: false

Créer le Secret de bind avant installation :

kubectl create namespace akko
kubectl create secret generic akko-ldap-bind \
  --from-literal=password='<MOT_DE_PASSE_LDAP>' \
  -n akko

Déploiement :

helm upgrade --install akko helm/akko/ -n akko --create-namespace \
  --wait --wait-for-jobs --timeout 20m \
  -f helm/examples/values-domain.yaml \
  -f helm/examples/values-enterprise.yaml \
  -f values-ldap-overrides.yaml \
  --set-file akko-keycloak.realm.data=helm/examples/realm-domain.json

Dépannage

Symptôme Cause Correction
« Connection refused » dans le job Firewall / mauvais port Vérifier la joignabilité pod-vers-LDAP : kubectl exec -it deploy/akko-keycloak -- nc -vz ad.corp.example.com 636
Utilisateurs synchronisés sans rôle Mapper group-to-role absent Examiner les logs du job akko-keycloak-federation ; relancer helm upgrade
Échec handshake TLS Keycloak ne fait pas confiance au CA AD Ajouter le CA dans akko-keycloak.extraVolumes et JAVA_OPTS_APPEND=-Djavax.net.ssl.trustStore=...
Doublons d'utilisateurs dans Keycloak READ_ONLY non appliqué Forcer editMode: READ_ONLY ; supprimer les doublons
Période de synchro trop lente 24h par défaut Réduire syncPeriodSeconds (300 en dev, 3600 en prod)

Mode 3 — enterprise-oidc

Quand l'utiliser : vous avez déjà un IdP OIDC (Azure AD / Entra ID, Okta, Auth0, Google Workspace, Keycloak externe) et vous voulez qu'AKKO fasse du brokering plutôt que de fédérer un annuaire.

Ce qu'AKKO fait pour vous :

  • L'Identity Provider Keycloak est configuré automatiquement par le job d'init akko-keycloak-oidc-broker.
  • Le claim groups de l'IdP est mappé sur les rôles realm AKKO.
  • Les attributs ABAC (data-scope, column-mask, row-filter, ai-tier) sont importés tels quels depuis le token IdP.
  • directory service embarqué est désactivé.

Values Helm :

global:
  auth:
    mode: "enterprise-oidc"

    initialAdmin:
      enabled: true
      username: "admin-akko"
      email: "admin-akko@corp.example.com"

    oidc:
      provider: "azure-ad"                         # azure-ad | okta | google | keycloak
      displayName: "Se connecter avec le SSO corporate"
      discoveryUrl: "https://login.microsoftonline.com/<TENANT_ID>/v2.0/.well-known/openid-configuration"
      clientId: "<APPLICATION_CLIENT_ID>"
      clientSecretRef:
        name: "akko-oidc-client"
        key: "secret"
      scopes: "openid profile email groups"
      syncMode: "FORCE"
      trustEmail: true
      groupsClaim: "groups"
      roleMapping:
        akko-admin:    ["<OBJ_ID_OU_NOM_IT_ADMINS>"]
        akko-engineer: ["<OBJ_ID_OU_NOM_DATA_ENG>"]
        akko-analyst:  ["<OBJ_ID_OU_NOM_ANALYSTS>"]
        akko-steward:  ["<OBJ_ID_OU_NOM_STEWARDS>"]
        akko-user:     ["<OBJ_ID_OU_NOM_USERS>"]
        akko-viewer:   ["<OBJ_ID_OU_NOM_EXECS>"]
      # Claims ABAC propagés depuis l'IdP jusqu'au token AKKO
      attributeMapping:
        data-scope: "data_scope"
        column-mask: "column_mask"
        row-filter: "row_filter"
        ai-tier: "ai_tier"
        project-groups: "projects"

akko-lldap:
  enabled: false

Créer le Secret contenant le client secret OIDC :

kubectl create secret generic akko-oidc-client \
  --from-literal=secret='<CLIENT_SECRET_IDP>' \
  -n akko

Déploiement :

helm upgrade --install akko helm/akko/ -n akko --create-namespace \
  --wait --wait-for-jobs --timeout 20m \
  -f helm/examples/values-domain.yaml \
  -f helm/examples/values-enterprise.yaml \
  -f values-oidc-overrides.yaml \
  --set-file akko-keycloak.realm.data=helm/examples/realm-domain.json

Dépannage

Symptôme Cause Correction
« Invalid redirect URI » côté IdP Redirect URI non identique à l'IdP Doit être https://keycloak.<votre-domaine>/realms/akko/broker/<alias>/endpoint
L'utilisateur se connecte sans rôle groupsClaim non émis par l'IdP Azure : ajouter un claim groups dans « Token configuration » ; Okta : scope groups ; Auth0 : ajouter une rule pour émettre les groupes
invalid_client à l'échange du token Client secret pivoté, Secret K8s obsolète Recréer akko-oidc-client, redémarrer Keycloak + le job OIDC broker
DNS split-horizon : le discoveryUrl non résolu dans les pods CoreDNS mal configuré Ajouter hostAliases sur Keycloak ou corriger le résolveur amont
Utilisateurs créés avec mauvais email IdP n'émet pas email_verified Positionner trustEmail: true ou forcer la vérification côté IdP

Apportez vos propres utilisateurs — Attribution manuelle

Si votre IdP corporate n'est pas disponible (ou pour des comptes break-glass), vous pouvez gérer les utilisateurs directement dans Keycloak.

1. Créer les utilisateurs dans l'UI Admin Keycloak

  1. Ouvrir https://keycloak.<votre-domaine>/admin
  2. Se connecter avec l'admin initial (admin-akko)
  3. Sélectionner le realm akko > Users > Add user
  4. Renseigner username, email, nom, prénom
  5. Email verified = On
  6. Enregistrer, puis onglet Credentials, poser un mot de passe temporaire

2. Assigner les rôles realm

Dans l'onglet Role mapping de l'utilisateur > Assign role, affecter un ou plusieurs rôles realm AKKO :

  • akko-admin
  • akko-engineer
  • akko-analyst
  • akko-steward
  • akko-user
  • akko-viewer

3. Poser les attributs ABAC

AKKO applique un contrôle d'accès à base d'attributs (ABAC) par-dessus le RBAC. Positionner ces attributs dans Users > \ > Attributes :

Clé attribut Exemple de valeur Effet
data-scope finance,risk Restreint les requêtes Trino aux schémas taggés sur ces domaines
column-mask email,phone,ssn Force le masquage de ces colonnes même pour les rôles privilégiés
row-filter region = 'EU' Préfixe un row filter Trino à chaque requête
ai-tier standard (ou premium, restricted) Contrôle l'accès aux modèles LiteLLM (GPT-4 vs. Ollama local)

Ces attributs sont émis dans le JWT via des protocol mappers et consommés par les policies OPA dans Trino, ainsi que par le middleware ABAC AKKO dans JupyterHub + Superset + ADEN.

4. Groupes projet

L'isolation projet se modélise via des groupes Keycloak préfixés projet- :

  1. Groups > Create group > projet-risk
  2. Ajouter les membres
  3. Les règles OPA lisent le claim groups et restreignent iceberg.projet_risk.* aux membres
  4. Les buckets object storage projet-risk/* héritent de la même restriction via le mapper OIDC object storage

Voir Architecture de la gouvernance pour le modèle complet de groupes et l'arborescence des règles OPA.


Mapping des rôles — Rôle corporate → Rôle AKKO

Utilisez ce tableau comme point de départ pour votre roleMapping. Adaptez les noms de groupes à ceux de votre IdP.

Rôle corporate Rôle AKKO Permissions
CTO, VP Data, Platform Owner, SRE Lead akko-admin Accès complet à tous les services + consoles admin, PII en clair, gestion RBAC + ABAC, édition des policies OPA
Data Engineer, Platform Engineer, DevOps akko-engineer CREATE / INSERT / SELECT sur Iceberg, gestion des pipelines (Airflow, dbt), jobs Spark, pas de masquage PII, MLflow, LiteLLM (1000 req/jour)
Data Analyst senior, Data Scientist akko-analyst SELECT sur tous les schémas, PII complète sur les scopes autorisés, création de dashboards (Superset), notebooks (JupyterHub), requêtes NL via ADEN
Data Steward, Data Governance Lead akko-steward Ownership catalogue (OpenMetadata), classification de données, glossaire, lineage éditable, SELECT limité + accès LLM embeddings
Utilisateur métier, Compliance, Finance akko-user SELECT sur schémas publiés, colonnes PII masquées (email, téléphone, NIR, date de naissance), dashboards en lecture seule, requêtes en langage naturel
Exécutif, Auditeur, Consultant externe akko-viewer Dashboards publiés en lecture seule, row filters appliqués, PII masquée, pas de SQL direct, aucune écriture

Règle d'or : commencer restrictif, élargir via les attributs ABAC (data-scope, row-filter) plutôt que par une promotion de rôle.


Checklist — Déploiement entreprise

Dérouler cette checklist avant toute mise en production. Chaque item est obligatoire pour un déploiement entreprise.

  • [ ] 1. Certificat TLS. Soit cert-manager (global.tls.issuer), soit Secret TLS apporté référencé par global.tls.secretName. Les certificats auto-signés sont interdits en production.
  • [ ] 2. Mode d'authentification. global.auth.mode à enterprise-ldap ou enterprise-oidc. akko-lldap.enabled à false. Vérifié en rendant le chart et en grep-ant lldap.
  • [ ] 3. Role mapping défini. Chaque groupe auquel vos utilisateurs appartiennent est mappé sur exactement un rôle AKKO dans global.auth.ldap.roleMapping ou global.auth.oidc.roleMapping. Pas de wildcard *.
  • [ ] 4. Attributs ABAC synchronisés. Les attributs utilisateur (data-scope, column-mask, row-filter, ai-tier) sont émis en tant que claims JWT. Vérifié via curl ... /userinfo | jq ..
  • [ ] 5. Logs d'audit envoyés au SIEM corporate. logs layer est configuré pour forwarder vers votre SIEM (Splunk, Elastic, Datadog) via le ruler.remote_write logs layer ou un log shipper dédié. Les événements Keycloak, les décisions OPA et les query logs Trino sont inclus.
  • [ ] 6. Backup et DR configurés. akko-postgresql, akko-postgresql-data, export du realm Keycloak, réplication des buckets object storage, métadonnées Polaris — tous couverts par un job quotidien Velero / pgBackRest / mirror object storage.
  • [ ] 7. Utilisateurs demo désactivés. Aucun compte alice, bob, carol, dave, eve ne reste. Vérifié avec kubectl exec deploy/akko-keycloak -- /opt/keycloak/bin/kcadm.sh get users -r akko --fields username.
  • [ ] 8. Admin break-glass documenté. Le mot de passe initialAdmin.username est stocké dans votre coffre de secrets corporate (HashiCorp Vault, AWS Secrets Manager, etc.), procédure de rotation documentée.
  • [ ] 9. NetworkPolicies appliquées. global.networkPolicies.enabled=true. Aucun pod ne peut sortir sur Internet sauf autorisation explicite (LiteLLM upstream, MLflow artefact store).
  • [ ] 10. Keycloak durci. KC_HOSTNAME_STRICT=true, KC_HTTP_ENABLED=false, détection brute-force activée dans le realm, MFA requis pour akko-admin.

Une fois les dix cases cochées, lancer bash helm/scripts/lint-no-hardcoding.sh (la CI le lance aussi) et bash tests/run-all.sh pour valider la pile end-to-end.


Pour aller plus loin