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:
- The platform — the AKKO software AKKO ships and supports.
- 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)¶
- Standalone chart
helm/akko-demo-ad/: - own Chart.yaml (apiVersion v2)
- 9 templates (Deployment, Service, ServiceAccount, PVC, Secret, ServiceMonitor, NetworkPolicy ×2, Ingress, ConfigMap, Job, NOTES.txt)
- cross-namespace NetworkPolicy that allows ingress from
global.akkoNamespace(the AKKO platform) only -
perimeter label
akko.io/perimeter: customer-simulated-adon every workload, used by cockpit Governance to render a "federated" badge (Sprint 61.1.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.
-
No hardcoded credentials (ADR-039) :
adminPassword: REQUIRED — Helm renders an explicit error message when not setbootstrap.defaultUserPassword: REQUIRED for bootstrap users-
Both passwords are stored in a single Kubernetes Secret created by the chart and consumed by the bootstrap Job
-
Connection contract : the chart exposes its in-cluster URL via the
akko-demo-ad.ldapUrltemplate helper :
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.
- Baseline gates in
tests/integration/test_security_baseline.py: test_demo_ad_standalone_chart_existstest_demo_ad_bootstrap_populates_four_oustest_demo_ad_renders_networkpolicy_and_bootstrap_nptest_demo_ad_labels_expose_customer_simulated_perimetertest_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 …thenhelm 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 installcommands instead of one for the demo cluster. Documented indocs/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 templaterenders 11 resources with no errors whenglobal.domain+adminPassword+bootstrap.defaultUserPasswordare 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