Learn: Identity & Access — reference
A reference for the identity and access model, in brief. For the full walkthrough, see the orientation. Each piece here may earn its own module later.
The shape
Section titled “The shape”Decide once in git, derive (who) × (what), then project it into each system’s native config. Three planes,
sharing machinery, zero trust between them:
| Plane | Who | Identity of record |
|---|---|---|
| Workforce (built) | platform engineers, developers, viewers, auditors | Keycloak (IdP of record) |
| Machine (built) | workloads needing AWS (agents are a richer case — below) | EKS Pod Identity (+ delegation for agents) |
| Consumer / CIAM (deferred) | end-users of hosted products | one isolated Keycloak realm per Product |
The git source of truth
Section titled “The git source of truth”Person(gitops/people/) — the roster:spec.person(Keycloak anchor) +spec.grants: [{role, team}].WorkforceRole(gitops/roles/) — the catalog: each role declares its shape (reach,power,mode,riskTier) and how it projects (identityCenter,keycloak, …).grants— a grant isrole × scope; standing grants are projected (active), on-demand grants are eligible-but-inert (see Temporary power).
The role axes
Section titled “The role axes”- reach —
team(own team) →platform(org-wide) →any(broadest). - power —
look(read) →operate→change(deploy) →manage-access. - mode —
standing(everyday, always active) vson-demand(borrowed, expires). - riskTier —
standard…apex(break-glass).
Catalog today: developer, team-admin, platform-operator, access-admin, auditor, viewer,
release-approver, break-glass.
Projection — where access lands
Section titled “Projection — where access lands”Each tool decides access internally, so the platform derives its native config from (Person × Role):
- AWS — Identity Center permission sets (console/CLI), per team.
- Apps (ArgoCD, Backstage, Grafana) — Keycloak realm roles / per-team groups, brokered via OIDC.
- Cluster — per-team RBAC.
- Coming — GitHub teams, PagerDuty on-call, Slack.
Temporary power
Section titled “Temporary power”- An
on-demandgrant declares eligibility (who may borrow what) — but the projection generators deliberately exclude on-demand grants from the standing config, so the access doesn’t exist in any system until activated. - Activate = a step-up (re-prompt a passkey, the
acr.loa.mapseam) + a TTL; extend in windows, then re-borrow. Auto-revoked on expiry, loudly audited. - Built + live: the eligibility model, the passkey step-up seam, and the activation operator (a Kubebuilder controller that mints the live grant and expires it on TTL), with a Backstage front door.
Workload identity
Section titled “Workload identity”- EKS Pod Identity: a pod assumes a scoped IAM role via its ServiceAccount — short-lived,
no static keys. Provisioned per-Service by the Environment Composition
(e.g.
Pod-<team>-<product>-<stage>-<svc>). The platform’s own add-ons use Pod Identity too. - Agents — a richer machine subject: an agent gets its own Pod Identity plus a three-identity authority model — its own identity, its tool/model grant, and on-behalf-of-user delegation — where effective authority is the intersection of the agent grant and the human’s scope, enforced by trusted boundary code (never the agent) and attenuating across chains. It’s the same access model, with agents as grant subjects, bounded by graduated autonomy. Largely designed today; the full treatment is the coming Agentic platform module.
Keycloak — the pluggable seam
Section titled “Keycloak — the pluggable seam”- Keycloak is the IdP of record for the workforce; it brokers a corporate IdP if one exists, so the platform never becomes the identity monopoly. Apps get direct OIDC to Keycloak. Admin plane hardened (passkey + sealed break-glass).
Gotchas
Section titled “Gotchas”- Declared ≠ effected. A grant in git is intent; the projected native config is the effect. The honest model verifies intent-vs-effected + drift, because a system could be changed out-of-band. Don’t assume the console matches git without checking.
- Per-team cluster (kubectl) access isn’t fully provisioned. The v3 Composition emits only the
in-cluster
developersRoleBinding, not theDeveloperAccess-<team>IAM role + EKS access entry — OIDC-native cluster auth is designed, not yet built — useplatctl kubeconfig/ PlatformAdmin until built. (This is why this shell reads with PlatformAdmin but can’t write to tenant namespaces.) - On-demand grants are invisible in every console until activated — that’s the point, not a bug.
Glossary
Section titled “Glossary”Person/WorkforceRole/ grant — the git-native roster, role catalog, and role×scope assignment.- derive / project — compute
(who) × (what), then render it into each target system’s native config. - standing vs on-demand — always-active access vs borrowed-and-expiring.
- Pod Identity — a pod’s scoped, keyless AWS identity via its ServiceAccount.
- IdP of record — Keycloak; the authoritative identity source the platform projects from.
- step-up — re-authenticating (passkey) to activate higher power.
Go deeper
Section titled “Go deeper”- Identity & Access Strategy (north star).
- Substrate: NIST Zero Trust · EKS Pod Identity · Keycloak.