Files
net-kingdom/canon/standards/user-engine-boundary-contract_v0.1.md

18 KiB

id, type, title, domain, status, version, created, updated, scope, workplan, related
id type title domain status version created updated scope workplan related
netkingdom-user-engine-boundary-contract standard NetKingdom User Engine Boundary Contract v0.1 netkingdom accepted 0.1 2026-05-22 2026-05-22 user-domain-boundaries
workplans/NK-WP-0014-user-engine-preparation-boundary-contracts.md
canon/standards/iam-profile_v0.2.md
canon/standards/playbook-capability-contract_v0.1.md
docs/responsibility-map.md
docs/user-engine-interface-guidance.md
docs/reviews/2026-05-22T19-19-59+0200-user-engine-architecture-review.md
docs/user-engine-netkingdom-integration-assessment.md (current intent/scope fit, gaps, and recommendations)

NetKingdom User Engine Boundary Contract v0.1

Purpose

This contract defines how user-engine integrates into the NetKingdom landscape without duplicating IAM, authorization, application registration, deployment, audit, or UI responsibilities.

user-engine owns user-domain facts and profile projections. NetKingdom owns the cross-repo boundary contract. Implementations and adapters must preserve the ownership rules below even when they use local fixtures for development or standalone deployments.

Ownership Model

user-engine is a headless user-domain and profile service. It is not an identity provider, MFA system, policy decision point, runtime secret store, deployment engine, or UI repository.

Concern Owner user-engine responsibility
OIDC discovery, login, token issuance key-cape, Keycloak, or local-identity in dev Consume verified IAM Profile claims
Passwords, passkeys, sessions, MFA IAM/MFA stack No storage or lifecycle responsibility
Stable identity links user-engine Map (issuer, subject) to user_id
Account lifecycle and profile facts user-engine Canonical source of truth
Product memberships user-engine unless explicitly imported Own, validate, export as read models
Coarse authentication groups and roles IAM provider normalized through the IAM Profile Consume as actor facts
Fine-grained authorization flex-auth Ask, enforce, and audit decisions
Runtime secrets OpenBao/Railiance platform services Consume scoped secret references through adapters
Deployment mechanics Railiance and application repos Publish requirements and readiness signals
Self-service/admin UI future UI repos Provide APIs and projections only

Source-Of-Truth Matrix

Resource kind Source of truth user-engine relation Boundary rule
OIDC issuer and discovery metadata IAM Profile implementation Consume issuer metadata and JWKS through adapters Never hardcode provider-specific paths where discovery is available
Login, session, MFA, and token lifecycle key-cape, Keycloak, or local-identity in non-production Accept only verified claim envelopes user-engine must not issue, refresh, or revoke tokens
Identity claims IAM Profile implementation Normalize into an actor envelope Claims are authentication facts, not final authorization decisions
Human subject IAM provider for authentication identity; user-engine for domain record Link (issuer, subject) to user_id Email, username, and display name are mutable attributes, not keys
Local/bootstrap identities local-identity Allowed only in local/test/standalone modes Production adapters must reject local or loopback issuers
User record user-engine Canonical owner Other systems may reference user_id but must not mutate the record directly
Account lifecycle user-engine Canonical owner IAM disablement may trigger import/sync events, but user-engine records lifecycle state
Groups IAM provider Consume from claims or imports as identity facts Groups do not overwrite user-engine-owned memberships
Coarse roles IAM provider, normalized into roles Consume as actor facts for policy input Roles are not user-engine resource ownership
Fine-grained roles, scopes, policies flex-auth Register resources/actions and request decisions user-engine does not interpret policy packages locally in production
Tenant identifiers NetKingdom/IAM Profile contract Store tenant-scoped records and memberships Tenant admin authority never implies tenant:platform authority
Product memberships user-engine unless an import contract says otherwise Canonical owner for local facts Every imported membership carries source, version, freshness, and delete semantics
External/provisioned memberships Provisioning system under import contract Store as externally mastered facts user-engine may expose/read them but must not silently take ownership
Applications as profile consumers user-engine Own application record and allowed profile scopes Does not replace IAM clients, protected systems, or deployments
OIDC clients IAM provider Store binding metadata only Client secrets and redirect validation stay with IAM
Protected systems flex-auth Store binding metadata and resource/action vocabulary reference flex-auth remains PDP and protected-system registry owner
Catalog namespaces user-engine Canonical owner and validator Namespaces bind to one owning application and version policy
Profile and preference values user-engine Canonical owner Attribute definitions must resolve to a catalog namespace or governed global key
Effective-profile projections user-engine Canonical resolver and projection API Projections are read models with version/freshness metadata
Claims enrichment inputs IAM-side adapter Optional profile read from user-engine Adapter owns cache, freshness, and failure mode; login must not synchronously depend on user-engine
Runtime secrets and DB credentials OpenBao/Railiance platform services Consume logical secret names through SecretProvider Secret values must not be stored in profile/catalog records
Deployment metadata Railiance/application repo Store binding references where needed for onboarding Railiance executes deployment and readiness mechanics
Authorization decisions flex-auth Enforce returned decisions and obligations Sensitive writes fail closed when decisions are unavailable
Local audit record user-engine Canonical owner for local mutation trail Must carry correlation fields to decision and event records
Decision audit flex-auth Store returned decision id user-engine audit must link to the decision id where a check occurred
Platform audit sink NetKingdom/Railiance audit service Emit redacted summaries Sensitive profile payloads are not exported by default
Domain events user-engine outbox Canonical source for user-domain lifecycle events Events are durable after commit and carry schema/version identifiers

Membership Synchronization Contract

Every membership fact that crosses a system boundary must carry this envelope:

Field Requirement
membership_id Stable id for the fact in the owning system
owner_system One of user-engine, iam, provisioning, or another explicit source
source_system System that last supplied the fact
subject_user_id user-engine user_id when resolved
issuer and subject Original identity key when a user link is not yet resolved
tenant Tenant context such as tenant:platform or tenant:coulomb
scope_type tenant, application, team, catalog, or a contract extension
scope_id Stable id inside the scope type
relation Role, relation, or membership kind
freshness Timestamp, version, sequence, or lease/expiry marker
delete_semantics tombstone, disable, expire, or hard_delete_requested
conflict_rule owner_wins, newer_version_wins, or an explicit manual-review rule
correlation_id Request/import/export correlation id

Allowed ownership classes:

Class Rule
user_engine_mastered Created and mutated in user-engine; exported outward as read models only
iam_imported_seed IAM group/role data may seed a local membership once, but does not continue overwriting it unless a contract says so
externally_provisioned Provisioning source remains owner; user-engine stores the fact with source/version/delete semantics
flex_auth_export user-engine exports subject facts to flex-auth for policy input; flex-auth does not become the membership store
iam_export_requested Optional adapter-owned export for coarse IAM groups/claims; user-engine remains owner unless explicitly transferred

Conflict handling:

  • owner wins by default;
  • non-owner updates are rejected or stored as pending import review;
  • stale imports are ignored when their freshness marker is older than the current fact;
  • cross-tenant imports must be rejected unless the import contract explicitly maps source tenant to target tenant;
  • deletes from a non-owner source disable only that source's externally mastered fact and must not remove user-engine-owned memberships.

Freshness and invalidation:

  • membership writes emit outbox events with a version stamp;
  • exports to flex-auth carry the membership version used to build the subject fact;
  • consumers must be able to tell whether an authorization decision used stale membership facts;
  • high-risk membership changes invalidate request caches and short-lived decision caches.

Application Onboarding Contract

A platform application is represented by several records. They are bound together, but not merged into one ownership domain.

Binding Owner Required fields
user-engine application user-engine application_id, display name, owner, allowed profile scopes, projection types, lifecycle state
IAM OIDC client key-cape or Keycloak client id, issuer, redirect URIs, allowed scopes, assurance requirements
flex-auth protected system flex-auth protected-system id, resource/action vocabulary, policy package binding
Catalog namespace user-engine namespace, owning application id, catalog id, versioning and deprecation policy
Deployment metadata Railiance/application repo environment, service name, tenant placement, ingress/readiness endpoints
Audit/event identity user-engine plus platform sink source application id, event subject prefix, correlation-id policy

Minimum binding record:

application_id: string
tenant_scope: string
iam:
  issuer: string
  oidc_client_id: string
flex_auth:
  protected_system_id: string
  resource_vocabulary_version: string
catalog:
  namespace: string
  active_catalog_version: string
deployment:
  environment: string
  service_name: string
audit:
  event_source: string
  correlation_policy: required

Safe onboarding checklist:

  1. Register or approve the application owner and tenant scope.
  2. Create the IAM OIDC client with redirect URIs, scopes, and assurance requirements.
  3. Register the flex-auth protected system and policy package.
  4. Create the user-engine application record and bind the IAM/flex-auth ids.
  5. Register the catalog namespace and publish the first catalog version.
  6. Define projection types the application may request.
  7. Register event source and audit redaction rules.
  8. Record Railiance deployment metadata and readiness endpoints.
  9. Verify one authorized profile read, one denied profile read, one authorized mutation, one denied mutation, and correlated audit/event output.

Projection And Claims-Enrichment Boundaries

Projection types are distinct contracts:

Projection type Consumer Required boundary
self_service Current user Includes only fields visible/editable by the subject under policy
admin Tenant or platform admin tools Requires flex-auth checks and tenant/platform authority separation
application_runtime Registered applications Limited to allowed profile scopes and catalog namespace bindings
audit Operators and audit sinks Redacted summaries with correlation metadata, not full sensitive payloads
agent_context Autonomous or delegated agents Policy-filtered context with actor/delegation evidence
claims_enrichment IAM-side enrichment adapter Optional, cache/freshness governed, and never token issuance itself

Required projection metadata:

  • projection type;
  • target user id;
  • tenant and application context;
  • catalog/profile version stamps;
  • redaction policy used;
  • authorization decision id where a decision was needed;
  • freshness timestamp;
  • correlation id.

Claims enrichment rules:

  • user-engine must not issue tokens;
  • IAM owns token issuance and the enrichment adapter;
  • enrichment adapters must define cache TTL, stale-read policy, and failure behavior;
  • privileged or destructive login claims must not depend on stale profile enrichment;
  • when user-engine is unavailable, the adapter either omits optional enriched claims or fails according to IAM-side policy, not user-engine policy.

Authorization Contract

user-engine is a policy enforcement point. flex-auth is the policy decision point for production authorization decisions.

Minimum authorization request:

actor:
  issuer: string
  subject: string
  tenant: string
  principal_type: human | service | agent
  roles: [string]
  groups: [string]
  scopes: [string]
  assurance: object
resource:
  type: string
  id: string
action: string
context:
  tenant: string
  application_id: string | null
  target_user_id: string | null
  projection_type: string | null
  correlation_id: string

Resource/action vocabulary:

Resource Baseline actions
user-engine:user read, create, update, deactivate, delete_request
user-engine:identity-link read, link, unlink
user-engine:profile read, update, resolve, project
user-engine:membership read, assign, remove, import, export
user-engine:application register, read, update, deactivate
user-engine:catalog register, activate, deprecate, migrate
user-engine:projection read, render, invalidate
user-engine:audit read, export_summary

Performance model:

  • single sensitive writes use synchronous flex-auth checks and fail closed;
  • list screens and bulk admin operations should use batch checks;
  • request-scoped memoization is allowed for identical checks within one request;
  • short-lived decision caches are allowed only for low-risk reads when the policy package permits caching and names invalidation events;
  • local policy fixtures are allowed only for tests and standalone development;
  • production adapters must record the flex-auth decision id or equivalent decision correlation.

Audit Correlation Contract

Every user-engine mutation and sensitive read must create or reference a correlation bundle:

Field Requirement
correlation_id Stable id propagated across request, decision, audit, and event records
request_id Transport/request id where available
actor IAM Profile actor envelope or redacted service/agent equivalent
tenant Tenant context for the action
application_id Application context where applicable
target_user_id Target user where applicable
resource and action user-engine resource/action pair
authorization_decision_id flex-auth decision id when an authorization check occurred
user_engine_audit_id Local audit record id
outbox_event_id Event id when a domain event is emitted
redaction_policy Policy used to summarize sensitive fields
change_summary Redacted mutation summary

Platform audit sinks receive summaries. They must not receive full profile payloads, secret values, or catalog-sensitive values unless a future contract explicitly authorizes that export path.

user-engine Repo Readiness

The user-engine repository may start production-code implementation when these artifacts exist and remain aligned with this contract:

Artifact Required purpose Current expected path
Scope boundary State in/out-of-scope responsibilities /home/worsch/user-engine/SCOPE.md
Architecture notes Explain IAM, flex-auth, platform, UI, and deployment boundaries /home/worsch/user-engine/wiki/ArchitectureBlueprint.md
Repo layout decision Keep domain logic independent from transports and adapters /home/worsch/user-engine/docs/development.md
Local development contract Define standalone vs platform configuration and guardrails /home/worsch/user-engine/docs/configuration.md
NetKingdom integration notes Translate this contract into repo-local ports/adapters /home/worsch/user-engine/docs/interfaces/netkingdom-integration.md
Implementation workplans Carry implementation tasks in user-engine, not NetKingdom /home/worsch/user-engine/workplans/USER-WP-0001 through USER-WP-0006

Readiness checklist:

  • source-of-truth boundaries are documented before new stores are added;
  • membership imports/exports identify owner, source, freshness, and delete semantics;
  • application records bind, but do not own, IAM clients and flex-auth protected systems;
  • projections include version/freshness and redaction metadata;
  • claims enrichment is optional and adapter-owned;
  • authorization ports can support synchronous, batch, memoized, and safe-cache modes;
  • audit records can correlate with flex-auth decisions and outbox events;
  • implementation work remains in user-engine workplans while NetKingdom keeps only boundary and orchestration responsibilities.