user-engine/SCOPE.md
tegwick 96430299b7
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Declare Engine/PIP and open USER-WP-0024 for layer conformance
Adopt security-layer-model v0.7 in INTENT.md in this repository's own
voice, restate SCOPE.md from that declaration, and record the
scope-versus-implementation assessment. USER-IN-0001 is answered;
runtime follow-through is USER-WP-0024.

Assistant: grok
Assistant-Session: 01a04cea-f0d6-7ab3-9ffd-881eb6bea6cb
2026-08-29 11:56:06 +02:00

10 KiB

SCOPE

Layer

Engine, role PIP — deterministic API for users, accounts, and memberships. Subject context is an input to the authorization decision and never a decision. Protected mutations are PEP-shaped: they consume access-engine (flex-auth) and do not substitute for it.

Declaration: INTENT.md frontmatter. Statute: net-kingdom/canon/standards/security-layer-model_v0.7.md (accepted). Working companion: net-kingdom/SECURITY-COMPANION.md. Boundary contract unchanged: net-kingdom/canon/standards/user-engine-boundary-contract_v0.1.md.

One-Liner

Headless user-domain and identity-domain Engine (PIP) for accounts, identity links, memberships, catalogs, projections, local audit, and events, with an optional in-repo portal. It consumes NetKingdom IAM, authorization, tenant authority, provisioning, and delivery; it does not own them and it does not decide them.

In Scope

  • user and account records, and account lifecycle state;
  • external identity links keyed by (issuer, subject);
  • actor, authenticated-subject, authorization-principal, and user-context mappings from verified IAM Profile claims;
  • global, tenant, application, and membership profile values and preferences;
  • tenant, application, team, and scope memberships;
  • hats, realms, services, assets, access profiles, and active access context as user-domain facts and claim templates;
  • identity-context read models for domain consumers;
  • PIP exports: subject, membership, and access-control facts for access-engine and other engines to consume as claims;
  • canon interface cards, entity and relationship mappings, and explicit gap records;
  • application registry for profile consumers;
  • customization catalog registry, versioning, and validation;
  • effective profile resolution and projections (self-service, admin, application runtime, audit, agent, claims-enrichment);
  • local audit records and durable outbox events;
  • local evidence references derived from audit and events;
  • invitations, prepared accounts, entitlement claims, and onboarding journeys that user-engine owns;
  • public registration orchestration (start, verify, resume, cancel, provider handoff) behind an explicit runtime flag;
  • provider-neutral tenant lifecycle calls to the tenant authority (create, read, update, retire, reactivate, recover);
  • optional CSRF-protected portal over the same APIs (self-service, onboarding, tenant admin, platform operator);
  • standalone/local fixtures and a production PostgreSQL store of the modeled concept;
  • integration ports for claims, flex-auth decisions (including a rotating caller token), provisioning, registration verification, tenant management, outbox delivery, and runtime secrets;
  • PEP enforcement of access-engine decisions on user-engine-owned mutations, including a published unreachable-engine stance.

Out Of Scope

  • login, OIDC/SAML token issuance, passwords, passkeys, sessions, and MFA lifecycle — key-cape, Keycloak, or local-identity;
  • final authorization policy decisions and the protected-system registry — flex-auth / access-engine;
  • caching or compiling an authorization decision, including from hats, access profiles, or memberships;
  • durable authorization grants beyond user-engine-owned memberships;
  • tenant identifier authority, grouping reclassification, and capability role grants — tenant-engine;
  • application-owned first-login profiles, unlink, and action step-up — consuming apps (e.g. coulomb-social) and KeyCape client policy;
  • policy, control, access-review, exception, and organization source-of-truth ownership;
  • runtime secret custody — OpenBao / Railiance; no OpenBao client here;
  • a Keycloak or key-cape admin client;
  • platform audit store and transactional SMTP — audit-core and email-connect;
  • full SCIM server, enterprise directory replacement, or inbound SAML/OIDC federation (demand-triggered; Keycloak expanded mode is the published path);
  • a generic extracted profile engine;
  • observing production security events — kings-guard, and currently unstaffed;
  • actuation: reduce authority, require step-up, isolate a workload — an Engine concept held at zero estate-wide.

The in-repo portal is an optional surface, not a UI product. Password and MFA screens stay on the identity provider. LocalAuthorizationCheckPort is a test and standalone double, not a production decision point.

Boundary Rule

user-engine owns user-domain facts, identity-context mappings, and projections. Adjacent systems provide authentication, IAM claims, authorization decisions, tenant authority, policy/control definitions, deployment, event transport, durable audit, secrets, organization records, or additional UI — and they integrate through explicit adapters. They must not become hidden sources of profile or identity-domain truth.

user-engine must not become a hidden source of authorization truth. Memberships, hats, and access-control facts are claims. access-engine renders the decision. When access-engine is unreachable, shipped behaviour is fail-closed for protected mutations; that stance still has to be published, tested equal to the code, and recorded as stance application rather than as a minted local decision id.

Governing published contracts:

Current Status

Workplans USER-WP-0001 through USER-WP-0023 are finished. The isolated MVP, multi-tenancy, catalogs, canon alignment, durable PostgreSQL store, self-service and admin portal, public-registration orchestration, and flex-auth caller identity (live A2 on flex-auth-user-engine) are in the repo and, where applicable, on Railiance.

USER-WP-0024 is the active workplan: layer declaration is in INTENT.md; machine-readable conformance, the published PEP stance map, decision lifetime, evidence cadence, and the access-control-fact claim contract are not yet shipped.

Still operator-owned, not remaining product scope:

  • public registration and outbox mail stay fail-closed until governed OpenBao verification/delivery tokens and the transactional SMTP lane are installed;
  • the live tenant-lifecycle probe from a user-engine pod (GET / PATCH / retire / reactivate on a disposable tenant) is still owed;
  • policy.enabled and tenant-engine caller enforce belong to flex-auth / tenant-engine.

Layer-model residue that is remaining product scope, tracked in USER-WP-0024 and assessed in history/2026-08-29-security-layer-scope-intent-assessment.md:

  • no layer.yaml and no conformance check;
  • unreachable-engine stance is fail-closed in FlexAuthHTTPAdapter but unpublished, untested against a map, and recorded as a locally minted decision_id;
  • AuthorizationDecision carries no lifetime;
  • denials have no declared emission cadence or heartbeat;
  • LocalAuthorizationCheckPort defaults to allow and is a second decision point if a production runtime ever constructed it.

Against INTENT.md

INTENT is the stable aspiration. Against the pre-layer product aims, the repo still does the job it set out to do. Against the layer declaration now in INTENT, SCOPE is narrower than INTENT on conformance artifacts and PEP obligations.

INTENT aim Status
Headless user-domain service, provider- and PDP-agnostic Met. Ports and adapters; production uses IAM Profile v0.3 and flex-auth.
Standalone now, multi-tenant / multi-app later Met. Fixtures and in-memory conformance plus live PostgreSQL and Railiance.
Users, links, memberships, catalogs, projections, events Met.
NetKingdom identity-domain integration layer Met for the owned slice. Consumes KeyCape, flex-auth, tenant-engine, identity-provisioner, audit-core, email-connect.
Applications answer who / which scopes / what to project Met via /me, identity context, catalogs, and projections.
Engine / PIP declaration in own voice Met in INTENT.md as of 2026-08-29. Closes the declaration half of USER-IN-0001.
Subject context is a claim, never a decision Held in production path (FlexAuthHTTPAdapter). Not yet proven for hats/access-control facts under §6.1, and the local double can still decide.
PEP-shaped: no side effect without a decision or recorded stance Partial. Production asks flex-auth and fail-closes on errors. Stance is unpublished; unavailable DENY mints a local decision_id.
Published unreachable-engine stance map, tested equal to shipped behaviour Missing.
Every allow has a lifetime Missing on AuthorizationDecision.
Evidence bound: no completeness claim; cadence for load-bearing events Partial. Mutations enqueue audit+outbox in the same store transaction. Completeness is not claimed in code; docs do not classify load-bearing vs attributive or declare a cadence.
Not an IdP, PDP, secret store, directory, or org authority Held.
Optional UI, not UI-driven Held, with a narrower reading: an optional portal now lives in this repo over the same APIs. INTENT's "not a UI application" still applies to product identity.
Canon-aligned mappings without taking IAM as SoT Met (USER-WP-0007, interface card). Access-review, policy, and control remain references, not owned records.
Path from local setup to governed NetKingdom deploy Met.
No OpenBao / key-cape admin client Held. SecretProvider is an unused port; runtime reads env.

Still aspirational, and deliberately not started here:

  • inbound federation / SCIM / directory sync — new workplan only on tenant demand, targeting published Keycloak expanded mode;
  • first-class access-review and governance records;
  • a dedicated agent consumption product (projections exist);
  • extracting a generic profile engine;
  • observing production, or actuating containment — estate-wide zeros, not this repo's gaps to close.

Those remain INTENT, not a hole in SCOPE, except the layer-conformance rows above, which are now SCOPE because INTENT has adopted the accepted standard.