Aller au contenu

ADR-045 — AKKO demo cluster splits into 3 perimeters; identity provider lives in akko-demo-ad

  • Status : Accepted
  • Date : 2026-04-30
  • Sprint : 61.1
  • Drivers : founder vision 2026-04-29 ("le déploiement Netcup est démo + dev — chez un vrai client AKKO ne contrôlera ni l'AD ni les sources"), prospect credibility ("comment vous gérez NOTRE AD ?")
  • Related : ADR-036 (functional FQDN), ADR-039 (zero hardcoding), ADR-040 (cockpit-backend service account), ADR-044 (JWT issuer/JWKS split)

Context

Until Sprint 60, the akko-lldap directory service was a sub-chart of the umbrella akko chart, deployed in the same namespace as every other AKKO platform service. This collapses two things into one:

  1. The platform — the AKKO software AKKO ships and supports.
  2. The customer's identity provider — what the customer already runs (Active Directory, Okta, Azure AD, an internal LLDAP, etc.).

At a real customer this distinction is non-negotiable: the customer's IdP is theirs, AKKO never owns it, never has admin credentials on it, and only reads it through Keycloak User Federation. Every prospect demo that hides this distinction creates a credibility gap ("how do you handle MY AD?") and a temptation to hardcode shortcuts that real customers won't accept.

Founder directive (verbatim, 2026-04-29):

Le déploiement AKKO sur Netcup est un déploiement de démonstration et de dev. Chez un vrai client il aura son propre Active Directory (dont on ne sait pas sur quoi il est basé), ses propres sources de données (Cloudera Hadoop, SQL Server, Oracle, Postgres). Sur Netcup il faut simuler un vrai environnement client (un AD séparé peuplé comme une vraie entreprise, un cluster Cloudera kerberisé, des Postgres clients fédérés) et le tester avec AKKO comme un vrai client le ferait. Le jour où je vais voir un client je dois avoir un vrai déploiement AKKO et être capable sur Netcup de simuler un vrai AD et un vrai cluster Hadoop.

Decision

The Netcup demo cluster is split into three perimeters, each in its own namespace, deployed by its own Helm release :

# Perimeter Namespace Sprint Helm release
1 AKKO core — the platform akko preexisting akko (umbrella chart helm/akko/)
2 Customer-simulated IdP — LLDAP populated like a real org akko-demo-ad 61.1 akko-demo-ad (this chart, helm/akko-demo-ad/)
3 Customer-simulated data sources — Cloudera Hadoop, Postgres tenants, Oracle XE, MS SQL akko-demo-cloudera, akko-demo-sources 61.2 + 61.3 separate releases

The umbrella akko-lldap sub-chart is kept for k3d / dev clusters (developer wants the whole stack in one helm install). Sprint 61.1 introduces a standalone chart helm/akko-demo-ad/ that should be used for any production-style or prospect-facing demo.

Sprint 61.1 deliverables (this ADR)

  1. Standalone chart helm/akko-demo-ad/ :
  2. own Chart.yaml (apiVersion v2)
  3. 9 templates (Deployment, Service, ServiceAccount, PVC, Secret, ServiceMonitor, NetworkPolicy ×2, Ingress, ConfigMap, Job, NOTES.txt)
  4. cross-namespace NetworkPolicy that allows ingress from global.akkoNamespace (the AKKO platform) only
  5. perimeter label akko.io/perimeter: customer-simulated-ad on every workload, used by cockpit Governance to render a "federated" badge (Sprint 61.1.6)

  6. Bootstrap data : 50 users distributed across 4 OUs (Engineering ×20, Finance ×12, Compliance ×10, Sales ×8), plus the 5 AKKO-platform-role groups (akko-admins, akko-engineers, akko-analysts, akko-stewards, akko-viewers). Each user is mapped to 1 OU + 1 platform-role group.

  7. No hardcoded credentials (ADR-039) :

  8. adminPassword : REQUIRED — Helm renders an explicit error message when not set
  9. bootstrap.defaultUserPassword : REQUIRED for bootstrap users
  10. Both passwords are stored in a single Kubernetes Secret created by the chart and consumed by the bootstrap Job

  11. Connection contract : the chart exposes its in-cluster URL via the akko-demo-ad.ldapUrl template helper :

ldap://<release>-akko-demo-ad.<namespace>.svc.cluster.local:3890

AKKO core consumes this URL via Keycloak User Federation, configured on the akko (umbrella) release through values (NOT through admin API hot-patches). The federation password is shared from the akko-demo-ad chart's secret, copied or referenced into the akko namespace by the operator.

  1. Baseline gates in tests/integration/test_security_baseline.py :
  2. test_demo_ad_standalone_chart_exists
  3. test_demo_ad_bootstrap_populates_four_ous
  4. test_demo_ad_renders_networkpolicy_and_bootstrap_np
  5. test_demo_ad_labels_expose_customer_simulated_perimeter
  6. test_demo_ad_admin_password_required

Customer install pattern (BYO-IdP)

For a real customer who already has an Active Directory, periphery 2 is not deployed. Instead, the operator points the AKKO Keycloak User Federation directly at the customer's AD:

# values-<customer>.yaml
akko-keycloak:
  userFederation:
    enabled: true
    provider: ldap
    url: "ldaps://ad.bigcorp.local:636"
    bindDn: "CN=akko-svc,OU=Service Accounts,DC=bigcorp,DC=local"
    baseDn: "OU=People,DC=bigcorp,DC=local"
    bindCredentialSecret:
      name: akko-byo-ad-binding
      key:  password

The customer creates the bind account, hands AKKO the credentials, and the operator stores them in akko-byo-ad-binding (out-of-band, not in git). At runtime the cockpit Governance page badges every user as "federated, read-only".

The standalone akko-demo-ad chart is the mock of this pattern — identical from AKKO's point of view, just running on the same cluster in a separate namespace.

Consequences

Positive

  • Demo credibility : the prospect can see for themselves that AKKO reads, never modifies, the directory. Open the LLDAP web UI in akko-demo-ad, show 50 users in 4 OUs, then show those same users logging into AKKO cockpit with their roles derived from the OU membership.
  • Zero hardcoding enforced : separating into a standalone chart forces the operator to configure passwords, URLs, and bind DN — none of these can be inherited from the umbrella defaults.
  • Production parity : the install path for the demo cluster (helm install akko-demo-ad … then helm install akko … with federation values) IS the install path at a customer (just skip step 1 if the customer has their own AD). No fork between demo and prod.

Negative

  • Two helm install commands instead of one for the demo cluster. Documented in docs/admin/akko-3-perimeters.md + helm/scripts/.
  • Operator must rotate two passwords instead of one (admin + default user). Acceptable — they were always two distinct secrets conceptually, just hidden.
  • Sprint 61.1.4 (Keycloak federation post-upgrade hook valuification) is a follow-up. The current chart exposes the LDAP URL via NOTES.txt and a helper template, but the actual federation wiring on the AKKO side is still configured by hand. Tracked as task #337 sub-item.

Validation

  • 5/5 baseline tests pass (pytest -k demo_ad).
  • helm lint helm/akko-demo-ad/ clean.
  • helm template renders 11 resources with no errors when global.domain + adminPassword + bootstrap.defaultUserPassword are provided.
  • Live deploy on Netcup deferred to next session — requires kubectl create ns akko-demo-ad + secrets injection from out-of-band store.

References

  • ADR-036 — functional FQDN (consumer-side hostname strategy)
  • ADR-039 — zero hardcoding policy
  • ADR-040 — cockpit-backend service account pattern (BYO-IdP friendly)
  • ADR-044 — JWT issuer/JWKS split (BYO-IdP friendly)
  • Sprint 61 master plan — akko-technical-map/sprints/sprint-61-3-perimeters-vision.md
  • Project memory — project_akko_3_perimeters_vision.md