generated from coulomb/repo-seed
265 lines
13 KiB
Markdown
265 lines
13 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`
|
|
- `prepare_account`, `update_prepared_account`, `list_prepared_accounts`,
|
|
`revoke_prepared_account`, `expire_prepared_account`,
|
|
`claim_prepared_account`
|
|
- `register_access_profile`, `list_access_profiles`, `select_active_hat`,
|
|
`export_access_control_facts`, `access_profile_diagnostics`
|
|
- `register_welcome_protocol`, `list_welcome_protocols`,
|
|
`start_onboarding_journey`, `start_onboarding_for_registration`,
|
|
`start_onboarding_for_prepared_account`, `progress_onboarding_step`,
|
|
`complete_onboarding_step`, `skip_onboarding_step`,
|
|
`fail_onboarding_step`, `resume_onboarding_journey`,
|
|
`onboarding_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`
|
|
|
|
## UI Contract Surface
|
|
|
|
`RegistrationAccessManagementUi` is the optional UI-facing contract facade for
|
|
registration and access management. It returns screen/view models and route
|
|
definitions over `UserEngineService`; transport adapters may serve those as
|
|
HTTP, RPC, desktop, CLI, or rendered HTML.
|
|
|
|
The facade covers self-service registration, factor status, terms/consent,
|
|
prepared-rights review and claim, active hat selection, admin diagnostics, and
|
|
accessible HTML verification. It does not handle credential entry, MFA
|
|
challenges, token issuance, hidden policy decisions, notifications, or
|
|
service-specific admin consoles.
|
|
|
|
## Scenario And Security Conformance Contract
|
|
|
|
`user_engine.testing.scenarios` defines `SCENARIO_MATRIX` and
|
|
`REGISTRATION_SCENARIO_MATRIX` for local conformance. The matrix covers
|
|
self-registration, prepared-account claims, privileged approval gates,
|
|
eID-backed assurance, family invite, tenant admin invite, group access,
|
|
cross-tenant denial, and USER-WP-0014 UI workflows.
|
|
|
|
Conformance tests must run without production IAM, proofing, notification,
|
|
workflow, authorization-engine, or database infrastructure. They exercise
|
|
adapter seams with local harnesses and assert fail-closed behavior, audit
|
|
evidence, outbox replay, redaction, and durable transaction semantics.
|
|
|
|
## 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.
|
|
|
|
## Prepared Account Contract
|
|
|
|
Prepared accounts are pending user-domain facts for people who have not yet
|
|
registered or have not yet claimed their prepared rights. They can carry
|
|
required factor matches, entitlement intent, preparer metadata, expiry, and
|
|
claim lifecycle state, but they do not create credentials.
|
|
|
|
`claim_prepared_account` requires a completed registration session and
|
|
unexpired verified `IdentityFactor` records that satisfy every prepared factor
|
|
requirement. A successful claim marks the package claimed and converts
|
|
prepared entitlements into user-engine-owned facts: tenant account state,
|
|
memberships, catalog validated profile values, application bindings, and
|
|
onboarding-request events.
|
|
|
|
Expired, revoked, claimed, mismatching, ambiguous, duplicate, or
|
|
approval-required packages fail closed. Denied claim decisions are audited
|
|
without outbox events. Mutation outbox payloads include ids, counts, statuses,
|
|
factor types, and journey names, but not normalized factor values.
|
|
|
|
## Access Profile And Hat Contract
|
|
|
|
Access profiles are tenant-scoped templates for selecting an active hat across
|
|
tenant, realm, service, asset, or group contexts. A profile combines required
|
|
memberships, required verified factor types, profile defaults, projection
|
|
claims, optional group references, and explicit realm/service/asset scope ids.
|
|
|
|
`select_active_hat` requires an active tenant account, satisfied membership
|
|
requirements, unexpired verified factor evidence, and authorization-port
|
|
approval. The selected hat is persisted as `ActiveAccessContext` and is exposed
|
|
through `identity_context` and claims-enrichment projections.
|
|
|
|
`export_access_control_facts` returns adapter-neutral `AccessControlFact`
|
|
records for authorization engines and ACL systems. These facts include direct
|
|
membership facts, group-derived facts, and active-context facts, but
|
|
user-engine still does not make final access decisions or enforce protected
|
|
service runtime policy.
|
|
|
|
Access-profile diagnostics report counts, factor requirement types, and
|
|
approval-required issues without exposing profile default values, projection
|
|
claim values, or raw factor values.
|
|
|
|
## Onboarding Journey Contract
|
|
|
|
Welcome protocols are tenant-scoped onboarding templates. They can match
|
|
registration completion, prepared-account claims, invitations, access-profile
|
|
events, or manual starts by trigger type and optional context keys.
|
|
|
|
Onboarding journeys are persisted user state. They track protocol, source
|
|
event, trigger type, ordered steps, task references, subsystem handoff
|
|
references, lifecycle gaps, active step, status, and correlation ids.
|
|
|
|
Registration completion and prepared-account claim automatically start matching
|
|
welcome protocols. Manual start/progress/complete/skip/fail/resume operations
|
|
are also exposed through `UserEngineService` and authorization-gated.
|
|
|
|
Missing required subsystem callbacks produce explicit lifecycle gaps and block
|
|
the journey. The service records audit/outbox events with ids, statuses, step
|
|
keys, source ids, and lifecycle gap identifiers, but not factor values, support
|
|
content, notification payloads, or subsystem-specific tour data.
|
|
|
|
## 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, optional active access context,
|
|
exportable access-control facts, onboarding journeys, 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
|
|
|
|
`user_engine.migrations` exposes the ordered durable-store manifest,
|
|
`LATEST_SCHEMA_VERSION`, logical record types, and adapter-neutral diagnostic
|
|
count keys. The isolated store's `SCHEMA_VERSION` is derived from that manifest
|
|
and its `migrate` hook must be idempotent. Database-backed stores must expose
|
|
equivalent readiness semantics before they are accepted by platform adapters.
|
|
|
|
Provider-backed Postgres adapters can use
|
|
`migrations/postgres/0001_user_engine_store.sql` as the bootstrap contract or
|
|
translate it into their own migration framework while preserving schema-version
|
|
tracking, logical record uniqueness, audit durability, and pending-outbox
|
|
reads.
|
|
|
|
Future adapters should run
|
|
`user_engine.testing.assert_user_engine_store_conformance(testcase, factory)`
|
|
with a factory that returns a fresh store. The harness covers readiness,
|
|
idempotent migration, core save/read/query behavior, transaction rollback,
|
|
outbox ordering, and diagnostics that expose counts without raw factor or
|
|
profile values.
|
|
|
|
`user_engine.store_records` defines the JSONB serialization contract for the
|
|
generic record table. `store_record_for` turns supported domain dataclasses
|
|
into `StoreRecord` envelopes with deterministic keys and index metadata, while
|
|
`domain_record_from_store_record` restores those payloads to domain objects.
|
|
These payloads are durable state and may contain sensitive values, so they must
|
|
not be emitted as diagnostics.
|
|
|
|
`user_engine.adapters.postgres.PostgresUserEngineStore` is the optional
|
|
Postgres implementation. It accepts a provider-owned DB-API or psycopg-like
|
|
connection, applies the bootstrap SQL in `migrate`, and persists generic
|
|
records, audit records, and pending outbox events without depending on a
|
|
specific driver package.
|