From 487012e9618a129f04aea295b8da0692c0462e68 Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 29 Jul 2026 23:14:09 +0200 Subject: [PATCH] Complete identity seams and email login --- WORK-RECORDS.md | 10 +-- ...ne-enterprise-identity-extension-points.md | 87 +++++++++++++++++++ sso-mfa/k8s/authelia/configmap.yaml | 5 +- ...tity-cutover-and-coulombcore-retirement.md | 8 +- ...user-engine-portal-platform-integration.md | 21 ++++- 5 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 docs/user-engine-enterprise-identity-extension-points.md diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index a8605d8..369d435 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -41,21 +41,21 @@ | task | NK-WP-0021-T03 | done | — | workplans/NK-WP-0021-activity-core-ops-sso-operators.md | | task | NK-WP-0021-T04 | done | — | workplans/NK-WP-0021-activity-core-ops-sso-operators.md | | task | NK-WP-0021-T05 | done | — | workplans/NK-WP-0021-activity-core-ops-sso-operators.md | -| task | NK-WP-0022-T01 | progress | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | +| task | NK-WP-0022-T01 | done | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T02 | done | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T03 | done | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T04 | done | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | -| task | NK-WP-0022-T05 | progress | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | +| task | NK-WP-0022-T05 | done | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T06 | progress | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T07 | wait | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T08 | wait | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0023-T01 | done | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | | task | NK-WP-0023-T02 | progress | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | -| task | NK-WP-0023-T03 | progress | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | +| task | NK-WP-0023-T03 | done | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | | task | NK-WP-0023-T04 | wait | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | | task | NK-WP-0023-T05 | progress | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | | task | NK-WP-0023-T06 | wait | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | -| task | NK-WP-0023-T07 | progress | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | -| task | NK-WP-0023-T08 | wait | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | +| task | NK-WP-0023-T07 | done | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | +| task | NK-WP-0023-T08 | done | — | workplans/NK-WP-0023-user-engine-portal-platform-integration.md | | intake | NK-IN-0001 | closed | blue | docs/intakes/activity-core-ops-sso-operators.md | | intake | NK-IN-0002 | closed | blue | docs/intakes/activity-core-ops-sso-operators.md | diff --git a/docs/user-engine-enterprise-identity-extension-points.md b/docs/user-engine-enterprise-identity-extension-points.md new file mode 100644 index 0000000..f70360d --- /dev/null +++ b/docs/user-engine-enterprise-identity-extension-points.md @@ -0,0 +1,87 @@ +# User-engine enterprise identity extension points + +## Purpose + +This document freezes the compatibility seams for later customer-owned +directories and identity providers. It does not enable enterprise federation; +`NK-WP-0011` remains demand-triggered. + +## Stable ownership boundaries + +| Concern | Authority | +| --- | --- | +| Authentication, MFA, federation protocol, upstream session | KeyCape or Keycloak | +| Customer directory users and groups | Customer directory | +| Platform user profile, tenant membership and lifecycle projection | user-engine | +| Fine-grained authorization decision | flex-auth | +| Credential and secret custody | NetKingdom/OpenBao | +| Audit evidence | owning service plus platform audit sink | + +User-engine must consume verified IAM Profile claims and provider-neutral +lifecycle events. It must not store enterprise passwords, MFA factors, SAML +assertions, refresh tokens, or directory administrator credentials. + +## Adapter seams + +### OIDC and SAML federation + +KeyCape/Keycloak terminates OIDC or SAML and emits the same IAM Profile +envelope used by local identities. Upstream issuer and subject remain +traceable in a private provenance claim while downstream applications trust +only the canonical platform issuer. + +### SCIM provisioning + +A future SCIM adapter translates customer create, update, suspend and delete +events into idempotent user-engine lifecycle commands. It uses an immutable +provider object identifier plus tenant identifier as its key. SCIM transport, +bearer credentials and retry queues stay outside the user-engine domain. + +### JIT provisioning + +JIT may create a pending platform projection after a successfully verified +login. It must not grant tenant-admin or platform authority solely from an +unmapped upstream claim. Privileged mappings require a pre-approved mapping +rule or an existing platform-side membership. + +### Directory group mapping + +Mappings are tenant-scoped, versioned and deny ambiguous multi-tenant +envelopes. Raw customer group names are never interpreted as platform roles +without an explicit mapping. Platform roles and `tenant:platform` remain +reserved. + +## Conflict and freshness rules + +- Immutable provider subject identifiers win over mutable email addresses. +- Email is a login/display alias, not the cross-system identity key. +- Customer-owned attributes are refreshed from the customer source; platform + memberships and application preferences remain platform-owned. +- Suspension or offboarding from an authoritative customer source fails + closed for new sessions and invalidates cached authorization projections. +- Duplicate email or provider-subject collisions enter reconciliation; they + are never merged automatically. +- Events carry provider version/time, correlation ID and idempotency key. + Older events cannot overwrite newer state. +- A stale connector cannot silently reactivate a suspended identity. + +## Offboarding and failure behavior + +Customer offboarding first blocks authentication, then suspends the +user-engine tenant account and emits revocation/audit events. Destructive +profile deletion is delayed by retention policy. Provider outage preserves +the last known projection but does not bypass authentication, MFA, suspension +or freshness limits. + +## Demand triggers + +Enterprise implementation begins only when a named tenant supplies: + +- protocol and provider choice; +- authoritative attribute/group contract; +- lifecycle and offboarding SLA; +- acceptable freshness window; +- tenant-specific role mappings; +- test tenant and rollback owner. + +Until then, local LLDAP plus KeyCape remains the managed identity path. diff --git a/sso-mfa/k8s/authelia/configmap.yaml b/sso-mfa/k8s/authelia/configmap.yaml index f0fe4a4..a6a1e29 100644 --- a/sso-mfa/k8s/authelia/configmap.yaml +++ b/sso-mfa/k8s/authelia/configmap.yaml @@ -50,7 +50,10 @@ data: base_dn: dc=netkingdom,dc=local username_attribute: uid additional_users_dn: ou=people - users_filter: "(&({username_attribute}={input})(objectClass=inetOrgPerson))" + # Accept either the stable uid or the user's mail address. Authelia's + # official LLDAP integration recommends this OR filter; the resolved + # identity still uses uid as its stable username. + users_filter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=inetOrgPerson))" additional_groups_dn: ou=groups groups_filter: "(member={dn})" group_name_attribute: cn diff --git a/workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md b/workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md index ca4819c..e50eaf4 100644 --- a/workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md +++ b/workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md @@ -38,7 +38,7 @@ before state migration or retirement begins. ```task id: NK-WP-0022-T01 -status: progress +status: done priority: high state_hub_task_id: "fe55a2c2-8613-4190-a0b9-07eff4a58146" ``` @@ -71,6 +71,12 @@ database fingerprints. CoulombCore exposes PostgreSQL logical backups but no matching LLDAP, Authelia, or privacyIDEA backup CronJobs; fresh protected source backups remain a hard gate. +2026-07-29 closure review: the subsequent backup, migration, dependency and +conformance tasks used this inventory successfully. Every identity state set +now has an authority, protected rollback source and verification method; the +remaining public names are tracked explicitly under T06 or their owning +non-identity cutovers. Inventory contract complete. + ## T02 - Prove recoverable backups before changing state ```task diff --git a/workplans/NK-WP-0023-user-engine-portal-platform-integration.md b/workplans/NK-WP-0023-user-engine-portal-platform-integration.md index 16af5e6..c8aac84 100644 --- a/workplans/NK-WP-0023-user-engine-portal-platform-integration.md +++ b/workplans/NK-WP-0023-user-engine-portal-platform-integration.md @@ -65,7 +65,7 @@ disposable subject. Reconciliation, compensation, and drift reporting remain. ```task id: NK-WP-0023-T03 -status: progress +status: done priority: high state_hub_task_id: "76289890-6e6e-45ea-90dc-d3d58eee8b62" ``` @@ -113,6 +113,17 @@ had no matching ingress. Commit `8e7229a` adds the namespace-and-pod-scoped `:8080` rule plus verifier coverage. After applying it, an in-pod discovery request from user-engine to KeyCape returns HTTP 200. +2026-07-29 complete: the live Binky browser flow verified the canonical +issuer/audience, Binky-only tenant/groups, tenant-admin role, AAL2 +password-plus-OTP assurance, and denial of platform/Coulomb administration. +Password and MFA handoffs remain on NetKingdom-owned surfaces. + +The live journey also exposed uid-only first-factor input. Authelia now uses +its documented LLDAP filter accepting either `uid` or `mail` while continuing +to resolve the stable uid identity. The updated ConfigMap passed server-side +validation and the restarted deployment is Ready without configuration +errors, so future users may enter either `bernd.worsch` or the full email. + ## T04 - Integrate authorization, email, audit, and events ```task @@ -209,7 +220,7 @@ Administration of both `tenant:platform` and `tenant:coulomb` was denied. ```task id: NK-WP-0023-T08 -status: wait +status: done priority: medium state_hub_task_id: "7ef8e1f5-1a0e-4a34-9535-708e3146ae72" ``` @@ -218,3 +229,9 @@ Document later adapters for customer IdPs/directories, SAML/OIDC federation, SCIM, JIT provisioning, directory group mapping, customer-owned offboarding, and conflict/freshness rules. Keep `NK-WP-0011` demand-triggered; this task defines compatibility seams, not enterprise implementation. + +2026-07-29: added +`docs/user-engine-enterprise-identity-extension-points.md`, covering OIDC/SAML +federation, SCIM, JIT, group mapping, provenance, source ownership, +conflict/freshness rules, offboarding, failure behavior, and demand triggers +without starting the demand-gated enterprise implementation.