Files
user-engine/docs/contracts.md

139 lines
6.0 KiB
Markdown

# Public Contracts
## Headless Service Surface
`UserEngineService` is the stable in-process API for the current MVP. Future
HTTP or RPC adapters should preserve these operation names:
- `health`, `readiness`, `operability_snapshot`, `outbox_diagnostics`
- `start_registration`, `attach_registration_factor`, `complete_registration`,
`abandon_registration`, `expire_registration`, `resume_registration`,
`registration_diagnostics`
- `me`, `create_user`, `set_account_status`, `link_identity`
- `resolve_tenant_context`, `set_tenant_account_status`, `add_membership`,
`tenant_diagnostics`
- `register_application`, `publish_catalog`
- `set_profile_value`, `effective_profile`, `projection`, `identity_context`
- `onboard_family_dataspace`, `invite_family_member`,
`resend_family_invitation`, `revoke_family_invitation`,
`accept_family_invitation`
- `audit_records`, `outbox_events`
## Registration Contract
Registration is a headless user-entry facade. It creates a
`RegistrationSession`, accepts safe `FactorVerification` evidence from external
proofing adapters, records persisted `IdentityFactor` metadata, and completes
the session into a stable NetKingdom ID.
The first NetKingdom ID contract is `User.user_id`: an opaque, stable user
identifier that must not encode IAM issuer/subject pairs, email addresses,
phone numbers, postal addresses, eID payloads, tenant names, or other proofing
data.
Registration completion creates or resolves a `User`, `Account`,
`TenantAccount`, and `ExternalIdentity` link for the verified actor, attaches
verified factors to that user, emits audit/outbox records, and returns
`identity_context`.
user-engine does not verify factors itself, issue credentials, perform MFA,
run eID proofing, or issue tokens. Those remain external IAM/proofing adapter
responsibilities.
## Identity Context Contract
`identity_context` is the first canon-facing read model for NetKingdom
identity-domain consumers. It resolves a verified actor into the local user,
account, external identity links, tenant scope, memberships, optional
application scope, optional effective profile, canon entity references,
relationship references, grant-like membership facts, and evidence references.
The method keeps these concepts distinct:
- user-engine `User` record;
- operational `Account`;
- external `Identity Record` and scoped issuer/subject identifier;
- `Actor` from verified claims;
- `Authenticated Subject` projected from issuer and subject;
- `Authorization Principal` projected for policy evaluation;
- `Tenant`, `Team`, `Scope`, `Membership Relationship`, and `Role` references.
Evidence references are currently derived from local audit records. External
policy, control, access-review, exception, and lifecycle task references belong
to adapter contracts and remain non-owned unless a later workplan assigns
source-of-truth responsibility to user-engine.
## Family Dataspace Onboarding Contract
`onboard_family_dataspace` is a convenience facade for personal-family
identity-domain setup. It composes existing user, account, tenant-account,
membership, application, catalog, profile, audit, outbox, projection, and
identity-context operations.
The facade represents a family as a NetKingdom tenant plus a `family` scope. It
does not provision the tenant, issue SSO tokens, own credentials, or implement
the protected dataspace runtime. Family roles are scoped membership facts such
as `owner`, `adult`, `child`, `guest`, and `delegated-caretaker`; authorization
systems decide how those facts affect access.
Invitation acceptance requires already-verified claims. user-engine stores
local invitation lifecycle, links the verified external identity, activates
account state, and returns both `identity_context` and a
`CLAIMS_ENRICHMENT` projection for SSO adapters.
## Error Taxonomy
- `ValidationError`: caller supplied an invalid shape, state transition, or
catalog/profile value.
- `AuthorizationDenied`: the authorization port or tenant boundary denied the
operation.
- `NotFoundError`: a requested user, account, or active attribute is missing.
- `ConflictError`: uniqueness or ownership would be violated.
## Catalog Contract
Catalogs are active by namespace and owning application. Attribute keys must
use the namespace prefix. Active namespace ownership cannot move to another
application. Catalog updates cannot move versions backwards or downgrade
attribute sensitivity.
## Projection Contract
Application runtime, agent-context, and claims-enrichment projections require
an `application_id` and are filtered to that application's active catalogs.
Sensitive and secret values are redacted outside admin, audit, and
self-service projections.
## Audit And Event Contract
Every mutating service operation appends an audit record and outbox event with
the same correlation id and resolved tenant. Authorization denials are audited
without emitting outbox events.
Local audit records may be exported as identity-canon `Evidence Source`
references. Durable platform audit custody remains outside user-engine.
## Durable Store Contract
`UserEngineService` depends on the `UserEngineStore` protocol, not the
in-memory adapter's concrete collections. Store implementations must expose
schema readiness, logical record accessors, audit-log reads, pending-outbox
reads, adapter-neutral record counts, and a `transaction` context for atomic
mutations.
Mutating writes happen after validation and authorization, inside the store
transaction. Domain changes, local mutation audit records, and outbox events
must commit or roll back together. Authorization-denial audit records must
remain durable without outbox events, including when a denial occurs inside a
composed mutation that rolls back other writes.
Postgres-specific connection handling, SQL, locks, credentials, tenant
isolation primitives, backup, restore, and platform observability remain
adapter or provider concerns outside the domain service.
## Migration Contract
The isolated store exposes `SCHEMA_VERSION = 0001_initial` and a `migrate`
hook. Database-backed stores must expose equivalent readiness semantics before
they are accepted by platform adapters.