RBAC — Contrôle d'accès basé sur les rôles¶
AKKO implémente un modèle de sécurité à 4 couches qui applique le contrôle d'accès de l'authentification jusqu'à l'exécution des requêtes :
Keycloak (authentification) → OPA (autorisation) → Trino (application des requêtes) → Superset (filtrage des tableaux de bord)
Chaque utilisateur s'authentifie via le SSO Keycloak, reçoit des claims de rôle dans son jeton JWT, et ces rôles sont appliqués par les politiques OPA dans Trino, les mappings de rôles dans Superset/Airflow/Dashboards, et le filtrage réseau via OAuth2-Proxy pour les services sans OIDC natif.
Kubernetes-first
Toute la configuration RBAC est déployée via Helm. Le realm Keycloak est importé depuis realm-akko-k3d.json, les politiques OPA depuis un ConfigMap, et les règles Trino depuis des fichiers montés. Aucune étape manuelle requise après helm install.
Rôles¶
AKKO définit cinq rôles de realm à l'échelle de la plateforme dans Keycloak :
| Rôle | Description | Persona | Niveau d'accès |
|---|---|---|---|
akko-admin |
Administrateur de la plateforme | Alice Chen -- SRE / propriétaire | Accès complet à tous les services, consoles admin, DDL/DML, aucun masquage |
akko-engineer |
Ingénieur de données | Bob Martin -- construit les pipelines | CREATE/INSERT/SELECT sur Iceberg, gestion des pipelines, pas de masquage PII |
akko-analyst |
Analyste senior | Carol Santos -- explore les données | SELECT uniquement, visibilité complète PII, tableaux de bord, notebooks |
akko-user |
Utilisateur standard / conformité | Eve Dupont -- audite les données | SELECT uniquement, colonnes PII masquées (email, téléphone, SSN, date de naissance) |
akko-viewer |
Exécutif / visualiseur de tableaux de bord | Dave Kim -- consulte les tableaux de bord | SELECT sur schémas limités, filtré par lignes, PII masqué |
Rôle par défaut
Les nouveaux utilisateurs se voient automatiquement attribuer akko-analyst via le rôle composite default-roles-akko. Cela inclut offline_access et uma_authorization.
Matrice d'accès¶
Accès par service¶
| Service | akko-admin | akko-engineer | akko-analyst | akko-user | akko-viewer |
|---|---|---|---|---|---|
| Keycloak (console admin) | Complet | -- | -- | -- | -- |
| Trino (SQL) | DDL/DML complet | DDL/DML sur schémas désignés | SELECT uniquement | SELECT, PII masqué | SELECT, filtré + masqué |
| Superset | Rôle Admin | Rôle Alpha | Rôle Gamma | Rôle Gamma | Rôle Public |
| Airflow | Admin | User | Viewer | Viewer | Viewer |
| Dashboards | Admin | Editor | Viewer | Viewer | Viewer |
| JupyterHub | Panneau admin + spawn | Spawn | Spawn | Spawn | Spawn |
| MLflow | Complet | Complet | Complet | Complet | Complet |
| LiteLLM | Complet (clé maître) | Complet | Complet | Complet | Complet |
| object storage | Root | Root | Root | Root | Root |
| OpenMetadata | Admin | Navigation + édition | Navigation + édition | Navigation | Navigation |
Services sans RBAC granulaire
MLflow, LiteLLM, object storage et Spark utilisent actuellement des identifiants partagés. L'accès est contrôlé au niveau réseau (OAuth2-Proxy pour MLflow, clé maître pour LiteLLM, identifiants root pour object storage). Le RBAC par utilisateur pour ces services est prévu dans la feuille de route.
Accès aux catalogues Trino¶
| Rôle | Iceberg | PostgreSQL | System |
|---|---|---|---|
| akko-admin | tout (propriétaire) | tout (propriétaire) | tout |
| akko-engineer | tout (DDL sur raw, staging, analytics, sandbox) |
tout (DDL) | lecture seule |
| akko-analyst | lecture seule (tous les schémas) | lecture seule | lecture seule |
| akko-user | lecture seule (tous les schémas, PII masqué) | lecture seule | lecture seule |
| akko-viewer | lecture seule (analytics, reporting, public uniquement) |
-- | lecture seule |
| (défaut) | -- | -- | lecture seule |
Privilèges sur les tables Trino (Iceberg)¶
| Rôle | Schémas | Privilèges |
|---|---|---|
| akko-admin | tous | SELECT, INSERT, DELETE, UPDATE, OWNERSHIP, GRANT_SELECT |
| akko-engineer | raw, staging, analytics, sandbox |
SELECT, INSERT, DELETE, UPDATE |
| akko-analyst | tous | SELECT |
| akko-user | tous | SELECT (PII masqué) |
| akko-viewer | analytics, reporting, public |
SELECT (filtré par lignes, PII masqué) |
Configuration Keycloak¶
Structure du realm¶
Toute la configuration d'identité AKKO se trouve dans un realm Keycloak unique nommé akko, importé depuis realm-akko-k3d.json au premier démarrage.
Paramètres principaux :
| Paramètre | Valeur |
|---|---|
| Nom du realm | akko |
| Thème de connexion | akko (personnalisé) |
| Durée de vie du jeton d'accès | 300s (5 min) |
| Session SSO maximale | 36000s (10 heures) |
| Inscription | Désactivée |
| Protection brute force | Activée (5 échecs, verrouillage 5 min) |
Définition des rôles¶
Les rôles sont définis comme des rôles de realm (et non des rôles de client). Chaque rôle est mappé à un claim de groupe via le mapper de protocole groups, qui émet les noms de rôles dans le tableau groups du JWT.
Le mapper groups est configuré dans les scopes client microprofile-jwt et spécifiques aux services :
{
"name": "groups",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-realm-role-mapper",
"config": {
"multivalued": "true",
"claim.name": "groups",
"id.token.claim": "true",
"access.token.claim": "true"
}
}
Cela garantit que lorsqu'un utilisateur se connecte, ses rôles apparaissent dans le jeton JWT sous forme de groups, que OPA, Trino et les autres services utilisent pour les décisions d'autorisation.
Clients OAuth2¶
13 clients OAuth2 sont préconfigurés dans le realm :
| Client | Type | Mappe les rôles |
|---|---|---|
jupyterhub |
Confidentiel | Oui (flag admin) |
superset |
Confidentiel | Oui (Admin/Alpha/Gamma/Public) |
airflow |
Confidentiel | Oui (Admin/User/Viewer) |
grafana |
Confidentiel | Oui (Admin/Editor/Viewer) |
trino |
Confidentiel | Oui (via groupes OPA) |
openmetadata |
Confidentiel | Partiel |
polaris |
Confidentiel | Non |
oauth2-proxy |
Confidentiel | Non (contrôle réseau) |
minio |
Confidentiel | Non |
account |
Public | Non (interne Keycloak) |
account-console |
Public (PKCE) | Non (interne Keycloak) |
admin-cli |
Public | Non (interne Keycloak) |
broker |
Confidentiel | Non (interne Keycloak) |
realm-management |
Confidentiel | Non (interne Keycloak) |
security-admin-console |
Public | Non (interne Keycloak) |
Pas de client cockpit
Le cockpit AKKO utilise l'adaptateur JavaScript Keycloak avec les clients publics account ou account-console pour la détection de session. Il ne dispose pas de son propre client OAuth2 dédié dans le realm.
Attribuer un rôle à un utilisateur¶
- Ouvrir la console d'administration Keycloak :
https://identity.akko.local/admin/ - Sélectionner le realm akko
- Naviguer vers Users et sélectionner l'utilisateur (ou en créer un nouveau)
- Aller dans l'onglet Role mapping
- Cliquer sur Assign role et filtrer par rôles de realm
- Sélectionner le rôle souhaité (
akko-admin,akko-engineer,akko-analyst,akko-userouakko-viewer)
emailVerified doit être true
Tous les utilisateurs doivent avoir emailVerified=true. Le service oauth2-proxy rejette les utilisateurs sans email vérifié, causant des échecs de connexion pour JupyterHub et les autres services protégés par proxy.
Politiques OPA¶
OPA (Open Policy Agent) fournit une autorisation policy-as-code pour Trino. Les politiques sont écrites en Rego et déployées sous forme de ConfigMap.
Architecture¶
Trino délègue trois types de décisions à OPA :
- Autorisation -- cet utilisateur peut-il exécuter cette opération ?
- Filtrage par lignes -- quelles lignes cet utilisateur peut-il voir ?
- Masquage de colonnes -- les colonnes sensibles doivent-elles être masquées ?
Intégration Trino-OPA¶
Trino est configuré pour appeler OPA à chaque requête :
access-control.name=opa
opa.policy.uri=http://akko-akko-opa:8181/v1/data/trino/allow
opa.policy.row-filters-uri=http://akko-akko-opa:8181/v1/data/trino/rowFilters
opa.policy.column-masking-uri=http://akko-akko-opa:8181/v1/data/trino/columnMask
Politique de contrôle d'accès¶
La politique principale (trino_access.rego) mappe les opérations aux rôles. Voici la politique réelle déployée via ConfigMap dans helm/akko/charts/akko-opa/templates/configmap.yaml :
package trino
import rego.v1
default allow := false
# Les administrateurs peuvent tout faire
allow if {
"akko-admin" in input.context.identity.groups
}
# Ingénieurs : SELECT, INSERT, CREATE TABLE, DROP TABLE, ALTER
allow if {
"akko-engineer" in input.context.identity.groups
input.action.operation in [
"ExecuteQuery", "AccessCatalog", "FilterCatalogs",
"FilterSchemas", "FilterTables", "FilterColumns",
"SelectFromColumns", "ShowSchemas", "ShowTables",
"ShowColumns", "ShowCreateTable", "ShowFunctions",
"ShowStats", "CreateTable", "InsertIntoTable",
"AddColumn", "DropTable", "RenameTable"
]
}
# Analystes (senior) : SELECT uniquement, visibilité complète (pas de masquage)
allow if {
"akko-analyst" in input.context.identity.groups
input.action.operation in [
"ExecuteQuery", "AccessCatalog", "FilterCatalogs",
"FilterSchemas", "FilterTables", "FilterColumns",
"SelectFromColumns", "ShowSchemas", "ShowTables",
"ShowColumns", "ShowCreateTable", "ShowFunctions",
"ShowStats"
]
}
# Utilisateurs standard (conformité) : SELECT uniquement, PII masqué (voir column_masking.rego)
allow if {
"akko-user" in input.context.identity.groups
input.action.operation in [
"ExecuteQuery", "AccessCatalog", "FilterCatalogs",
"FilterSchemas", "FilterTables", "FilterColumns",
"SelectFromColumns", "ShowSchemas", "ShowTables",
"ShowColumns", "ShowCreateTable", "ShowFunctions",
"ShowStats"
]
}
# Viewers (exécutifs) : SELECT + métadonnées, filtré par lignes + PII masqué
allow if {
"akko-viewer" in input.context.identity.groups
input.action.operation in [
"ExecuteQuery", "AccessCatalog", "FilterCatalogs",
"FilterSchemas", "FilterTables", "FilterColumns",
"SelectFromColumns", "ShowSchemas", "ShowTables",
"ShowColumns", "ShowCreateTable", "ShowFunctions",
"ShowStats"
]
}
# Identité de filtre par lignes : Trino revérifie les permissions avec l'identité du filtre
allow if {
input.context.identity.user == "viewer_active_only"
}
Politique de masquage des colonnes¶
Les colonnes PII sont masquées pour les rôles akko-user et akko-viewer. Les administrateurs, ingénieurs et analystes voient les données en clair :
# Colonnes PII texte : email, phone, ssn, medical_record_number
columnMask := {"expression": expression, "identity": identity} 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
expression := "'***MASKED***'"
identity := "mask_pii"
}
# Colonnes PII date : date_of_birth (NULL type-safe)
columnMask := {"expression": expression, "identity": identity} if {
input.action.resource.column.columnName in ["date_of_birth"]
not "akko-admin" in input.context.identity.groups
not "akko-engineer" in input.context.identity.groups
not "akko-analyst" in input.context.identity.groups
expression := "CAST(NULL AS DATE)"
identity := "mask_pii"
}
Résumé du masquage :
| Colonne | admin | engineer | analyst | user | viewer |
|---|---|---|---|---|---|
email |
clair | clair | clair | ***MASKED*** |
***MASKED*** |
phone |
clair | clair | clair | ***MASKED*** |
***MASKED*** |
ssn |
clair | clair | clair | ***MASKED*** |
***MASKED*** |
medical_record_number |
clair | clair | clair | ***MASKED*** |
***MASKED*** |
date_of_birth |
clair | clair | clair | NULL |
NULL |
Politique de filtrage par lignes¶
Les filtres par lignes restreignent les lignes visibles par rôle :
# Les viewers ne peuvent voir que les comptes actifs
rowFilters contains {"expression": expression, "identity": identity} if {
"akko-viewer" in input.context.identity.groups
input.action.resource.table.tableName == "accounts"
expression := "status = 'active'"
identity := "viewer_active_only"
}
Actuellement, seule la table accounts a un filtre par lignes pour akko-viewer. Des filtres supplémentaires peuvent être ajoutés par table selon les besoins.
Ajouter une nouvelle politique OPA¶
Les politiques OPA sont définies en ligne dans le template ConfigMap à helm/akko/charts/akko-opa/templates/configmap.yaml. Le ConfigMap contient trois fichiers Rego :
| Fichier | Objectif |
|---|---|
trino_access.rego |
Règles autoriser/refuser par opération et par rôle |
column_masking.rego |
Règles de masquage des colonnes PII |
row_filter.rego |
Filtres de sécurité au niveau des lignes |
Étape par étape : Ajouter une nouvelle règle d'accès
- Ouvrir
helm/akko/charts/akko-opa/templates/configmap.yaml -
Ajouter votre règle Rego dans la section
.regoappropriée. Par exemple, pour ajouter un filtrage par lignes sur la tabletransactionspour les viewers : -
Si le filtre utilise une identité personnalisée (comme
viewer_small_txn_only), ajouter une règle allow correspondante danstrino_access.rego: -
Déployer la politique mise à jour :
-
OPA recharge les politiques à chaud depuis le ConfigMap -- aucun redémarrage de pod nécessaire. Vérifier que la politique est chargée :
# Vérifier qu'OPA a la politique mise à jour kubectl exec -n akko deploy/akko-akko-opa -- \ curl -s http://localhost:8181/v1/policies | python3 -m json.tool # Tester la politique avec un exemple d'entrée kubectl exec -n akko deploy/akko-akko-opa -- \ curl -s -X POST http://localhost:8181/v1/data/trino/allow \ -d '{"input":{"context":{"identity":{"user":"dave","groups":["akko-viewer"]}},"action":{"operation":"SelectFromColumns","resource":{"table":{"catalogName":"iceberg","schemaName":"banking","tableName":"transactions"}}}}}' \ | python3 -m json.tool
Tester les politiques localement
Avant de déployer, testez la syntaxe Rego localement :
Application dans Trino¶
En plus d'OPA, Trino utilise un contrôle d'accès basé sur des fichiers pour les permissions de catalogue/schéma/table. Les deux systèmes fonctionnent ensemble :
- OPA gère l'autorisation au niveau des opérations (autoriser/refuser), le masquage des colonnes et le filtrage par lignes
- Les règles basées sur fichiers (
rules.json) appliquent l'accès catalogue/schéma/table avec des privilèges granulaires
Mappings de groupes¶
Trino mappe les utilisateurs aux groupes via group.txt :
akko-admin:admin,alice,trino,airflow
akko-engineer:bob
akko-analyst:carol
akko-user:eve
akko-viewer:dave
Utilisateurs de service
Les utilisateurs trino et airflow doivent être dans le groupe akko-admin. Trino utilise trino pour les opérations internes, et Airflow se connecte en tant que airflow pour exécuter les requêtes de pipeline.
Groupe utilisateur standard
Le groupe akko-user correspond à Eve (analyste conformité). Quand OPA évalue les règles de masquage de colonnes, il vérifie le claim groups dans le JWT -- le fichier Trino group.txt est utilisé pour les règles de contrôle d'accès basées sur fichiers, pas pour les décisions OPA.
Évaluation des règles¶
Les règles dans rules.json sont évaluées de haut en bas, première correspondance gagne. Le fichier comporte trois sections : catalogs, schemas et tables. Une règle de refus générique à la fin bloque les accès non correspondants :
Période de rafraîchissement¶
Les fichiers rules.json et group.txt sont rafraîchis toutes les 5 minutes. Les modifications prennent effet sans redémarrage de Trino.
Sécurité au niveau des lignes dans Superset¶
Superset mappe les rôles Keycloak à ses rôles internes :
| Rôle Keycloak | Rôle Superset | Capacités |
|---|---|---|
akko-admin |
Admin | Tous les tableaux de bord, SQL Lab, datasets, paramètres admin |
akko-engineer |
Alpha | Créer des tableaux de bord, SQL Lab, datasets |
akko-analyst |
Gamma | Voir les tableaux de bord, SQL Lab, voir les datasets |
akko-user |
Gamma | Voir les tableaux de bord, SQL Lab, voir les datasets |
akko-viewer |
Public | Voir les tableaux de bord publics uniquement, pas de SQL Lab |
Superset se connecte à Trino en utilisant l'utilisateur de service trino (qui a les privilèges akko-admin). Cela signifie que le masquage des colonnes et le filtrage par lignes d'OPA ne sont pas appliqués au niveau Superset-vers-Trino. Superset applique l'accès via son propre système de rôles :
- Visibilité des tableaux de bord -- le rôle Public ne peut voir que les tableaux de bord explicitement publiés
- SQL Lab -- seuls les rôles Admin, Alpha et Gamma ont accès à SQL Lab
- Accès aux datasets -- les datasets sont contrôlés par les permissions de rôle Superset
Application de bout en bout
Pour un filtrage complet des données par utilisateur à travers Superset, l'approche recommandée est de configurer Superset pour transmettre l'identité réelle de l'utilisateur à Trino (au lieu de l'utilisateur partagé trino), afin que les politiques OPA s'appliquent aux requêtes des tableaux de bord. Ceci est prévu pour une version future.
Gestion des utilisateurs¶
Ajouter un nouvel utilisateur (interface web)¶
- Ouvrir la console d'administration Keycloak à
https://identity.akko.local/admin/ - Se connecter avec les identifiants admin (voir
values-dev.yamlpour le mot de passe dev, ouglobal.auth.keycloakAdminPasswordpour la production) - Sélectionner le realm akko (menu déroulant en haut à gauche)
- Naviguer vers Users > Add user
- Remplir les champs requis :
- Username (requis, minuscules, sans espaces)
- Email (requis -- OAuth2-Proxy rejette les utilisateurs sans email)
- First name, Last name
- Basculer Email verified sur ON
- Cliquer sur Create
- Aller dans l'onglet Credentials :
- Cliquer sur Set password
- Saisir le mot de passe et confirmer
- Basculer Temporary sur OFF pour les comptes de service ou de test
- Cliquer sur Save
- Aller dans l'onglet Role mapping :
- Cliquer sur Assign role
- Dans le menu déroulant de filtre, sélectionner Filter by realm roles
- Sélectionner le rôle souhaité (
akko-admin,akko-engineer,akko-analyst,akko-userouakko-viewer) - Cliquer sur Assign
Ajouter un nouvel utilisateur (API Admin Keycloak)¶
Pour l'automatisation ou les pipelines CI/CD, utiliser l'API REST Admin Keycloak :
# 1. Obtenir un jeton admin
ADMIN_TOKEN=$(kubectl exec -n akko deploy/akko-keycloak -- \
curl -s -X POST http://localhost:8080/realms/master/protocol/openid-connect/token \
-d "client_id=admin-cli&grant_type=password&username=admin&password=<mot-de-passe-admin>" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
# 2. Créer l'utilisateur
kubectl exec -n akko deploy/akko-keycloak -- \
curl -s -X POST http://localhost:8080/admin/realms/akko/users \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "newuser",
"email": "newuser@company.com",
"firstName": "Nouveau",
"lastName": "Utilisateur",
"enabled": true,
"emailVerified": true,
"credentials": [{"type": "password", "value": "mot-de-passe-fort", "temporary": false}]
}'
# 3. Obtenir l'ID de l'utilisateur
USER_ID=$(kubectl exec -n akko deploy/akko-keycloak -- \
curl -s http://localhost:8080/admin/realms/akko/users?username=newuser \
-H "Authorization: Bearer $ADMIN_TOKEN" \
| python3 -c "import sys,json; print(json.load(sys.stdin)[0]['id'])")
# 4. Obtenir l'ID du rôle (ex : akko-analyst)
ROLE_ID=$(kubectl exec -n akko deploy/akko-keycloak -- \
curl -s http://localhost:8080/admin/realms/akko/roles/akko-analyst \
-H "Authorization: Bearer $ADMIN_TOKEN" \
| python3 -c "import sys,json; r=json.load(sys.stdin); print(r['id'])")
# 5. Attribuer le rôle
kubectl exec -n akko deploy/akko-keycloak -- \
curl -s -X POST \
"http://localhost:8080/admin/realms/akko/users/$USER_ID/role-mappings/realm" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d "[{\"id\": \"$ROLE_ID\", \"name\": \"akko-analyst\"}]"
Alternative port-forward
Si vous préférez exécuter les commandes depuis votre machine locale plutôt que via kubectl exec, faites d'abord un port-forward du pod Keycloak :
Vérification de l'accès¶
Après avoir attribué un rôle, vérifier que le jeton de l'utilisateur contient les bons claims :
# Obtenir un jeton pour l'utilisateur (via le client JupyterHub, qui a le mapper groups)
TOKEN=$(kubectl exec -n akko deploy/akko-keycloak -- \
curl -s -X POST http://localhost:8080/realms/akko/protocol/openid-connect/token \
-d "grant_type=password&client_id=jupyterhub&client_secret=akko-dev-jupyterhub-oidc&username=alice&password=alice123&scope=openid" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
# Décoder le JWT et vérifier le claim groups
echo "$TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool
# Résultat attendu inclut : "groups": ["akko-admin", "default-roles-akko", ...]
Que vérifier dans le JWT
- Le tableau
groupsdoit contenir le nom du rôle attribué (ex :akko-admin) - Le champ
email_verifieddoit êtretrue - Le
preferred_usernamedoit correspondre au nom d'utilisateur - Le
iss(émetteur) doit êtrehttps://identity.akko.local/realms/akko
Révoquer l'accès¶
Retirer un rôle à un utilisateur (interface web)¶
- Ouvrir
https://identity.akko.local/admin/et sélectionner le realm akko - Naviguer vers Users et sélectionner l'utilisateur
- Aller dans l'onglet Role mapping
- Trouver le rôle à retirer et cliquer sur le bouton X (désattribuer) à côté
- L'utilisateur doit se déconnecter puis se reconnecter pour que le changement prenne effet (les jetons JWT sont valides jusqu'à expiration -- 5 minutes par défaut)
Retirer un rôle à un utilisateur (API Admin)¶
# Retirer le rôle akko-engineer d'un utilisateur
kubectl exec -n akko deploy/akko-keycloak -- \
curl -s -X DELETE \
"http://localhost:8080/admin/realms/akko/users/$USER_ID/role-mappings/realm" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d "[{\"id\": \"$ROLE_ID\", \"name\": \"akko-engineer\"}]"
Désactiver un utilisateur entièrement¶
- Interface web : Naviguer vers l'utilisateur, basculer Enabled sur OFF, cliquer sur Save
- API Admin :
Forcer la déconnexion (invalider les sessions actives)¶
# Déconnecter toutes les sessions d'un utilisateur spécifique
kubectl exec -n akko deploy/akko-keycloak -- \
curl -s -X POST \
"http://localhost:8080/admin/realms/akko/users/$USER_ID/logout" \
-H "Authorization: Bearer $ADMIN_TOKEN"
Délai d'expiration des jetons
Révoquer un rôle ou désactiver un utilisateur ne bloque pas immédiatement l'accès. Les jetons JWT existants restent valides jusqu'à leur expiration (par défaut : 5 minutes). Les services qui cachent les jetons (Superset, Dashboards) peuvent nécessiter que l'utilisateur se déconnecte puis se reconnecte.
Ajouter un utilisateur aux groupes Trino basés sur fichiers¶
Si Trino utilise le contrôle d'accès basé sur fichiers en plus d'OPA, les nouveaux utilisateurs doivent être ajoutés à group.txt :
- Éditer le fichier de groupes Trino dans le chart Helm (l'emplacement exact dépend de la structure de votre chart)
- Ajouter le nom d'utilisateur à la ligne de groupe appropriée :
- Mettre à jour la release Helm :
- Attendre jusqu'à 5 minutes que Trino recharge le fichier (ou redémarrer le pod coordinateur Trino)
Utilisateurs de test par défaut¶
| Nom d'utilisateur | Rôle | Mot de passe | Nom complet | |
|---|---|---|---|---|
alice |
akko-admin |
alice123 |
alice@akko.local | Alice Chen |
bob |
akko-engineer |
bob123 |
bob@akko.local | Bob Martin |
carol |
akko-analyst |
carol123 |
carol@akko.local | Carol Santos |
eve |
akko-user |
eve123 |
eve@akko.local | Eve Dupont |
dave |
akko-viewer |
dave123 |
dave@akko.local | Dave Kim |
Tous les utilisateurs de test ont emailVerified=true et enabled=true. Alice a également le rôle client realm-admin, lui donnant accès à la console d'administration Keycloak.
Mots de passe de test
Dans le realm de développement (realm-akko-k3d.json), les mots de passe suivent le modèle <nom_utilisateur>123. Ne jamais utiliser ces identifiants en production. Utilisez des mots de passe forts, des fournisseurs d'identité externes (LDAP, SAML) ou les politiques de mots de passe de Keycloak.
Dépannage¶
L'utilisateur ne peut pas accéder à un service¶
- Vérifier le jeton JWT -- vérifier que le claim
groupscontient le rôle attendu - Vérifier emailVerified -- doit être
truepour les services protégés par OAuth2-Proxy - Vérifier la session Keycloak -- l'utilisateur peut avoir une ancienne session avec des claims de rôle obsolètes. Se déconnecter puis se reconnecter.
Mauvaises permissions dans Trino¶
- Vérifier group.txt -- vérifier que l'utilisateur est dans le bon groupe Trino
- Vérifier les logs OPA --
kubectl logs -n akko deploy/akko-akko-opapour voir les évaluations de politique - Vérifier rules.json -- les règles fonctionnent en première correspondance ; une règle plus haute dans la liste peut correspondre en premier
- Attendre le rafraîchissement -- Trino rafraîchit les fichiers de groupes et de règles toutes les 5 minutes
Le masquage des colonnes ne fonctionne pas¶
- Vérifier le nom de la colonne -- doit correspondre à un nom dans la politique OPA (
email,phone,ssn,medical_record_number,date_of_birth) - Vérifier le rôle de l'utilisateur -- seuls
akko-useretakko-viewervoient les valeurs masquées - Tester via CLI -- utiliser
curlpour interroger Trino directement avec le jeton de l'utilisateur pour exclure le cache de Superset
Le rôle ne se propage pas à Superset/Airflow/Dashboards¶
Ces services mappent les rôles Keycloak aux rôles internes au moment de la connexion. Si un rôle change :
- L'utilisateur doit se déconnecter du service
- Effacer la session du service (ou utiliser une fenêtre de navigation privée)
- Se reconnecter -- le nouveau rôle sera mappé
Exécuter les tests RBAC¶
# Tous les tests d'intégration RBAC
pytest tests/integration/ -m rbac -v
# Tests de sécurité (inclut l'application des politiques OPA)
pytest tests/integration/ -m security -v
# Service spécifique
pytest tests/integration/test_rbac_grafana.py -v
# Suite de tests complète
bash tests/run-all.sh --fast
Décisions d'architecture¶
| ADR | Décision |
|---|---|
| Keycloak comme IdP | Source unique de vérité pour l'identité. Tous les services s'authentifient via OIDC. |
| OPA pour Trino ABAC | Policy-as-code permet la sécurité au niveau des lignes et des colonnes sans modifier Trino. |
| Règles Trino basées sur fichiers | Complément à OPA pour les permissions catalogue/schéma/table. Rafraîchissement de 5 minutes. |
| Rôles de realm (pas de rôles client) | Gestion simplifiée. Un rôle par utilisateur, visible sur tous les clients via le claim groups. |
| 5 rôles | Couvre les personas admin, ingénierie, analyse, conformité et exécutif. Extensible selon les besoins. |