Skip to content

ADR-039 — No hardcoded identities (users / roles / permissions)

Status: PROPOSED — implementation Sprint 56 Date: 2026-04-27 Sprint: 56 (planned) Supersedes: relaxes the "demo personas OK in chart" implicit pattern

Context

AKKO is a platform delivered to clients. Each client has : - Their own Active Directory / LDAP / IdP (Azure AD, Okta, Auth0, Keycloak self-hosted, OpenLDAP, 389-DS, ...) - Their own users identified by matricules / employee IDs / corporate emails (e.g. M123456, john.doe@acme.com, jdupont) - Their own roles / groups (e.g. AD-DataPlatform-Admins, service-marketing, dir-finance) - Their own permission policies (per regulatory framework, per business unit, per data sensitivity)

The current Helm chart contains hardcoded references to demo personas (alice, bob, carol, dave, eve) and to a fixed role taxonomy (akko-admin, akko-engineer, akko-analyst, akko-steward, akko-viewer). These hardcoded values appear in 12 files for personas (37 hits) and 10 files for roles (39 hits) — see audit table below.

Founder feedback 2026-04-27 (3 successive messages of the same day) :

  1. "Dans la vraie vie, le client va avoir son LDAP... il faut rien hardcoder, ni les users, ni les rôles, ni les droits, ni les autorisations."

  2. "Je ne veux pas cette règle spéciale [demo hardcoding OK]. Je veux que le point de vérité soit l'active directory du client, ici notre exemple c'est lldap."

The "demo OK to hardcode" escape hatch is rejected. Even on demo.akko-ai.com the source of truth must be LLDAP (which substitutes for the client's AD in the showcase context).

Decision

No hardcoded identities anywhere in the chart-by-default surface. The single source of truth for identities is the customer's AD (or LLDAP on demo). All apps consume identities via Keycloak User Federation → JWT claims, never via init seed scripts that write into their internal DBs.

What "identity" means here

  • User names (matricules) : alice, M123456, john.doe@acme.com
  • Roles / groups : akko-admin, service-marketing, AD-DataPlatform-Admins
  • Permissions : column mask, row filter, table grant, dataset access
  • Email domain : never used as a primary key, only metadata

Scope of this ADR

In scope (must be Helm-templated, default empty/disabled) : - Init scripts that seed humain users in apps DB (OM, Superset, Airflow, OPA) - initialAdmins lists in app configs - groupRoleMapping for OPA / cockpit / catalog manager - principalDomain filters - Hardcoded usernames in OPA Rego policies - Default secrets / passwords for demo personas

Out of scope (system accounts may stay hardcoded) : - Service accounts with prefix svc- or suffix -bot (e.g. svc-aden, ingestion-bot, service-account-akko-aden-bot) - These are AKKO-internal and don't represent client humans - Documented as system-only

Chart-default behaviour after this ADR

# helm/akko/values.yaml (default)
global:
  initialAdmins: []          # empty by default
  groupRoleMapping: {}       # empty by default

demo:
  enabled: false             # the akko-demo sub-chart that seeds
                             # alice/bob/... in LLDAP only

akko-lldap:
  enabled: false             # the client has their own AD
# helm/examples/values-dev.yaml (demo configuration)
demo:
  enabled: true              # personas seed only into LLDAP

akko-lldap:
  enabled: true              # LLDAP acts as AD-substitute on demo

global:
  initialAdmins: [admin, alice]   # demo admins, observable via JWT
  groupRoleMapping:
    "akko-admin":    "akko-admin"
    # ...
# helm/examples/values-customer-template.yaml (Sprint 56 deliverable)
global:
  initialAdmins: []          # the client fills in their matricules
  groupRoleMapping:
    "<THEIR_AD_GROUP_ADMINS>":    "akko-admin"
    # ...

demo:
  enabled: false

akko-lldap:
  enabled: false

Consequences

Migration cost

Audited surface (Sprint 54 close-out 2026-04-27) : - 12 files contain persona names in chart-by-default (37 hits) - 10 files contain hardcoded role names (39 hits)

See Sprint 56 plan for day-by-day breakdown (8 days).

CI enforcement

Three new baseline assertions added in Sprint 56 : 1. test_no_hardcoded_personas_in_chart_default — grep chart-default for alice/bob/carol/dave/eve → must return 0 hits outside demo.* sub-chart 2. test_chart_default_has_zero_seed_users_in_appshelm template default values must produce 0 Job that creates seed users in OM / Superset / Airflow / OPA 3. test_groupRoleMapping_is_value_driven — chart accepts arbitrary strings as group names and role names (no string equality with hardcoded constants)

Customer onboarding

A customer onboarding playbook (docs/admin/customer-onboarding.md) is delivered Sprint 56. New clients can deploy AKKO without any seed data leak from our demo cluster. Their first login = their AD identity, no user seeded in our chart.

Demo continuity

The akko-demo sub-chart (Sprint 56 deliverable) keeps the showcase working : alice/bob/carol/dave/eve are seeded in LLDAP, then propagated to all apps via Keycloak User Federation + JWT. From the apps' point of view, they're indistinguishable from real client users — exactly what we want for showcasing.

Rollback

If Sprint 56 hits an unmovable blocker (e.g. OpenMetadata 1.12 refuses empty initialAdmins) : 1. Document the blocker in ADR-040 2. Adopt a less-strict pattern (e.g. always seed an akko-system-admin bot user that's not a human) 3. Plan SCIM 2.0 implementation immediately (Sprint 57+)

Comparison with industry

Vendor Identity source Hardcoded users in chart?
Dremio Cloud SCIM 2.0 from any IdP None
DataHub OIDC sub primary, JIT-create None
Snowflake SCIM connector None
Trino official Helm empty defaults, customer-driven None
AKKO today (pre-ADR-039) LLDAP seed + hardcoded refs 12 files / 76 hits
AKKO post-ADR-039 LLDAP/AD via JWT, JIT-create 0 (only system bots)

Implementation

See akko-technical-map/sprints/detailed/sprint-56-customer-onboarding-no-hardcoding.md.

  • ADR-038 : OIDC sub-based user matching (Sprint 55) — sister ADR
  • feedback_no_hardcoded_users_roles_permissions.md (memory rule)
  • feedback_oidc_sub_is_stable_id.md (memory rule)
  • project_akko_4_architectures_workflows.md (operational cadre)