05

Enterprise Login, Teams, OAuth, and OIDC

Turn an enterprise sign-in into a current organization-and-team context, then distinguish platform login from machine and human connector delegation.

The enterprise problem and today’s slice

Enterprise problem: A valid enterprise login can carry stale memberships or be confused with permission to use an external connector, causing a transferred or deprovisioned employee to retain team or downstream access.

Whole-course context: Day 04 produced a typed identity context and intersection rule; today supplies the authenticated human, current active-team membership, and separately governed OAuth (the standard delegated-authorization protocol) grants that later runs will consume.

Today’s slice: We design OpenID Connect (OIDC) or Security Assertion Markup Language (SAML) login, just-in-time (JIT) or System for Cross-domain Identity Management (SCIM) lifecycle input, organization and active-team resolution, explicit generated-app tenant and role mapping, admin-provisioned machine access, and optional user-delegated OAuth across all authorization boundaries.

End-of-day evidence: A reviewer receives positive and negative login traces, a team-switch and cross-tenant proof, and separate machine-grant and user-consent records with issuer, audience, scope, revision, environment, timestamp, and immutable trace IDs.

Still unsolved: Run authorization, per-tool argument policy, high-risk approval, production connector execution, and continuous revocation are deliberately deferred.

Customer use cases

Treating a signed token as the complete authorization state lets stale or wrongly addressed claims cross customer boundaries, so the platform must authenticate the subject and then resolve current authority independently.

OpenID Connect (OIDC) adds authentication to OAuth 2.0 and gives the client an ID token describing who signed in. OAuth 2.0 delegates limited access to a resource server; its access token describes what a client may do, not a reusable proof of platform identity.

Use case IDActorCustomer jobSuccess outcomeDenial or recovery evidence
D05-UC-01Enterprise identity administrator and employeeConfigure OIDC or SAML, provision a person through JIT or SCIM, and sign inExact provider metadata and callbacks validate, one protocol subject resolves to one enterprise principal, and authentication and provisioning remain separately auditableBad issuer, audience, signature, nonce, state, replay, disabled SCIM record, or duplicate protocol subject produces a specific denial trace and no session
D05-UC-02Multi-team generated-app employeeSelect one provider team and receive the intended application tenant and roleCurrent provider membership resolves through an explicit subject binding to one app-owned subject, tenant, membership, and roleCross-organization team selection, unbound principal, synthetic preview fixture, or same-local-ID cross-tenant request is denied while the employee's valid tenant remains allowed
D05-UC-03Integration administrator and hosted runtimeProvision and use stable non-human connector authorityA workload grant pins workload, application, environment, connector version, operations, audience, and tenant without acquiring any human sessionSubstituting a project role, app session, or human token for workload identity is denied and the valid workload path remains allowed
D05-UC-04Data-authorized employeeOptionally link the employee's external account for one on-behalf-of operationA distinct delegated grant binds user, app tenant, connector, source account, operation, audience, consent version, and bounded lifetimeWrong user, tenant, source, audience, scope, expired consent, or revocation denies delegation without disabling SSO, app membership, or workload access

Organization roles and team roles answer different questions:

ScopeExample rolesAppropriate decisions
Organizationorg_admin, it_admin, security_admin, ai_studio_admin, billing_admin, memberConfigure enterprise identity, manage organization policy, provision teams, inspect organization audit
Teamteam_admin, agent_builder, agent_operator, member, viewerBuild, run, review, or administer resources inside one team

The platform selects one primary team per operation. It must not create an accidental permission union such as Marketing plus Finance plus Legal merely because one employee belongs to all three.

Actor-centred user stories

When identity, team choice, and connector consent are expressed as one vague “logged in” state, customers cannot revoke the correct authority without disrupting unrelated work.

Story IDUse case IDsUser storyObservable acceptance conditions
D05-US-01D05-UC-01As a customer identity administrator, I want OIDC or SAML sign-in and JIT or SCIM lifecycle control configured independently, so that login and provisioning failures can be diagnosed and revoked separatelyConsole shows verified issuer or entity ID, exact redirect or assertion-consumer-service endpoint, signing metadata, stable subject mapping, provisioning status, and distinct authentication and lifecycle traces
D05-US-02D05-UC-02As a multi-team generated-app employee, I want my verified principal mapped to the intended provider team and app-owned tenant role, so that signing in never grants another tenant's dataAlpha membership allows only Alpha resources; a Beta resource with the same local ID fails; evidence links principal, active team, subject binding, app subject, tenant, membership, role, and policy version
D05-US-03D05-UC-03As a connector administrator, I want a team workload grant separated from every human identity, so that scheduled automation remains durable without inheriting a builder or employee sessionWorkload grant is provisioned and tested first; connector call succeeds only for its pinned identity, version, operation, audience, and tenant; human-token substitution is denied
D05-US-04D05-UC-04As a data-authorized employee, I want optional on-behalf-of connector access scoped to my consent, so that revoking delegation stops source use without disabling my application accountValid exchange returns a short-lived audience-restricted credential; consent revocation or tenant mismatch denies the next exchange while sign-in, app membership, provisioning, and workload probes stay healthy

The modern interactive login flow is Authorization Code with PKCE. PKCE means Proof Key for Code Exchange: the client generates a secret verifier, sends only its derived challenge before login, and must present the verifier when exchanging the one-time code. An intercepted code is therefore not enough to obtain tokens.

OIDC ID token     -> client learns authenticated user identity
OAuth access token -> resource server evaluates delegated API access
OAuth refresh token -> client obtains new access tokens; highly sensitive

Tokens are encoded claims, not automatic truth. If a token is a JSON Web Token (JWT), the receiver validates signature, allowed algorithm, issuer, audience, expiry, not-before time, and authorized client before using its claims. Its readable payload is signed, not encrypted; secrets must never be placed in it.

For enterprise connectors, provision machine authority first:

  1. An administrator creates a team-owned workload or service-account grant.
  2. The downstream administrator limits its scopes and resource access-control lists.
  3. The platform limits which team, connector, and operations may select it.
  4. A positive and negative probe records observed behavior.
  5. Only then may an employee add optional on-behalf-of access to their personal account through a separate consent flow.

Neither grant inherits the other. Client Credentials is suitable for a confidential backend acting as itself; Authorization Code with PKCE is suitable when a human delegates access. A public browser client cannot safely hold a client secret.

SAML, or Security Assertion Markup Language, is a common enterprise authentication alternative to OIDC. The relying party validates the assertion signature, exact issuer, audience restriction, recipient, time conditions, request correlation, and replay state. Both protocols normalize to a stable key such as (identity_provider_id, protocol_subject); an email address is mutable profile data, never an identity join.

SCIM, the System for Cross-domain Identity Management, provisions and deactivates users and groups. Just-in-time (JIT) provisioning creates or updates a principal during a successful login. Neither mechanism creates a login session, active provider team, app tenant membership, app role, workload grant, or connector delegation by itself.

End-to-end product flows

Login and delegation failures are dangerous when redirects obscure the terminal result, so each path must end in a visible session, denial, revocation, or independently verified downstream probe.

Flow IDUse case IDsPathTriggerNumbered stepsTerminal evidence
D05-FLOW-01D05-UC-01HappyAdministrator saves an OIDC or SAML configuration, provisions Alice, and Alice signs in1. Validate issuer or entity ID, signing keys, exact callback or assertion-consumer-service endpoint, audience, and subject claim.<br>2. Apply the JIT or idempotent SCIM event to one Principal.<br>3. For OIDC, complete code plus PKCE and validate state, nonce, signature, issuer, audience, expiry, and authorized client; for SAML, validate conditions, correlation, and replay state.<br>4. Create a short platform session.Evidence records Alice, provider configuration resource, authentication scope, precondition active provisioned principal, expected one admitted principal, observed session, environment, timestamp, configuration revision, provisioning event, trace, and immutable authentication-event ID
D05-FLOW-02D05-UC-02DeniedAlice selects Alpha and requests Beta board:42, which shares Alpha's local identifier1. Resolve current provider team membership rather than token groups.<br>2. Follow explicit Principal-to-AppSubject binding.<br>3. Derive app tenant and active membership server-side.<br>4. Apply tenant predicate at API and data layers.<br>5. Deny Beta and repeat Alpha as a positive control.Evidence records Alice, requested board resource, Beta tenant scope, Alpha membership precondition, expected Beta deny and Alpha allow, observed results, environment, timestamp, subject-binding and membership IDs, policy version, and decision ID
D05-FLOW-03D05-UC-03HappyIntegration administrator provisions Marketing automation and the hosted runtime reads an approved source1. Register confidential workload and pin generated app, environment, and deployment.<br>2. Downstream authorization server issues minimal service grant.<br>3. Vault stores credential behind an opaque reference.<br>4. Bind connector version, operations, audience, and tenant to workload grant.<br>5. Run approved read, forbidden-resource probe, and human-token substitution probe.Evidence records workload actor, connector and downstream resource, machine scopes, approved-grant precondition, expected read allow and two denies, observed results, environment, timestamp, workload-grant ID, and immutable probe-run ID
D05-FLOW-04D05-UC-04RecoveryEmployee revokes an optional personal OAuth connection1. App reauthorizes current tenant, role, resource, and action.<br>2. Broker revokes provider consent and platform delegated grant.<br>3. Invalidate refresh-token family.<br>4. Attempt next user exchange and observe reauthorization required.<br>5. Probe app sign-in, app membership, SCIM state, and separate workload grant unchanged.Evidence records employee, source resource, app-tenant and delegated scopes, precondition delegated grant active, expected delegation deny plus four unaffected controls, observed results, environment, timestamp, revocation version, and immutable trace ID

The edge gateway should terminate Transport Layer Security (TLS), reject caller-supplied identity headers, validate stable token properties, rate-limit abuse, and call external authorization for business decisions. It should not decide access to a particular team or agent from a broad JWT role.

An illustrative normalized session token is short-lived and audience-bound:

{
  "iss": "https://identity.platform.example",
  "aud": "agent-control-plane",
  "sub": "user_8472",
  "org": "org_acme",
  "membership_version": 39182,
  "session_id": "session_3a40",
  "auth_time": 1785527200,
  "amr": ["pwd", "mfa"],
  "exp": 1785527500
}

amr lists authentication methods, such as password and multi-factor authentication. The membership version is a staleness signal, not a membership grant; sensitive requests still resolve current state.

System design derived from the flows

If the gateway, membership service, and credential broker share one undifferentiated trust domain, a login token compromise can become an external-system compromise with no separately revocable boundary.

Use case IDEntry pointResponsible servicesAuthoritative storeFailure evidence
D05-UC-01Identity-provider configuration console, OIDC callback or SAML assertion-consumer endpoint, and SCIM endpointIdP Configuration Service validates metadata; Auth Broker verifies OIDC or SAML; JIT/SCIM Provisioner updates Principal; Session Service issues bounded platform sessionCustomer identity provider owns authentication; Identity Configuration and Principal stores owned by Enterprise Identity Service; platform Session Store owned by Session Serviceoidc_state_mismatch, pkce_failed, saml_replay, invalid_issuer, duplicate_protocol_subject, provisioning_disabled, or account_inactive, with configuration, provisioning, and auth-event IDs
D05-UC-02Active-team selector and generated-app protected routeMembership Service resolves current org/team roles; Subject Binding Service maps Principal to app subject; generated-app Policy Enforcement Point and Policy Decision Point enforce tenant, role, resource, and actionProvider Membership Store owned by Membership Service; generated-app subject, tenant, membership, role, session, and domain stores owned by that generated applicationteam_not_in_organization, unbound_principal, synthetic_fixture_rejected, inactive_app_membership, or tenant_mismatch, with stable IDs and positive-control result
D05-UC-03Integration administration and connector broker workload endpointConnector Control Plane registers grant; Workload Verifier attests runtime; OAuth Broker obtains machine token; Vault stores secrets; Probe Runner tests downstream behaviorConnector Catalog and Workload Grant Store owned by Integration Control Plane; secret material owned by Vault; service grant and resource ACLs owned by downstream providerinvalid_workload_audience, missing_workload_grant, connector_version_mismatch, human_token_substitution, or failed negative probe, with grant and trace IDs
D05-UC-04Generated-app “Connect my account” and delegated token-exchange endpointsApp Session Verifier checks current app authority; Delegation Broker binds state and PKCE; OAuth Broker narrows user grant; Credential Proxy calls source without returning secretDelegated Grant and Revocation stores owned by Integration Control Plane; consent, external subject, and resource ACLs owned by downstream provideruser_consent_missing, wrong_tenant, wrong_audience, wrong_source, refresh_reuse_detected, or credential_revoked, with delegated-grant and trace IDs

Machine and human authority remain separate all the way down:

PropertyTeam workload grantUser-delegated grant
PrincipalService account or confidential workloadHuman external account plus current app subject
Typical flowClient Credentials or administrative provider grantAuthorization Code with PKCE
Consent ownerEnterprise administrator and downstream administratorIndividual user plus enterprise policy
SchedulingDurable when policy permitsUnsafe by default if tied to a departing user
Downstream auditService-account identity; platform must preserve initiating actorHuman external identity
RevocationTeam or organization administratorUser, provider, or organization administrator

Generated applications own their authorization vocabulary. A Workboard may use Viewer, Editor, and Owner; a revenue dashboard may use RevenueReader and ForecastApprover; a public intake app may allow anonymous submission creation while denying anonymous read and mutation. Shared platform invariants are explicit tenant derivation, server-side policy, and negative tests—not one universal role catalogue.

Every generated-app query and mutation includes the server-derived tenant. A second data-layer predicate, such as row-level security or a constrained tenant-aware repository, independently limits rows. Tenant keys also scope caches, object prefixes, search filters, queues, subscriptions, idempotency keys, and background leases; matching local identifiers across tenants must not collide.

Data model and ownership

Copying identity-provider groups, OAuth tokens, and active-team choice into one mutable profile makes staleness invisible and causes deletion in one system to leave live authority in another.

Generated-application database: Required in this slice — the generated application owns app subjects, tenants, memberships, roles, sessions, and tenant-scoped domain predicates, while enterprise principals and connector grants remain in separately revocable stores.

Record or entityStore and ownerPrimary keyForeign key or opaque referenceTenant keyMaterial constraintLifecycle and deletionUse case IDs
IdentityProviderIdentity Configuration Store; Enterprise Identity Serviceidentity_provider_idOpaque customer-organization referenceorganization_idProtocol, exact issuer or entity ID, audience, callback or assertion-consumer URI, subject claim, signing metadata, and issuer aliases require verified revisionsDisabled immediately; redacted revisions retained; secrets purged after policy windowD05-UC-01
ExternalIdentityPrincipal Store; Enterprise Identity Serviceexternal_identity_idLocal foreign keys to IdentityProvider and Principalorganization_idUnique on (identity_provider_id, protocol_subject) even with issuer aliases; email is never an identity keyTombstoned on deprovision; stable subject hash and conflict audit retained; profile attributes deleted under policyD05-UC-01
PrincipalPrincipal Store; Enterprise Identity Serviceprincipal_idOpaque organization referenceorganization_idOne enterprise person or service principal per record; preview fixtures never auto-promoteDisabled on lifecycle removal; denial references retained; personal profile data later purgedD05-UC-01, D05-UC-02
ProvisioningEventProvisioning Ledger; JIT/SCIM Provisionerprovisioning_event_idLocal references to IdentityProvider and Principalorganization_idIdempotency key and source version prevent replay; provisioning success never implies login or app authorityImmutable outcome retained; payload attributes redacted or deleted by policyD05-UC-01
PlatformSessionProvider Session Store; Session Servicesession_idLocal foreign key to Principal; opaque authentication-event referenceorganization_idShort expiry, bound client and authentication strength; contains no generated-app roleCreated after validated exchange; rotated; revoked on logout/deprovision/risk event; expires and is deletedD05-UC-01, D05-UC-02
TeamMembershipMembership Store; Membership Service(team_id, principal_id)Local team reference; opaque Principal and SCIM source referencesorganization_idOne status and monotonic version per pair; principal and team must share organizationProvisioned and updated by admin or SCIM; revoke invalidates caches; audit tombstone retained before deletionD05-UC-02
ActiveTeamContextSession Store; Session Service(session_id, context_revision)Local foreign key to PlatformSession; opaque team reference validated by Membership Serviceorganization_idExactly one selected primary team per protected operation; selection never unions rolesCreated or revised by explicit selection; invalidated on membership change; expires with sessionD05-UC-02
AppSubjectBindingIdentity Binding Store; Subject Binding Servicesubject_binding_idLocal Principal reference; opaque generated-app app_subject_id referenceorganization_id plus app_idUnique active (principal_id, app_id) binding; synthetic preview subjects cannot silently promoteRevoked independently; stable IDs tombstoned for audit; optional labels later purgedD05-UC-02
AppSubjectGenerated-app identity store; generated applicationapp_subject_idOpaque subject_binding_id resolved by binding serviceapp_tenant_idTenant-bearing identity and fixture provenance mandatoryDisabled or deleted by app policy; tombstone retained while evidence depends on itD05-UC-02
AppTenantGenerated-app tenant store; generated applicationapp_tenant_idOpaque customer-organization referenceapp_tenant_idEvery role, domain resource, cache key, object prefix, job, and subscription carries tenantArchived before deletion; export and retention complete before data and encryption-key destructionD05-UC-02
AppMembershipAndRoleBindingGenerated-app authorization store; generated applicationmembership_id and role_binding_idLocal references to AppSubject, AppTenant, and AppRoleapp_tenant_idUnique active subject-tenant membership; role and resource predicates cannot be satisfied by provider project rolesRevoked immediately; versioned policy history retained; archived or deleted by tenant policyD05-UC-02
AppSessionGenerated-app session store; generated applicationapp_session_idOpaque Principal and subject-binding references; local AppSubject and membership referencesapp_tenant_idHashed token material only; audience, policy version, expiry, and server-derived tenant mandatoryExpires or revokes on binding change; token hash purged after evidence retentionD05-UC-02, D05-UC-04
ConnectorInstanceConnector Registry; Integration Control Planeconnector_instance_idOpaque downstream provider and MCP server referencesorganization_idAuthentication mode and ownership scope immutable while active; team access explicitCreated by admin; disabled before deletion; bindings revoked; metadata retained for auditD05-UC-03
WorkloadGrantConnector Grant Store; Integration Control Planeworkload_grant_idLocal ConnectorInstance and pinned connector-version references; opaque runtime workload referenceorganization_id plus app_tenant_idNon-human subject, app, environment, deployment, audience, operation, connector version, and expiry mandatoryRevoked independently; tombstoned grant and traces retained; secret destroyed and metadata later deletedD05-UC-03
DelegatedGrantDelegation Store; Delegation Brokerdelegated_grant_idLocal ConnectorInstance reference; opaque Principal, AppSubjectBinding, source-account, and Vault referencesorganization_id plus app_tenant_idUser, tenant, source, operation, audience, consent version, and bounded expiry mandatoryExpires or revokes independently; credential material destroyed immediately; tombstone retained for auditD05-UC-04
RevocationEventAppend-only evidence store; Security Operationsrevocation_event_idOpaque target reference to session, binding, workload grant, or delegated grantorganization_id plus optional app_tenant_idMonotonic target version and idempotency key prevent stale reactivationImmutable redacted evidence retained and later archived or deleted under policyD05-UC-02, D05-UC-03, D05-UC-04
AuthenticationAndGrantEventAppend-only evidence store; Audit Serviceevent_idOpaque references to provider configuration, provisioning event, session, membership version, app binding, workload grant, delegated grant, probe run, and provider eventorganization_id plus optional app_tenant_idAllow, deny, revoke, and probe outcomes are immutable and carry actor, resource, scope, precondition, expected, observed, environment, timestamp, and immutable traceAppended at decision time; sealed and retained; legal-hold aware archival and deletionD05-UC-01, D05-UC-02, D05-UC-03, D05-UC-04

Secret material and metadata have different owners: Vault stores encrypted refresh tokens or client credentials, the OAuth Broker owns lifecycle and rotation state, and the downstream provider owns actual consent and resource permissions. Deleting metadata without revoking provider authority is incomplete recovery.

The evidence suite must falsify every tempting bridge: project member without app membership, app owner without provider-project membership, workload acting as a person, app session used as connector authority, wrong source or audience, same local resource ID in another tenant, and post-revocation reuse. Each denial is paired with an unaffected positive control so a broken environment cannot masquerade as correct isolation.

Implementation reviews should use the governing specifications: OpenID Connect Core 1.0 for ID-token and relying-party validation, RFC 9700 for current OAuth security practice, RFC 8693 for token exchange subject/actor/audience semantics, RFC 7644 for SCIM lifecycle operations, and SAML 2.0 Core for assertion conditions and protocol messages.