| Product-domain memberships | user-engine unless imported by contract | Canonical owner for local membership facts |
| Authentication groups and coarse roles | IAM provider, normalized into IAM Profile claims | Consumed as actor facts, not treated as final authorization |
| Audit/event identity | user-engine plus platform sink | source application id, correlation id policy, event subject prefix |
Application onboarding is ready when all bindings exist, the app can request a
runtime projection through user-engine, flex-auth can decide its protected
actions, and audit/event correlation works for at least one profile read and
one profile mutation.
## Membership Synchronization Contract
Membership facts are allowed to cross systems only with explicit ownership.
| Flow | Rule |
| --- | --- |
| IAM groups/roles -> user-engine | Import only as identity facts or mapped seed data. Do not silently overwrite user-engine-owned memberships. |
| user-engine memberships -> flex-auth | Export as subject facts/read models for policy input. flex-auth decides, but does not become the membership store. |
| external provisioning -> user-engine | Mark imported records as externally provisioned and preserve source, version, and deletion semantics. |
| user-engine -> IAM | Optional and adapter-owned; used only when IAM needs coarse groups/claims. |
Every membership fact needs:
- source system;
- owning system;
- tenant/scope;
- subject user;
- membership kind;
- freshness/version;
- delete/disable semantics;
- conflict rule.
## Projection Boundaries
Projection types must stay distinct:
-`self_service`: what the current user may inspect or edit.
-`admin`: what a scope admin may inspect or mutate.
-`application_runtime`: what a registered app may consume at runtime.
-`audit`: redacted summaries for traceability.
-`agent_context`: policy-filtered context for delegated or autonomous agents.