Files
net-kingdom/workplans/NK-WP-0002-local-identity.md
tegwick 8929bf65bc feat(sso-mfa): T03 PostgreSQL manifests (NK-WP-0001-T03)
CloudNativePG Cluster CR (net-kingdom-pg, PostgreSQL 16) with two
application databases: keycloak_db (owner: keycloak) and privacyidea_db
(owner: privacyidea). Passwords managed continuously via managed.roles.
WAL archiving section stubbed and commented; activate when object storage
is available. ScheduledBackup CR included (daily 02:00 UTC, 7d retention).

Also: sync workplan status for T01 (Phase 0a done), T02 (manifests done),
T03 (manifests done, restore drill pending); close NK-WP-0002.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 09:22:13 +01:00

8.4 KiB
Raw Blame History

id, type, title, domain, status, owner, topic_slug, state_hub_workstream_id, created, updated
id type title domain status owner topic_slug state_hub_workstream_id created updated
NK-WP-0002 workplan Local Identity — Bootstrap User Store & Minimal OIDC netkingdom completed worsch netkingdom 7c9021b1-319c-4b4a-a8be-0642239a1893 2026-03-01 2026-03-05

Local Identity — Bootstrap User Store & Minimal OIDC

Summary

Implement a zero-dependency, file-based user management capability for net-kingdom environments that do not yet have (or do not need) a running Keycloak instance. Local Identity derives the primary user from the Linux identity, auto-generates test users, provides a sandbox→production mapping mechanism, and (in Stage 3) a minimal native OIDC provider for dev/test use.

See docs/LocalIdentity.md for the full capability description, design principles, user schema, and risk mitigations.

Context

Resolved from Decision D5 (2026-03-01, Tegwick). The decision chose to implement Local Identity in-repo (not as a separate repository) in staged workplan form, with a clear scope boundary and explicit out-of-scope limitations. The minimal OIDC provider is to be implemented natively to avoid heavy dependencies, keeping the bootstrap footprint minimal.

Relationship to NK-WP-0001

Local Identity is complementary to the SSO & MFA Platform (NK-WP-0001). It is not a blocking dependency: the SSO platform core deployment (T01T08) does not require Local Identity to be complete. However:

  • NK-WP-0001 T07 (user management) references Local Identity for the pre-Keycloak bootstrap use case.
  • Stage 2 of this workplan produces Keycloak-compatible user exports, which feed the NK-WP-0001 T06 realm configuration.
  • Once NK-WP-0001 is fully operational, Local Identity is no longer needed for new instances and should be explicitly migrated away from.

Architecture

~/.local-identity/
├── config.yaml          # operator email, optional overrides
└── users/
    ├── <user>.yaml      # primary user (derived from Linux identity)
    ├── <user>1.yaml     # test user 1 (generated)
    └── <user>2.yaml     # test user 2 (generated)

local-identity CLI
├── init                 # derive + generate users
├── list / show          # read operations
├── export               # Keycloak-compatible JSON
├── security-check       # permissions validation
└── serve                # Stage 3: minimal OIDC server (localhost only)

Secret injection: Local Identity does not use Vault or K8s Secrets — it operates entirely at the filesystem level, pre-cluster. This is by design.

Tasks

T01 — Stage 1: Core file store

id: NK-WP-0002-T01
state_hub_task_id: 656652dd-05af-4fa4-95b2-17ce029ac7bd
status: done
priority: high
commit: 4491bea

Define YAML user schema (schema_version, username, fullname, email, environment, generated, source_user, production_identity).

Implement:

  • local-identity init — read $USER, /etc/passwd GECOS, prompt for email if not in config; write primary user file; auto-generate two test users with N / +testN suffixes
  • local-identity list — tabular output of all users in the store
  • local-identity show <user> — pretty-print user YAML

File store:

  • Create ~/.local-identity/ with mode 700
  • Create user files with mode 600
  • Refuse to overwrite existing store without --force

Unit tests:

  • GECOS name parsing edge cases (missing fields, non-ASCII)
  • Test user derivation: username suffix, email +testN insertion
  • Idempotency: init twice with --force produces identical output

Done when: init/list/show work; files created with correct permissions; unit tests passing.


T02 — Stage 2: Bootstrap integration

id: NK-WP-0002-T02
state_hub_task_id: 5ea6e68d-7ebe-4ea7-b92e-61aac17ff04c
status: done
priority: high
commit: dad8365

Extend user schema with optional production_identity block (username, realm). Test users carry environment: local and generated: true.

Implement:

  • local-identity export <user> — emit Keycloak-compatible user JSON (Keycloak Admin REST API representation); apply production_identity mapping if present
  • Schema validation: run against Keycloak user JSON schema on export; fail with a clear diff if schema has drifted

Bootstrap tooling integration:

  • local-identity export --all produces a bulk import file compatible with Keycloak's partial import endpoint
  • Document the import procedure in docs/LocalIdentity.md

Isolation guarantee:

  • Production connectors (Keycloak, future services) must reject users with environment: local — document the configuration required on the Keycloak side (e.g. custom attribute check in authentication flow)

Done when: export produces valid Keycloak JSON; schema validation catches drift; bulk import procedure documented and tested against a local Keycloak dev instance.


T03 — Stage 3: Minimal native OIDC provider

id: NK-WP-0002-T03
state_hub_task_id: eb09d287-8e08-4c88-8bd1-6f0501ef5fc8
status: done
priority: medium
commit: d35823d

Implement local-identity serve — a minimal OIDC Authorization Code flow server, implemented natively (no heavy OIDC library dependencies). Target: a single binary or script that can be invoked without installing an application framework.

Endpoints required:

  • GET /.well-known/openid-configuration — OIDC discovery document
  • GET /auth — authorization endpoint (redirects with code)
  • POST /token — token endpoint (exchanges code for JWT)
  • GET /userinfo — userinfo endpoint

Token requirements:

  • JWT signed with a local key (generated on first serve invocation; stored in ~/.local-identity/keys/)
  • Claims: sub, iss: local-identity, aud, exp, iat, email, name, preferred_username
  • iss: local-identity is intentionally non-routable; configure production Keycloak to reject tokens with this issuer

TLS:

  • Auto-generate a self-signed certificate on first run; store in ~/.local-identity/tls/
  • Bind to 127.0.0.1 only; document that external binding is explicitly unsupported

Scope:

  • Supports openid, profile, email scopes
  • No refresh tokens (stateless; re-auth required after expiry)
  • No client secret validation (dev-mode only; all registered clients are trusted)

Done when: a standard OIDC client library can authenticate against local-identity serve; discovery, auth, token, and userinfo endpoints pass an OIDC conformance smoke test; server refuses to bind to 0.0.0.0.


T04 — Stage 4: Security hardening

id: NK-WP-0002-T04
state_hub_task_id: 936de7fa-dfb4-48a2-804f-6b9bd7271a05
status: done
priority: medium
commit: e7bafd6

Permission enforcement:

  • On every startup, validate ~/.local-identity/ mode 700 and all user files mode 600; fail loudly (exit 1 + clear error) if violated
  • local-identity security-check command: explicit security audit with per-check output (pass / warn / fail)

Audit log:

  • Append-only log at ~/.local-identity/audit.log; mode 600
  • Log entries: timestamp, command, username, outcome
  • For serve: log every authentication event (auth request, token issued, userinfo call)

Token hardening (for Stage 3 OIDC server):

  • Configurable token TTL (default: 1 hour)
  • Token revocation list stored in ~/.local-identity/revoked.json
  • local-identity revoke-token <jti> command

Documentation:

  • Optional SELinux/AppArmor label guidance added to docs/LocalIdentity.md
  • Security model section: threat model, assumptions, explicit non-guarantees

Done when: security-check passes cleanly on a correct install; audit log records all auth events; startup fails on incorrect permissions; token expiry and revocation functional.


Deliverables Checklist

  • ~/.local-identity/ store initialised from Linux identity; test users generated
  • local-identity list / show / export working; Keycloak export validated
  • Minimal OIDC server passes conformance smoke test; binds localhost only
  • Filesystem permissions enforced on startup; security-check passes
  • Audit log recording all auth events
  • docs/LocalIdentity.md complete with import procedure and security model
  • NK-WP-0001 T07 migration procedure documented (Local Identity → Keycloak)

Open Questions

None at this stage. All decisions resolved. Stage 3 language selection (implementation language for the OIDC server) is a task-level detail to be determined in T03.