user-engine/INTENT.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

12 KiB

layer role standard companion declared
Engine PIP net-kingdom/canon/standards/security-layer-model_v0.7.md net-kingdom/SECURITY-COMPANION.md 2026-08-29

INTENT

This file captures why this repository exists, the direction it is moving toward, and the kind of system it is meant to become. It is intentionally aspirational and stable, not a description of current implementation.

Layer

Engine, role PIP. This is user-engine's own declaration under the NetKingdom Security Layer Model (SECURITY-COMPANION.md v0.2; statute security-layer-model_v0.7.md, accepted 2026-08-29). A layer stated about this repository by another repository is not a declaration; this one is.

The same authoritative user-domain inputs yield the same result. That determinism is the test. user-engine is not Staff: it is not a judgment surface. It is not Tooling: it does not package identity infrastructure or hold runtime secrets. It is not the PDP: access-engine (flex-auth until the governed rename) is the only decision point in the estate.

The catalog row we accept: users, accounts, memberships. The existing boundary contract (net-kingdom/canon/standards/user-engine-boundary-contract_v0.1.md) holds unchanged. What the model adds, and what this file now states in our own voice:

  • we supply subject context as claims a decision consumes;
  • we never render, cache, or compile an authorization decision;
  • a new engine is a PIP unless the statute is amended, and we stay one.

PEP-shaped, same layer. Protected mutations in this service — account lifecycle, memberships, invitations, registration orchestration, hat selection, catalog and profile writes — proceed only after a decision from access-engine, or under a published unreachable-engine stance whose application is recorded in place of a decision. Being PEP-shaped does not move the repository out of Engine/PIP. The stance map belongs at a path named in the machine-readable layer declaration, registered in statute §13.1; shipping fail-closed in an adapter is not publication.

Not contested. Engine/PIP is the right assignment. What we raise back is that §4 catalogues us as Engine/PIP and does not mark the PEP shape that our protected mutations already have. That is a register finding, not a layer dispute.

Binding rules this repository keeps

  1. One decision point. access-engine renders authorization decisions. user-engine asks, enforces, and records. Access-control facts, hats, memberships, and projections are inputs and read models, never a local allow.
  2. Compiled data that determines an outcome is still deciding. A registry, cache, or access-profile schema that resolved a result before the engine ran would be an early decision. Provenance of anything we export as claims must remain reconstructable from the decision record that consumed it.
  3. Doctrine arrives as a claim. Nothing we hold — membership, hat, assurance forwarded from IAM, tenant capability roles — becomes authority except by reaching access-engine as a request claim or a versioned policy rule.
  4. Adaptive systems may only tighten. user-engine does not manufacture authority, and it does not assume the estate can contain anything automatically. Actuation is unowned and held at zero.
  5. Every allow has a lifetime. A decision we enforce is used within its stated binding and lifetime, not as a standing grant.
  6. Evidence proves alteration and truncation, not omission at source. Local audit and the durable outbox prove the records they hold. They do not prove that an event never sent did not happen. Completeness is not claimed.
  7. Agents working this repository are Staff principals, not a second layer. No standing credential, tool use only as a conduit or an Engine API, memory is not a state plane, every action reconstructable as the caller's. How to get a credential or a lane is ops-warden's, not this file's.

Tooling. §5 binds Staff. This Engine owns the persistence of the concept it models (the user-domain store). It consumes verified IAM Profile claims from key-cape / Keycloak / local-identity, and runtime secret references injected by Railiance. It holds no OpenBao client and no Keycloak admin client. A SecretProvider port exists so an engine surface can replace environment injection when secrets-engine exposes one; until then that capability is at zero here, not taken locally.

Purpose

user-engine exists to provide a reusable, headless user-domain and identity-domain service for products and platforms that need account, profile, preference, membership, identity-context, and application-specific user attribute management without coupling those concerns to a particular identity provider, authorization engine, security stack, or user interface.

As a PIP it is the estate's source of user-domain facts that authorization and consuming applications may take as claims: who the subject is in a domain context, which account and memberships apply, which profile material may be projected, and which identity-context mappings hold.

Primary Utility

The project provides a canonical user layer that can start small in a standalone service and grow into governed multi-tenant, multi-application, and multi-team environments.

It manages:

  • users and account state;
  • external identity links;
  • actor, principal, subject, and user-context mappings;
  • profile and preference data;
  • tenant, application, and team memberships;
  • application-registered customization attributes;
  • catalog-driven profile schemas;
  • profile projections for consuming applications;
  • lifecycle and profile-change events.

Those records are the PIP surface. They are not a policy package.

Strategic Direction

user-engine is intended to become the NetKingdom identity-domain integration layer: a headless Engine that exposes canonical identity, user, account, membership, tenant, team, profile, lifecycle, and evidence-facing concepts to applications, and that supplies those facts as claims to access-engine, without requiring those applications to know the technical IAM, security, authorization, audit, or secret-management implementation details.

NetKingdom infrastructure remains the source of truth for authentication, credential assurance, token issuance, policy decisions, security controls, runtime secrets, and platform audit infrastructure. user-engine consumes those capabilities through explicit adapters and presents a stable domain model aligned with identity-related InfoTechCanon concepts.

In this role, user-engine should make identity-domain questions easy for applications and agents to answer:

  • who the current actor is in a domain context;
  • which user, account, external identity, principal, or subject references are involved;
  • which tenant, team, application, and membership scopes apply;
  • which user-domain facts may be projected into runtime, admin, audit, agent, or claims-enrichment contexts;
  • which lifecycle, access-review, evidence, or integration gaps need attention.

It should never answer whether an actor may act. That answer is access-engine's, including when the resource is a user-engine record.

Strategic Role

user-engine separates user-domain management from authentication, authorization, credential lifecycle, and UI experience concerns.

It is intended to integrate through standards-aligned interfaces with NetKingdom IAM, identity providers, provisioning sources, directories, authorization systems, security controls, event sinks, audit infrastructure, and optional UI surfaces while remaining useful in simple standalone deployments.

It may implement identity-canon entities when they are user-domain facts or identity-context mappings. It should reference, map to, or consume adjacent canon entities when their source of truth belongs to NetKingdom infrastructure, security, access-control, governance, or organization systems.

Hats, realms, services, assets, and access profiles stay user-domain facts and claim templates. They exist so access-engine and consuming runtimes can see the same subject context; they do not become a second decision point by compilation or by local evaluation.

Intended Users

  • application developers adding user/account functionality to a service;
  • platform teams integrating NetKingdom identity infrastructure across multiple applications;
  • product teams needing self-service account and preference capabilities;
  • operators and tenant administrators managing scoped user populations;
  • agentic systems that need structured access to user preferences and profile context;
  • domain services that need identity-canon aligned user, actor, principal, subject, tenant, team, membership, and evidence references without depending on technical IAM implementation details;
  • access-engine, as a PIP consumer of subject, membership, and access-control facts.

Product Boundaries

user-engine is the headless backend and domain service.

It does not aim to be:

  • a full identity provider;
  • a password, passkey, session, or MFA system;
  • a fine-grained authorization engine;
  • the policy decision point for protected resources, including its own;
  • the owner of NetKingdom security controls or runtime secrets;
  • the full organization, HR, or directory authority;
  • a directory server;
  • a UI application;
  • an observer of production security events;
  • an actuation surface for containment, step-up, or authority reduction.

It provides the user-domain and identity-domain APIs, mapping records, catalog metadata, projections, events, evidence references, and local audit records that those surrounding systems can consume. Platform audit custody stays with audit-core. Optional UI in this repository is a surface over the same APIs, not a product identity.

Design Principles

  • headless first;
  • optional UI, not UI-driven;
  • standalone-friendly;
  • enterprise-integratable;
  • identity-provider agnostic;
  • authorization-engine agnostic — and never a substitute for one;
  • NetKingdom-integrated without hiding source-of-truth boundaries;
  • canon-aligned through explicit entity and relationship mappings;
  • catalog-driven customization;
  • explicit ownership, visibility, mutability, and sensitivity of attributes;
  • layered profiles instead of one global metadata blob;
  • deterministic and inspectable effective profile resolution;
  • evidence and lifecycle awareness for identity-domain changes, bounded by what an archive can actually prove;
  • fail closed on unreachable access-engine for protected mutations, with that stance published rather than implied by adapter code;
  • concrete user-domain focus with a possible future extraction path toward a generic profile engine.

Success Definition

user-engine succeeds when a repository or application can add robust user-domain and identity-domain capabilities with minimal coupling while keeping a clear path from a simple local setup to a governed multi-tenant, multi-application NetKingdom deployment.

It should also succeed as an implementation surface for identity-related canon intent: applications should be able to consume user, account, identity-link, actor, principal, subject, tenant, team, membership, profile, lifecycle, and evidence context through stable APIs and mappings without taking a direct dependency on the technical IAM, authorization, security, or audit substrate.

It succeeds as a PIP when access-engine can consume those facts as claims and reconstruct their application from the decision record, and as a PEP-shaped engine when every protected mutation it performs is bound to a decision or to a recorded stance, with a lifetime, and without a second decision point hiding in a cache, a hat, or a local adapter.