user-engine/SCOPE.md

197 lines
10 KiB
Markdown
Raw Normal View History

# 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;
2026-06-05 16:04:43 +02:00
- 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
2026-06-05 16:04:43 +02:00
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:
- IAM Profile v0.3 — https://policy.coulomb.social/standards/iam-profile/v0.3/
- Tenancy Posture v0.1 — https://policy.coulomb.social/standards/tenancy-posture/v0.1/
- NetKingdom architecture — https://policy.coulomb.social/architecture/net-kingdom/v0.1/
- User-engine boundary contract (accepted, not yet published) —
`~/net-kingdom/canon/standards/user-engine-boundary-contract_v0.1.md`
- NetKingdom Security Layer Model v0.7 (accepted) —
`~/net-kingdom/canon/standards/security-layer-model_v0.7.md`
- Working companion —
`~/net-kingdom/SECURITY-COMPANION.md`
## 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.