generated from coulomb/repo-seed
Established architecture blueprint
This commit is contained in:
580
wiki/ArchitectureBlueprint.md
Normal file
580
wiki/ArchitectureBlueprint.md
Normal file
@@ -0,0 +1,580 @@
|
|||||||
|
# User Engine Architecture Blueprint
|
||||||
|
|
||||||
|
Status: initial architecture blueprint
|
||||||
|
Date: 2026-05-22
|
||||||
|
Related product docs: `../INTENT.md`, `ProductRequirementsDocument.md`
|
||||||
|
Primary platform references:
|
||||||
|
|
||||||
|
- `/home/worsch/net-kingdom/canon/standards/iam-profile_v0.2.md`
|
||||||
|
- `/home/worsch/net-kingdom/docs/platform-identity-security-architecture.md`
|
||||||
|
- `/home/worsch/net-kingdom/docs/responsibility-map.md`
|
||||||
|
- `/home/worsch/key-cape/SCOPE.md`
|
||||||
|
- `/home/worsch/flex-auth/docs/iam-profile-consumption.md`
|
||||||
|
|
||||||
|
## 1. Architecture Decision
|
||||||
|
|
||||||
|
`user-engine` should be implemented as the headless user-domain and profile
|
||||||
|
service in the NetKingdom repository landscape.
|
||||||
|
|
||||||
|
It owns user-domain records, account state, external identity links,
|
||||||
|
profile/preference values, application registrations, customization catalogs,
|
||||||
|
profile projections, and lifecycle/profile events.
|
||||||
|
|
||||||
|
It does not own authentication, MFA, password/passkey credentials, OIDC token
|
||||||
|
issuance, final resource authorization, runtime secret custody, or UI
|
||||||
|
experience. Those remain with the existing NetKingdom-aligned components:
|
||||||
|
|
||||||
|
- `key-cape` or Keycloak implements the NetKingdom IAM Profile.
|
||||||
|
- `local-identity` supports local/bootstrap development identity.
|
||||||
|
- `flex-auth` owns final authorization decisions and policy/audit envelopes.
|
||||||
|
- OpenBao and Railiance platform services own runtime secrets and durable
|
||||||
|
platform backing services.
|
||||||
|
- Future `user-account` and `user-manager` repos/apps own the UI surfaces.
|
||||||
|
|
||||||
|
The useful product boundary is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Identity provider tells user-engine who the actor is.
|
||||||
|
flex-auth tells user-engine what the actor may do.
|
||||||
|
user-engine manages user-domain facts and profile projections.
|
||||||
|
Applications and UIs consume user-engine through stable headless APIs.
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Fit In The NetKingdom Landscape
|
||||||
|
|
||||||
|
### 2.1 Identity Integration
|
||||||
|
|
||||||
|
Applications and user-engine should target the NetKingdom IAM Profile, not a
|
||||||
|
concrete provider. In production and platform mode, requests arrive with
|
||||||
|
tokens issued by either:
|
||||||
|
|
||||||
|
- key-cape lightweight mode, backed by Authelia/LLDAP/privacyIDEA where used;
|
||||||
|
- Keycloak expanded mode, used for enterprise federation, SAML brokering, or
|
||||||
|
complex realm/delegated-admin needs.
|
||||||
|
|
||||||
|
In local development, `local-identity` can issue local OIDC tokens that are
|
||||||
|
accepted only in non-production environments. Production user-engine
|
||||||
|
deployments must reject local or loopback issuers as required by the IAM
|
||||||
|
Profile.
|
||||||
|
|
||||||
|
Required token inputs for user-engine are the same provider-neutral facts used
|
||||||
|
by flex-auth:
|
||||||
|
|
||||||
|
- `iss`, `sub`, `aud`, `tenant`, `principal_type`
|
||||||
|
- `groups`, `roles`, `scope` or `scp`
|
||||||
|
- `assurance`
|
||||||
|
- optional human display/contact claims such as `preferred_username`, `email`,
|
||||||
|
and `name`
|
||||||
|
- optional agent/delegation claims for agentic use cases
|
||||||
|
|
||||||
|
`user-engine` must treat `iss + sub` as the stable identity link key. Email,
|
||||||
|
username, or display name must never be primary keys.
|
||||||
|
|
||||||
|
### 2.2 Authorization Integration
|
||||||
|
|
||||||
|
`user-engine` enforces access, but it should not become the policy decision
|
||||||
|
point. For every protected action, it should present a normalized request to
|
||||||
|
flex-auth and enforce the returned decision locally.
|
||||||
|
|
||||||
|
Protected resource examples:
|
||||||
|
|
||||||
|
| Resource | Example 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` |
|
||||||
|
| `user-engine:application` | `register`, `update`, `deactivate` |
|
||||||
|
| `user-engine:catalog` | `register`, `activate`, `deprecate`, `migrate` |
|
||||||
|
| `user-engine:audit` | `read` |
|
||||||
|
|
||||||
|
The authorization flow should be:
|
||||||
|
|
||||||
|
1. Validate or receive a validated IAM Profile token.
|
||||||
|
2. Normalize identity claims into an actor envelope.
|
||||||
|
3. Resolve the actor's linked user where needed.
|
||||||
|
4. Call flex-auth with actor, tenant, resource, action, scope, assurance, and
|
||||||
|
contextual attributes.
|
||||||
|
5. Enforce deny/allow/obligations locally.
|
||||||
|
6. Apply attribute-level projection filtering for visibility, mutability, and
|
||||||
|
sensitivity.
|
||||||
|
7. Emit audit and domain events.
|
||||||
|
|
||||||
|
Memberships and profile facts can be authorization-relevant inputs, but they
|
||||||
|
are not authorization decisions. `user-engine` may export subject, tenant,
|
||||||
|
team, and membership facts to flex-auth subject manifests or resolver adapters;
|
||||||
|
flex-auth remains the decision boundary.
|
||||||
|
|
||||||
|
### 2.3 Deployment And Operations Integration
|
||||||
|
|
||||||
|
`user-engine` can run in three modes:
|
||||||
|
|
||||||
|
| Mode | Purpose | Dependencies |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Standalone | Small app, prototype, local dev, single service | Local DB, local/external OIDC, optional in-process policy adapter |
|
||||||
|
| Platform | Shared service for multiple NetKingdom applications | IAM Profile issuer, flex-auth, PostgreSQL, event/audit sink, OpenBao-backed secrets |
|
||||||
|
| Enterprise | Federated, provisioned, multi-tenant landscape | Keycloak expanded mode, SCIM/import adapters, stronger audit retention, directory/group resolvers |
|
||||||
|
|
||||||
|
Production platform mode should use Railiance-provided backing services:
|
||||||
|
|
||||||
|
- PostgreSQL for canonical user-engine state.
|
||||||
|
- OpenBao for database credentials, API client secrets, signing keys, and
|
||||||
|
webhook secrets.
|
||||||
|
- Railiance platform event or message services for outbox/event delivery.
|
||||||
|
- Cluster ingress, network policy, TLS, and observability from the Railiance
|
||||||
|
stack.
|
||||||
|
|
||||||
|
NetKingdom should meta-orchestrate the trust and responsibility boundaries.
|
||||||
|
Railiance should execute deployment mechanics. If `user-engine` becomes a
|
||||||
|
shared platform service that holds user, account, catalog, and membership
|
||||||
|
resources across the landscape, NetKingdom's responsibility map should be
|
||||||
|
updated there, not in `user-engine` intent, to preserve self-coherent repo
|
||||||
|
intent.
|
||||||
|
|
||||||
|
## 3. Responsibility Boundaries
|
||||||
|
|
||||||
|
| Concern | Owner | user-engine role |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| OIDC discovery, login, token issuance | key-cape, Keycloak, local-identity in dev | Consume tokens and identity facts |
|
||||||
|
| Passwords, MFA, passkeys, sessions | key-cape/Keycloak/MFA stack | No storage or credential lifecycle |
|
||||||
|
| External identity links | user-engine | Map `iss + sub` identities to local user records |
|
||||||
|
| Canonical user/account/profile data | user-engine | Source of truth |
|
||||||
|
| Application profile catalogs | user-engine | Source of truth and validation authority |
|
||||||
|
| Groups/roles in tokens | IAM provider, mapped to IAM Profile | Consume as identity facts; do not make final decisions |
|
||||||
|
| Membership/domain facts | user-engine, optionally synced with IAM/flex-auth | Manage user-domain relationships; export facts where useful |
|
||||||
|
| Final authorization | flex-auth and PDP adapters | Ask, enforce, audit obligations |
|
||||||
|
| Runtime secrets | OpenBao/Railiance platform | Consume scoped secrets only |
|
||||||
|
| Self-service UI | future `user-account` | Provide APIs/projections |
|
||||||
|
| Admin UI | future `user-manager` | Provide APIs/projections |
|
||||||
|
|
||||||
|
## 4. Conceptual Component Model
|
||||||
|
|
||||||
|
```text
|
||||||
|
+---------------------+
|
||||||
|
| key-cape / Keycloak |
|
||||||
|
| IAM Profile issuer |
|
||||||
|
+----------+----------+
|
||||||
|
|
|
||||||
|
| OIDC token / normalized claims
|
||||||
|
v
|
||||||
|
+-------------------------+--------------------------+
|
||||||
|
| user-engine |
|
||||||
|
| |
|
||||||
|
| API adapters |
|
||||||
|
| - REST/HTTP API |
|
||||||
|
| - internal service API |
|
||||||
|
| - future SDKs |
|
||||||
|
| |
|
||||||
|
| Domain core |
|
||||||
|
| - users and accounts |
|
||||||
|
| - identity links |
|
||||||
|
| - tenants, applications, teams, memberships |
|
||||||
|
| - global, tenant, app, and membership profiles |
|
||||||
|
| - preference values |
|
||||||
|
| |
|
||||||
|
| Catalog and projection engine |
|
||||||
|
| - catalog registry |
|
||||||
|
| - attribute governance |
|
||||||
|
| - effective profile resolver |
|
||||||
|
| - projection filters |
|
||||||
|
| |
|
||||||
|
| Integration layer |
|
||||||
|
| - flex-auth check client |
|
||||||
|
| - IAM Profile claim adapter |
|
||||||
|
| - event outbox |
|
||||||
|
| - audit writer |
|
||||||
|
+------------+--------------------------+------------+
|
||||||
|
| |
|
||||||
|
| policy checks | state/events/audit
|
||||||
|
v v
|
||||||
|
+-----------+ +----------------------+
|
||||||
|
| flex-auth | | PostgreSQL / outbox |
|
||||||
|
+-----------+ | event/audit sinks |
|
||||||
|
+----------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
The domain core should be usable without HTTP. API adapters should call domain
|
||||||
|
services rather than placing lifecycle or profile resolution logic in route
|
||||||
|
handlers.
|
||||||
|
|
||||||
|
## 5. Domain Model Blueprint
|
||||||
|
|
||||||
|
### 5.1 Stable Identifiers
|
||||||
|
|
||||||
|
Use stable internal identifiers and explicit external links.
|
||||||
|
|
||||||
|
| Entity | Identifier rule |
|
||||||
|
| --- | --- |
|
||||||
|
| User | Internal `user_id`, opaque and stable |
|
||||||
|
| External identity | Unique `(issuer, subject)` plus provider metadata |
|
||||||
|
| Tenant | NetKingdom-aligned identifiers such as `tenant:platform`, `tenant:coulomb`, `tenant:customer:<id>` |
|
||||||
|
| Application | Stable application id, preferably namespaced |
|
||||||
|
| Catalog | `(application_id, namespace, catalog_id, version)` |
|
||||||
|
| Attribute | Catalog-qualified key, not a global loose string |
|
||||||
|
| Membership | `(user_id, scope_type, scope_id, role_or_relation)` where applicable |
|
||||||
|
|
||||||
|
### 5.2 Core Entities
|
||||||
|
|
||||||
|
Minimum persistent entities:
|
||||||
|
|
||||||
|
- `User`: stable person/human-representing subject.
|
||||||
|
- `Account`: lifecycle state and platform/application relationship.
|
||||||
|
- `ExternalIdentity`: identity provider link, keyed by `iss + sub`.
|
||||||
|
- `Tenant`: platform or tenant plane scope.
|
||||||
|
- `Application`: profile-consuming application registration.
|
||||||
|
- `Team` or `GroupScope`: optional team/project scope for membership profiles.
|
||||||
|
- `Membership`: user relationship to tenant, application, team, project, or
|
||||||
|
other scope.
|
||||||
|
- `ProfileValue`: scoped profile/preference values.
|
||||||
|
- `Catalog`: application-owned customization descriptor.
|
||||||
|
- `AttributeDefinition`: catalog-defined attribute metadata.
|
||||||
|
- `ProjectionDefinition`: reusable projection rules.
|
||||||
|
- `AuditRecord`: durable user-engine audit trail.
|
||||||
|
- `OutboxEvent`: reliable integration event queue.
|
||||||
|
|
||||||
|
### 5.3 Account Lifecycle
|
||||||
|
|
||||||
|
Initial account states should align with the PRD while staying compatible with
|
||||||
|
external provisioning:
|
||||||
|
|
||||||
|
- `invited`
|
||||||
|
- `active`
|
||||||
|
- `disabled`
|
||||||
|
- `suspended`
|
||||||
|
- `deletion_pending`
|
||||||
|
- `deleted`
|
||||||
|
|
||||||
|
Account records should separately track management mode:
|
||||||
|
|
||||||
|
- `local`
|
||||||
|
- `externally_provisioned`
|
||||||
|
- `federated`
|
||||||
|
- `service_managed`
|
||||||
|
|
||||||
|
State transitions must be explicit, audited, and authorized. Deletion should
|
||||||
|
default to a staged `deletion_pending` flow so downstream projections and
|
||||||
|
events can settle before irreversible erasure.
|
||||||
|
|
||||||
|
## 6. Catalog And Profile Architecture
|
||||||
|
|
||||||
|
### 6.1 Catalog Descriptor
|
||||||
|
|
||||||
|
The first catalog descriptor should be JSON/YAML with JSON Schema-compatible
|
||||||
|
validation plus user-engine governance metadata.
|
||||||
|
|
||||||
|
Required catalog-level fields:
|
||||||
|
|
||||||
|
- namespace
|
||||||
|
- catalog id
|
||||||
|
- semantic version
|
||||||
|
- owning application id
|
||||||
|
- lifecycle state: `draft`, `active`, `deprecated`, `retired`
|
||||||
|
- allowed profile scopes
|
||||||
|
- projection types
|
||||||
|
- migration metadata
|
||||||
|
|
||||||
|
Required attribute-level fields:
|
||||||
|
|
||||||
|
- key
|
||||||
|
- value type and validation schema
|
||||||
|
- defaulting behavior
|
||||||
|
- allowed scopes
|
||||||
|
- owner
|
||||||
|
- visibility
|
||||||
|
- mutability
|
||||||
|
- sensitivity
|
||||||
|
- inheritance/override rule
|
||||||
|
- projection eligibility
|
||||||
|
- UI hints for future generated forms
|
||||||
|
|
||||||
|
Catalog activation should validate:
|
||||||
|
|
||||||
|
- namespace ownership
|
||||||
|
- attribute key uniqueness within the catalog version
|
||||||
|
- valid scope references
|
||||||
|
- supported validation schemas
|
||||||
|
- no incompatible sensitivity downgrade from previous active versions
|
||||||
|
- migration requirement when changing type, scope, or sensitivity
|
||||||
|
|
||||||
|
### 6.2 Layered Profile Scopes
|
||||||
|
|
||||||
|
Initial layers:
|
||||||
|
|
||||||
|
1. Global user profile
|
||||||
|
2. Tenant user profile
|
||||||
|
3. Application user profile
|
||||||
|
4. Membership/team profile
|
||||||
|
5. Admin override, only for attributes that explicitly allow it
|
||||||
|
|
||||||
|
The effective profile resolver should be deterministic and inspectable. A
|
||||||
|
projection response should be able to explain which layer supplied a value and
|
||||||
|
which values were hidden by visibility/sensitivity policy.
|
||||||
|
|
||||||
|
Suggested default precedence:
|
||||||
|
|
||||||
|
```text
|
||||||
|
catalog default
|
||||||
|
< global value
|
||||||
|
< tenant value
|
||||||
|
< application value
|
||||||
|
< membership/team value
|
||||||
|
< allowed admin override
|
||||||
|
```
|
||||||
|
|
||||||
|
Precedence should be configurable only through catalog-defined override rules,
|
||||||
|
not per-request ad hoc logic.
|
||||||
|
|
||||||
|
### 6.3 Projection Types
|
||||||
|
|
||||||
|
Minimum projection types:
|
||||||
|
|
||||||
|
- `self_service`: fields the current user may see or change.
|
||||||
|
- `admin`: fields visible to a scope administrator.
|
||||||
|
- `application_runtime`: fields a registered application may consume.
|
||||||
|
- `oidc_claims`: fields safe to map into OIDC-style profile claims.
|
||||||
|
- `audit`: redacted change summary for audit and diagnostics.
|
||||||
|
- `agent_context`: policy-filtered profile/preferences for delegated or
|
||||||
|
autonomous agent use.
|
||||||
|
|
||||||
|
Projection defaults should be deny-by-default for sensitive attributes.
|
||||||
|
Sensitivity and mutability should be enforced in the projection layer even
|
||||||
|
after flex-auth authorizes the broader action.
|
||||||
|
|
||||||
|
## 7. API Surface Blueprint
|
||||||
|
|
||||||
|
The first API should be headless and UI-neutral.
|
||||||
|
|
||||||
|
Suggested high-level resources:
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /health
|
||||||
|
GET /ready
|
||||||
|
|
||||||
|
GET /me
|
||||||
|
PATCH /me/profile
|
||||||
|
GET /me/applications/{application_id}/profile
|
||||||
|
PATCH /me/applications/{application_id}/profile
|
||||||
|
GET /me/identities
|
||||||
|
|
||||||
|
GET /users/{user_id}
|
||||||
|
PATCH /users/{user_id}
|
||||||
|
POST /users/{user_id}/lifecycle/{transition}
|
||||||
|
|
||||||
|
GET /tenants/{tenant_id}/users
|
||||||
|
GET /tenants/{tenant_id}/memberships
|
||||||
|
POST /tenants/{tenant_id}/memberships
|
||||||
|
DELETE /tenants/{tenant_id}/memberships/{membership_id}
|
||||||
|
|
||||||
|
GET /applications
|
||||||
|
POST /applications
|
||||||
|
GET /applications/{application_id}
|
||||||
|
PATCH /applications/{application_id}
|
||||||
|
|
||||||
|
GET /applications/{application_id}/catalogs
|
||||||
|
POST /applications/{application_id}/catalogs
|
||||||
|
POST /applications/{application_id}/catalogs/{catalog_id}/activate
|
||||||
|
POST /applications/{application_id}/catalogs/{catalog_id}/deprecate
|
||||||
|
|
||||||
|
GET /profiles/effective
|
||||||
|
GET /projections/{projection_type}
|
||||||
|
|
||||||
|
GET /audit
|
||||||
|
```
|
||||||
|
|
||||||
|
API design rules:
|
||||||
|
|
||||||
|
- Every mutating endpoint requires an authenticated IAM Profile actor.
|
||||||
|
- Every scoped endpoint must carry an explicit tenant/application/team context.
|
||||||
|
- Admin endpoints are scope-admin endpoints, not platform-root shortcuts.
|
||||||
|
- The `me` API uses the linked current actor, not a client-supplied user id.
|
||||||
|
- Applications may register catalogs only for namespaces they own.
|
||||||
|
- Attribute updates must validate against the active catalog version.
|
||||||
|
- Projection responses must not leak hidden sensitive values in validation
|
||||||
|
errors, explanations, or audit summaries.
|
||||||
|
|
||||||
|
## 8. Event And Audit Blueprint
|
||||||
|
|
||||||
|
`user-engine` should implement a transactional outbox so profile changes,
|
||||||
|
membership changes, catalog changes, and lifecycle changes cannot commit
|
||||||
|
without a corresponding event record.
|
||||||
|
|
||||||
|
Initial domain events:
|
||||||
|
|
||||||
|
- `user.created`
|
||||||
|
- `user.updated`
|
||||||
|
- `user.activated`
|
||||||
|
- `user.disabled`
|
||||||
|
- `user.suspended`
|
||||||
|
- `user.deletion_requested`
|
||||||
|
- `user.deleted`
|
||||||
|
- `identity.linked`
|
||||||
|
- `identity.unlinked`
|
||||||
|
- `profile.updated`
|
||||||
|
- `membership.changed`
|
||||||
|
- `application.registered`
|
||||||
|
- `catalog.registered`
|
||||||
|
- `catalog.activated`
|
||||||
|
- `catalog.deprecated`
|
||||||
|
- `projection.changed`
|
||||||
|
|
||||||
|
Audit records should include:
|
||||||
|
|
||||||
|
- actor identity envelope
|
||||||
|
- subject user or resource
|
||||||
|
- action
|
||||||
|
- tenant/application/scope
|
||||||
|
- authorization decision id or correlation id from flex-auth where available
|
||||||
|
- high-level change summary
|
||||||
|
- sensitivity-aware redaction
|
||||||
|
- timestamp and source client
|
||||||
|
|
||||||
|
Audit is part of user-engine's own accountability, but platform-wide durable
|
||||||
|
audit retention should integrate with the Railiance/NetKingdom audit sink when
|
||||||
|
available.
|
||||||
|
|
||||||
|
## 9. Standalone To Platform Progression
|
||||||
|
|
||||||
|
### 9.1 Standalone Setup
|
||||||
|
|
||||||
|
Standalone mode should prove reuse without a full platform:
|
||||||
|
|
||||||
|
- local or external OIDC issuer;
|
||||||
|
- SQLite or local PostgreSQL;
|
||||||
|
- local config file for application registration;
|
||||||
|
- in-process authorization adapter for development only, or a small allowlist
|
||||||
|
policy with clear production warnings;
|
||||||
|
- same catalog and profile APIs as platform mode.
|
||||||
|
|
||||||
|
Recommended decision: do not implement passwords or MFA in standalone mode.
|
||||||
|
Use `local-identity` for local OIDC or an external OIDC provider. This keeps
|
||||||
|
the standalone path useful without starting identity-provider creep.
|
||||||
|
|
||||||
|
### 9.2 NetKingdom Platform Setup
|
||||||
|
|
||||||
|
Platform mode should be the normal integrated setup:
|
||||||
|
|
||||||
|
- key-cape or Keycloak issues IAM Profile tokens.
|
||||||
|
- flex-auth authorizes user-engine actions.
|
||||||
|
- PostgreSQL stores canonical state.
|
||||||
|
- OpenBao provides runtime secrets.
|
||||||
|
- event/audit outbox drains to platform services.
|
||||||
|
- app and tenant identifiers follow NetKingdom tenant semantics.
|
||||||
|
|
||||||
|
### 9.3 Enterprise Setup
|
||||||
|
|
||||||
|
Enterprise mode adds:
|
||||||
|
|
||||||
|
- Keycloak expanded mode for inbound enterprise federation and SAML/Entra/AD
|
||||||
|
brokering;
|
||||||
|
- SCIM-aligned import/provisioning adapters;
|
||||||
|
- directory/group resolver integration for group overage and freshness;
|
||||||
|
- stronger audit retention, export, and review workflows;
|
||||||
|
- tenant and admin delegation models.
|
||||||
|
|
||||||
|
SCIM should initially be a compatibility target and adapter boundary, not the
|
||||||
|
MVP's source of truth.
|
||||||
|
|
||||||
|
## 10. Implementation Roadmap
|
||||||
|
|
||||||
|
### Phase 0 - Contracts And Skeleton
|
||||||
|
|
||||||
|
- Add `SCOPE.md` for user-engine.
|
||||||
|
- Add API and catalog descriptor draft specs.
|
||||||
|
- Define resource/action vocabulary for flex-auth.
|
||||||
|
- Define user-engine event names and audit schema.
|
||||||
|
- Choose implementation stack and repository layout.
|
||||||
|
|
||||||
|
### Phase 1 - Headless Core MVP
|
||||||
|
|
||||||
|
- Implement domain core for users, accounts, identity links, applications,
|
||||||
|
catalogs, profile values, and effective profile resolution.
|
||||||
|
- Implement persistence with migration support.
|
||||||
|
- Implement REST API and health/readiness endpoints.
|
||||||
|
- Implement transactional audit and outbox tables.
|
||||||
|
- Add SDK/client generation or a minimal typed client.
|
||||||
|
|
||||||
|
### Phase 2 - NetKingdom Integration
|
||||||
|
|
||||||
|
- Add IAM Profile claim adapter and production issuer validation.
|
||||||
|
- Add flex-auth check client and protected resource/action manifests.
|
||||||
|
- Add OpenBao/Railiance-ready secret configuration.
|
||||||
|
- Add event sink adapter for the platform event path.
|
||||||
|
- Add conformance tests with local-identity and IAM Profile fixtures.
|
||||||
|
|
||||||
|
### Phase 3 - Catalog And Projection Hardening
|
||||||
|
|
||||||
|
- Add catalog versioning and activation/deprecation rules.
|
||||||
|
- Add migration checks for catalog changes.
|
||||||
|
- Add projection definitions for self-service, admin, application runtime,
|
||||||
|
OIDC claims, audit, and agent context.
|
||||||
|
- Add attribute-level sensitivity, mutability, visibility, and explanation
|
||||||
|
tests.
|
||||||
|
|
||||||
|
### Phase 4 - Enterprise Adapters
|
||||||
|
|
||||||
|
- Add SCIM-aligned inbound provisioning adapter.
|
||||||
|
- Add Keycloak/expanded-mode provisioning integration where needed.
|
||||||
|
- Add directory/group resolver integration for freshness/overage handling.
|
||||||
|
- Add export/import and tenant onboarding diagnostics.
|
||||||
|
|
||||||
|
### Phase 5 - UI Consumers
|
||||||
|
|
||||||
|
- Build `user-account` as a self-service UI over the same APIs.
|
||||||
|
- Build `user-manager` as a scoped admin UI over the same APIs.
|
||||||
|
- Keep UI-specific form rendering downstream of catalog/projection metadata.
|
||||||
|
|
||||||
|
## 11. Testing And Conformance
|
||||||
|
|
||||||
|
Minimum test suites:
|
||||||
|
|
||||||
|
- domain model unit tests;
|
||||||
|
- catalog descriptor validation tests;
|
||||||
|
- profile resolution precedence tests;
|
||||||
|
- projection redaction and mutability tests;
|
||||||
|
- IAM Profile token acceptance/rejection tests;
|
||||||
|
- flex-auth allow/deny/obligation integration tests;
|
||||||
|
- tenant isolation tests;
|
||||||
|
- account lifecycle transition tests;
|
||||||
|
- audit/outbox atomicity tests;
|
||||||
|
- local standalone smoke test;
|
||||||
|
- platform-mode smoke test with local-identity or fixture issuer.
|
||||||
|
|
||||||
|
Production-readiness checks should include:
|
||||||
|
|
||||||
|
- rejects local-development issuers in production;
|
||||||
|
- validates issuer, audience, expiry, not-before, signature, and algorithm
|
||||||
|
either directly or through a trusted upstream gateway;
|
||||||
|
- enforces tenant context on every scoped request;
|
||||||
|
- denies profile access when flex-auth denies;
|
||||||
|
- redacts sensitive attributes in all non-eligible projections;
|
||||||
|
- persists audit records for administrative and lifecycle changes;
|
||||||
|
- drains outbox without losing committed changes.
|
||||||
|
|
||||||
|
## 12. Open Decisions
|
||||||
|
|
||||||
|
| Decision | Recommendation |
|
||||||
|
| --- | --- |
|
||||||
|
| Implementation language/framework | Choose after first API/design spike; keep domain core independent from HTTP |
|
||||||
|
| Standalone authentication | Use `local-identity` or external OIDC; do not implement passwords/MFA |
|
||||||
|
| First database | PostgreSQL for platform, optional SQLite for local standalone |
|
||||||
|
| Catalog descriptor format | JSON/YAML using JSON Schema-compatible validation plus user-engine governance metadata |
|
||||||
|
| Membership source of truth | user-engine owns user-domain memberships; IAM/flex-auth consume or mirror only what they need |
|
||||||
|
| SCIM timing | Adapter boundary after MVP, not initial source of truth |
|
||||||
|
| NetKingdom responsibility-map update | Do in net-kingdom if/when user-engine becomes a shared platform service |
|
||||||
|
|
||||||
|
## 13. First Implementation Slice
|
||||||
|
|
||||||
|
The smallest useful slice should be:
|
||||||
|
|
||||||
|
1. Authenticate a request with a local IAM Profile fixture or local-identity.
|
||||||
|
2. Link `iss + sub` to a `user_id`.
|
||||||
|
3. Register one application.
|
||||||
|
4. Register one catalog with a few profile/preference attributes.
|
||||||
|
5. Store global and application profile values.
|
||||||
|
6. Resolve an effective application profile projection.
|
||||||
|
7. Authorize the read/update path through a pluggable flex-auth interface,
|
||||||
|
using a local test adapter until flex-auth is wired.
|
||||||
|
8. Emit audit and outbox events for every mutation.
|
||||||
|
|
||||||
|
This slice proves the product thesis without duplicating identity provider,
|
||||||
|
MFA, authorization engine, UI, or deployment-platform responsibilities.
|
||||||
Reference in New Issue
Block a user