10

Authenticate Humans and Map Identity Across Three Planes

Authenticate a person once where appropriate, but authorize and revoke that person independently in the provider, hosted-runtime, and generated-application planes.

Run it in the public monorepo

This course is built around the public Zheta Kubernetes Lab monorepo. The excerpt below is runnable source, not pseudocode.

Source: services/shared/auth.py

if claims.get("iss") != issuer or claims.get("aud") != audience or int(claims.get("exp", 0)) <= int(time.time()):
        raise PermissionError("expired or wrong-scope bearer token")
    if not claims.get("sub") or not claims.get("org"):
        raise PermissionError("bearer token lacks tenant identity")
    return Identity(str(claims["sub"]), str(claims["org"]))

Code to reality

Declared intent
Derive actor and tenant authority only from a signed, scoped, unexpired identity token.
Interpreter
The shared authentication adapter verifies cryptographic and semantic claims before MVC dispatch.
Software effect
Accepted requests carry an immutable actor and organization identity; invalid requests stop at the boundary.
Hardware effect
Signature verification consumes service CPU but denied calls allocate no downstream runtime or data resources.
Observable evidence
Positive tenant access and wrong-signature, wrong-audience, and cross-tenant denials identify the boundary.

Start with the people and the result they need

The source tables below remain the detailed contract. Begin with these customer paths:

  • D10-UC-01
    • Person: Organization administrator
    • Job: Grant a colleague provider project access and a separate generated-app role
    • Observable result: Colleague can edit an app specification and view authorized app-domain records through distinct sessions
  • D10-UC-02
    • Person: Generated-app tenant administrator
    • Job: Revoke an app user's role without removing their provider account
    • Observable result: App-domain request is denied after revoke; provider project read remains allowed

Turn each customer job into a testable story

Now turn each customer job into a story with a result that an engineer can check:

  • D10-US-01
    • Story: As an organization administrator, I want explicit plane-local grants for one enterprise subject, so that authentication convenience does not…
    • Observable acceptance: Subject maps to separate provider principal, runtime operator principal if approved, and app user; each token has a distinct audience
  • D10-US-02
    • Story: As a generated-app tenant administrator, I want app roles independently revocable, so that app data access can stop without changing provider…
    • Observable acceptance: Revoked app session fails; provider read succeeds; runtime access remains absent unless separately granted

Add real state and observable proof

Finally trace each story through the system that owns its state and the evidence that proves the outcome:

  • D10-FLOW-01
    • Trigger: Administrator invites colleague to a project and app tenant
    • Responsible systems: Enterprise IdP, Identity and Organization service, Runtime Gateway, generated-app identity adapter
    • Authoritative state: Provider membership store and generated-app user/role store
    • Owned record: ProviderMembership
    • Observable evidence: Actor, enterprise subject, mapping/grant IDs, audiences, resources, expected/observed results, environment, timestamp, traces
    • Failure signal: Unknown subject, wrong token audience, absent mapping, or role denial
  • D10-FLOW-02
    • Trigger: App admin revokes app role and colleague retries with app and provider sessions
    • Responsible systems: Generated-app identity/authorization service and Audit Evidence
    • Authoritative state: Generated-app grant/session state; provider membership remains separately authoritative
    • Owned record: GeneratedAppUserGrant
    • Observable evidence: Revocation ID, denied app trace, provider positive-control trace, runtime denial, immutable evidence ID
    • Failure signal: Session survives revoke, provider grant changes unexpectedly, or runtime permission appears

The enterprise problem and today’s slice

Enterprise problem: Reusing one role or token across platform administration, runtime operations, and generated-app data turns organization membership into unintended access to deployments and customer records.

Whole-course context: Workload and delegated connector grants are separate design records rather than implemented authorities; today establishes the provider identity baseline before collaboration and publication.

Today’s slice: Design three plane-local principal mappings and inspect the provider-plane JWT identity implemented today; hosted-runtime operator and generated-app user grants are not yet implemented.

End-of-day evidence: A five-minute provider token and tests for signature, issuer, audience, expiry, subject, and organization prove the implemented boundary; plane-local grants and independent revocation remain explicit missing evidence.

Still unsolved: Sharing invitations, publication approval, release promotion, AWS federation, and production incident roles remain later slices.

Customer use cases

Single sign-on can establish who a person is, but each plane must decide what that person may do. These use cases create explicit mappings and revoke only one plane.

Use case IDActorCustomer jobSuccess outcomeDenial or recovery evidence
D10-UC-01Organization administratorGrant a colleague provider project access and a separate generated-app roleColleague can edit an app specification and view authorized app-domain records through distinct sessionsProvider token at generated-app API is denied while correct app session succeeds
D10-UC-02Generated-app tenant administratorRevoke an app user's role without removing their provider accountApp-domain request is denied after revoke; provider project read remains allowedRevocation trace, denied app request, and unaffected provider positive control

Actor-centred user stories

An identity mapping is not permission inheritance. These stories require independent grant IDs, audiences, policy owners, and revocation results.

Story IDUse case IDsUser storyObservable acceptance conditions
D10-US-01D10-UC-01As an organization administrator, I want explicit plane-local grants for one enterprise subject, so that authentication convenience does not collapse authorization boundariesSubject maps to separate provider principal, runtime operator principal if approved, and app user; each token has a distinct audience
D10-US-02D10-UC-02As a generated-app tenant administrator, I want app roles independently revocable, so that app data access can stop without changing provider employment or project membershipRevoked app session fails; provider read succeeds; runtime access remains absent unless separately granted

End-to-end product flows

The colleague signs in through an enterprise identity provider, then each product surface exchanges that identity for a plane-specific session. No surface accepts another plane's token audience.

Flow IDUse case IDsPathTriggerNumbered stepsTerminal evidence
D10-FLOW-01D10-UC-01, D10-UC-02HappyAdministrator invites colleague to a project and app tenant1. Identity provider authenticates subject.; 2. Organization service creates provider grant.; 3. App admin creates app-user mapping and role.; 4. Each issuer creates scoped session.; 5. Colleague performs one action in each allowed plane.Actor, enterprise subject, mapping/grant IDs, audiences, resources, expected/observed results, environment, timestamp, traces
D10-FLOW-02D10-UC-01, D10-UC-02DeniedApp admin revokes app role and colleague retries with app and provider sessions1. App grant becomes revoked.; 2. App session is invalidated.; 3. App request is denied.; 4. Provider project read succeeds.; 5. Runtime operation remains denied.Revocation ID, denied app trace, provider positive-control trace, runtime denial, immutable evidence ID

The administrator begins a provider-plane relationship. That invitation alone cannot create a generated-app user or hosted-runtime operator.

System design derived from the flows

One identity provider may authenticate the person, but separate policy decision points authorize each audience. Explicit mapping records connect opaque subject IDs without merging stores.

Use case IDEntry pointResponsible servicesAuthoritative storeFailure evidence
D10-UC-01Forge Studio invite and generated-app admin actionEnterprise IdP, Identity and Organization service, Runtime Gateway, generated-app identity adapterProvider membership store and generated-app user/role storeUnknown subject, wrong token audience, absent mapping, or role denial
D10-UC-02Generated-app role revokeGenerated-app identity/authorization service and Audit EvidenceGenerated-app grant/session state; provider membership remains separately authoritativeSession survives revoke, provider grant changes unexpectedly, or runtime permission appears

The enterprise subject can map to three principals, but each mapping is optional and each plane issues or accepts only its own audience and grants.

Data model and ownership

A shared users table would let provider administrators rewrite generated-app roles. Each plane stores its own principal and grant, joined only by opaque subject references.

Generated-application database: Not created in this runnable slice — the generated-application user, role, session, and predicate records below are the target ownership contract, while current code persists provider project collaborators only.

Record or entityStore and ownerPrimary keyForeign key or opaque referenceTenant keyMaterial constraintLifecycle and deletionUse case IDs
ProviderMembershipControl-plane PostgreSQL, owned by Identity and Organization servicemembership_idOpaque enterprise subject and project IDsorganization_idRole scoped to provider resources; token audience cannot access runtime/app APIsInvited, active, suspended/revoked; retained for provider audit then deletedD10-UC-01, D10-UC-02
GeneratedAppUserGrantGenerated-app PostgreSQL, owned by generated-app identity serviceapp_user_grant_idOpaque enterprise subject reference; local user and role FKsapp_tenant_idApp role and session independently revocable; every data predicate uses app tenant/userInvited, active, revoked; sessions invalidated; exported/deleted under app policyD10-UC-01, D10-UC-02

The two durable grants can refer to the same enterprise subject while retaining different owners, tenants, audiences, lifecycles, and revocation evidence.

Prove independent revocation

Inspecting token claims cannot prove every API rejects the wrong audience. The current implementation has one provider audience, forge-control-plane, and derives its value when minting a short-lived local token; it cannot prove independent runtime or generated-app revocation. Read the exact development-token tool in scripts/mint-local-token.py.

claims = encode({"sub": os.getenv("ACTOR", "owner@acme.test"), "org": os.getenv("ORGANIZATION_ID", "acme"), "iss": "zheta-forge", "aud": "forge-control-plane", "exp": int(time.time()) + 300})
signed = f"{header}.{claims}"
signature = base64.urlsafe_b64encode(hmac.new(secret.encode(), signed.encode(), hashlib.sha256).digest()).decode().rstrip("=")
print(f"{signed}.{signature}")
Declared intentInterpreterSoftware effectHardware effectEvidence
Mint one five-minute development token for the provider control planePython serializes claims and signs them with the configured HMAC secret; verify_bearer validates themProduces a bearer token carrying one actor, organization, issuer, audience, and expiry; it creates no membership, runtime operator, or app-user recordLocal CPU performs serialization and HMAC; no durable state or AWS resources changeAuthenticationTest proves signature and provider-scope checks; independent three-plane mappings and revocations remain required implementation evidence

Decision rules

Share authentication only where it reduces login friction; never share authorization implicitly. Every cross-plane mapping is explicit, least-privilege, audited, and independently revocable, and every API validates issuer, audience, tenant, resource, and current grant state.