Flux de sécurité¶
AKKO applique une défense à 4 couches qui propage l'identité de l'utilisateur du navigateur jusqu'au plan de données :
- Authentification — SSO Keycloak (source unique, 13 clients OAuth, 5 rôles).
- Autorisation — OPA (politiques fines et contextuelles synchronisées avec les groupes Keycloak).
- Application côté requête — row-filters + column-masks Trino via le plugin OPA.
- Audit — logs structurés (Loki) + événements Keycloak + query log Trino + decision log OPA.
Flux d'authentification de bout en bout¶
sequenceDiagram
participant B as Navigateur
participant T as Traefik (TLS)
participant O2P as oauth2-proxy
participant S as Service (Superset / JupyterHub)
participant KC as Keycloak
participant OPA as OPA
participant TR as Trino
participant OM as OpenMetadata
B->>T: https://bi.akko.local
T->>O2P: vérification ForwardAuth (services sans OIDC natif)
O2P->>KC: redirection vers /auth (OIDC)
B->>KC: login (utilisateur + mot de passe / MFA)
KC-->>B: ID token + access token (claim roles)
B->>S: requête avec bearer token
S->>KC: validation JWT (JWKS)
KC-->>S: ok
S->>TR: SQL avec X-Trino-User + token
TR->>OPA: POST /v1/data/trino/allow {user, roles, query, table, columns}
OPA->>KC: récupération des groupes (cache sync)
OPA-->>TR: allow + row_filters + column_masks
TR->>OM: résolution tags PII (cache)
TR->>TR: réécriture de la requête (filtres + masques)
TR-->>S: lignes masquées
S-->>B: graphique / table
note over OPA,KC: OPA interroge Keycloak toutes les 60 s pour la synchro des groupes
Rôles et groupes¶
flowchart LR
subgraph KC[Realm Keycloak akko]
R1[akko-admin]
R2[akko-engineer]
R3[akko-analyst]
R4[akko-user]
R5[akko-viewer]
G1[groupe: data-team]
G2[groupe: finance]
G3[groupe: svc-accounts]
end
subgraph LLDAP[LLDAP optionnel]
L1[utilisateurs entreprise]
L2[groupes entreprise]
end
LLDAP -.fédéré.-> KC
R1 -->|mappe| OPA
R2 -->|mappe| OPA
R3 -->|mappe| OPA
R4 -->|mappe| OPA
R5 -->|mappe| OPA
G1 -->|accès projet| OPA
G2 -->|accès projet| OPA
G3 -->|jetons machine| OPA
Row-Filter + Column-Mask Trino¶
Le plugin OPA réécrit chaque requête avant exécution.
# package trino — extrait
mask_email[columns] {
columns = {"email", "phone", "ssn", "dob"}
not roles[_] in {"akko-admin", "akko-engineer", "akko-analyst"}
}
row_filter[{"filter": f}] {
input.context.identity.groups[_] == "finance"
f := "region IN ('EU', 'APAC')"
}
Exemple : un utilisateur rôle akko-user exécute :
Trino réécrit en :
SELECT '***masked***' AS email, amount
FROM iceberg.banking.transactions
WHERE region IN ('EU', 'APAC');
Synchro des tags PII — OpenMetadata -> OPA¶
flowchart LR
OM[OpenMetadata<br/>tags de colonnes: PII, GDPR.Personal] -->|ingestion nocturne| REG[cache de tags]
REG -->|/policies/pii| OPA
OPA -->|column_mask| TR[Trino]
Le sidecar opa-sync interroge OpenMetadata toutes les 5 minutes et pousse les tags de colonnes PII comme donnée OPA. Les nouvelles colonnes taguées PII sont masquées automatiquement — aucun redéploiement de politique requis.
ForwardAuth oauth2-proxy¶
Les services sans OIDC natif (MLflow, Grafana mode legacy, Harbor UI dans certains modes) sont filtrés via le middleware ForwardAuth de Traefik pointant sur oauth2-proxy.
sequenceDiagram
participant B as Navigateur
participant TR as Traefik
participant O2 as oauth2-proxy
participant MLF as MLflow
B->>TR: https://experiments.akko.local
TR->>O2: forward-auth
alt pas de cookie valide
O2-->>B: redirection Keycloak
B->>O2: code + state
O2-->>B: pose cookie
B->>TR: nouvelle tentative
end
TR->>MLF: pass-through avec header X-Auth-User
MLF-->>B: UI
Piste d'audit¶
Trois flux de logs corrélés 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 via console decision log | {user, input, result, policy} |
| Query log Trino | JSON via event-listener |
{queryId, user, sql, bytes_scanned, duration} |
| audit_log ADEN | JSON vers Loki | aden_query_received, aden_opa_denied, aden_pii_masked |
Voir Guide d'audit et l'audit API Kubernetes pour la rétention et la corrélation complètes.
NetworkPolicies¶
Tous les namespaces appliquent des NetworkPolicies :
- L'egress Internet est refusé par défaut.
- Seul
ollama-inita une allowlist vers le registre de modèles Ollama à l'installation (désactivé en mode air-gap). - Le trafic inter-services n'est autorisé qu'entre paires explicites (Trino <-> Polaris, Airflow <-> Trino, etc.).