# User-engine enterprise identity extension points ## Purpose This document freezes the compatibility seams for later customer-owned directories and identity providers. It does not enable enterprise federation; `NK-WP-0011` remains demand-triggered. ## Stable ownership boundaries | Concern | Authority | | --- | --- | | Authentication, MFA, federation protocol, upstream session | KeyCape or Keycloak | | Customer directory users and groups | Customer directory | | Platform user profile, tenant membership and lifecycle projection | user-engine | | Fine-grained authorization decision | flex-auth | | Credential and secret custody | NetKingdom/OpenBao | | Audit evidence | owning service plus platform audit sink | User-engine must consume verified IAM Profile claims and provider-neutral lifecycle events. It must not store enterprise passwords, MFA factors, SAML assertions, refresh tokens, or directory administrator credentials. ## Adapter seams ### OIDC and SAML federation KeyCape/Keycloak terminates OIDC or SAML and emits the same IAM Profile envelope used by local identities. Upstream issuer and subject remain traceable in a private provenance claim while downstream applications trust only the canonical platform issuer. ### SCIM provisioning A future SCIM adapter translates customer create, update, suspend and delete events into idempotent user-engine lifecycle commands. It uses an immutable provider object identifier plus tenant identifier as its key. SCIM transport, bearer credentials and retry queues stay outside the user-engine domain. ### JIT provisioning JIT may create a pending platform projection after a successfully verified login. It must not grant tenant-admin or platform authority solely from an unmapped upstream claim. Privileged mappings require a pre-approved mapping rule or an existing platform-side membership. ### Directory group mapping Mappings are tenant-scoped, versioned and deny ambiguous multi-tenant envelopes. Raw customer group names are never interpreted as platform roles without an explicit mapping. Platform roles and `tenant:platform` remain reserved. ## Conflict and freshness rules - Immutable provider subject identifiers win over mutable email addresses. - Email is a login/display alias, not the cross-system identity key. - Customer-owned attributes are refreshed from the customer source; platform memberships and application preferences remain platform-owned. - Suspension or offboarding from an authoritative customer source fails closed for new sessions and invalidates cached authorization projections. - Duplicate email or provider-subject collisions enter reconciliation; they are never merged automatically. - Events carry provider version/time, correlation ID and idempotency key. Older events cannot overwrite newer state. - A stale connector cannot silently reactivate a suspended identity. ## Offboarding and failure behavior Customer offboarding first blocks authentication, then suspends the user-engine tenant account and emits revocation/audit events. Destructive profile deletion is delayed by retention policy. Provider outage preserves the last known projection but does not bypass authentication, MFA, suspension or freshness limits. ## Demand triggers Enterprise implementation begins only when a named tenant supplies: - protocol and provider choice; - authoritative attribute/group contract; - lifecycle and offboarding SLA; - acceptable freshness window; - tenant-specific role mappings; - test tenant and rollback owner. Until then, local LLDAP plus KeyCape remains the managed identity path. ## Provider reconciliation contract The local LLDAP adapter establishes the provider-neutral operational pattern that later enterprise adapters must preserve: - `drift` performs a read-only comparison of desired identity, tenant groups, roles, and lifecycle status; - `reconcile` converges only adapter-owned attributes and reports every change; - ambiguous email/subject conflicts fail for explicit repair instead of silently relinking an identity; - newly created identities are compensated when initial group projection cannot complete; - deprovisioning is replay-safe, and transient transport failures may be retried only with the caller's required idempotency key. SCIM and directory-synchronization adapters should implement this same seam instead of adding provider-specific repair behavior to user-engine.