Record the published fail-closed PEP stance in SCOPE, fill the agent stack and architecture stubs from the shipped layout, and retire the first-session protocol now that USER-WP-0001–0024 exist. Assistant: grok Assistant-Session: 01a04cea-f0d6-7ab3-9ffd-881eb6bea6cb
198 lines
10 KiB
Markdown
198 lines
10 KiB
Markdown
# 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 is published
|
|
in `pep-stance.yaml`, tested equal to `FlexAuthHTTPAdapter`, and recorded
|
|
as stance application (`decision_id` absent) 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` ships the layer-conformance follow-through: `layer.yaml`
|
|
and `pep-stance.yaml`, fail-closed stance recording without a minted
|
|
decision id, request-bound allow lifetime, local-authorization
|
|
confinement, evidence classification and heartbeat, and the
|
|
access-control-fact claim contract.
|
|
|
|
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 `USER-WP-0024` closed, assessed in
|
|
`history/2026-08-29-security-layer-scope-intent-assessment.md`:
|
|
|
|
- `layer.yaml` plus `scripts/check_layer_conformance.py`;
|
|
- published `pep-stance.yaml`, fail-closed total, tested equal to
|
|
`FlexAuthHTTPAdapter`; engine-unavailable DENY records stance
|
|
application and carries no `decision_id`;
|
|
- `AuthorizationDecision` allows are request-bound with a 30s lifetime;
|
|
- denials and revocations are load-bearing; cadence is
|
|
`record_evidence_heartbeat()`;
|
|
- `LocalAuthorizationCheckPort` cannot be constructed when
|
|
`USER_ENGINE_FLEX_AUTH_TOKEN_FILE` is set, and `runtime.py` does not
|
|
import 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` and `layer.yaml`. Closes `USER-IN-0001`. |
|
|
| Subject context is a claim, never a decision | Held. Production asks flex-auth. Hats and access-control facts have no effect field; tests forbid compiling them into allow/deny. The local double is confined to tests/standalone. |
|
|
| PEP-shaped: no side effect without a decision or recorded stance | Met. Unavailable DENY records `stance_applied=fail_closed` and no `decision_id`. |
|
|
| Published unreachable-engine stance map, tested equal to shipped behaviour | Met (`pep-stance.yaml`). Gate-house still owes the §13.1 inventory row. |
|
|
| Every allow has a lifetime | Met. Production allows are request-bound, 30s. Standing grants are denied. |
|
|
| Evidence bound: no completeness claim; cadence for load-bearing events | Met. Classification and heartbeat in `docs/evidence-classification.md` and `UserEngineService.record_evidence_heartbeat()`. |
|
|
| 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. Layer-conformance rows above
|
|
are met by `USER-WP-0024`; the §13.1 inventory row is gate-house's.
|