Commit Graph

26 Commits

Author SHA1 Message Date
df09dd42f4 feat(close): mark NK-WP-0003 T08/T08a/T08b done — acceptance tests passing
All 3 KeyCape test packages pass (migration, negative, profile).
DNS resolves for all 4 subdomains; Go 1.22.10 available at ~/go/bin/go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 11:52:11 +01:00
eebaa4fc81 chore(workplan): add T08a (DNS records) and T08b (Go install) tasks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 00:40:40 +00:00
d1fd73e7ed chore(workplan): NK-WP-0003-T08 blocked — DNS records + Go missing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 00:36:56 +00:00
c8c6efbc55 chore(workplan): NK-WP-0003-T07 done — KeyCape running
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 00:32:45 +00:00
d0629e7f20 chore(workplan): NK-WP-0003-T07 blocked — awaiting GHCR image from key-cape
Deployment applied; pod in ImagePullBackOff. Secrets already correct.
Capability request 0e0aefd7 filed; key-cape must publish ghcr.io image.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 22:24:32 +00:00
f2f07871eb fix(sso-mfa): commit T02–T06 fixes and workplan status updates
- authelia: users_filter uid→{username_attribute}, OIDC client secret
  moved from env var to inline bcrypt hash in configmap (4.38 limitation)
- authelia: remove unsupported CLIENTS_0_SECRET_FILE env var
- lldap: drop runAsNonRoot/runAsUser (image init requires root)
- verify-t02: keycloak→keycape NetworkPolicy check rename
- workplan: T02/T03/T05/T06 marked done with notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 20:25:03 +00:00
a60f4fc834 chore(workplan): NK-WP-0003-T04 done — privacyIDEA deployed and bootstrapped
Pod Running with correct image and config. enckey, audit keys, pi-admin,
trigger-admin all created via agent bootstrap (NK-WP-0005).
Remaining: TLS cert + trigger-admin policy via WebUI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 12:13:52 +00:00
bcae4bc6dd fix(workplans): portable key-cape path in NK-WP-0003-T08; add /creds-init skill
- NK-WP-0003 T08: replace hardcoded /home/worsch/key-cape with
  $(git rev-parse --show-toplevel)/../key-cape so acceptance tests
  run correctly on any machine
- NK-WP-0005 T04: create .claude/commands/creds-init.md — the
  autonomous credential bootstrap skill (reads creds-state.yaml,
  resumes from current phase, honours emergency bundle gate)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 10:01:14 +01:00
0670e17b42 chore(workplans): revise workplans post NK-WP-0005
NK-WP-0005: mark all tasks done, status → done
NK-WP-0003: T01 marked done (NK-WP-0004/0005 complete); pre-conditions
  updated; done criteria reflect agent-bootstrap model (no KeePassXC)
NK-WP-0001: status → deferred; T05-T08 (Keycloak) deferred indefinitely;
  superseded_by: NK-WP-0003 added

Active work path is now NK-WP-0003 T02-T09.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 08:47:44 +00:00
8db000e5f0 feat(workplan): NK-WP-0005 — agent-driven credential bootstrap
Replaces the human-as-operator model from NK-WP-0004 with full agent
automation. Agent generates, encrypts (SOPS), injects into cluster,
and delivers a single emergency bundle (age key + break-glass passwords).
Human only stores that bundle in their personal password manager.

KeePassXC removed from operational path. creds-state.yaml redesigned
with agent_mode and emergency_bundle_delivered gate. Standard to be
updated to v0.2 (T07).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 09:25:36 +01:00
b4a3a5966f chore(consistency): NK-WP-0004 complete — correct regressed task statuses
All 7 tasks were implemented in c10d7d2 but fix-consistency on the
workstation reverted all statuses to todo (CUST-WP-0026 regression bug).
Corrected all task blocks to status: done and workplan status to done.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 09:19:37 +01:00
01c8a07f3a fix(sso-mfa): NK-WP-0003-T04 — correct privacyIDEA image and port
privacyidea/privacyidea:3.12 does not exist on Docker Hub.
Correct image: privacyidea/otpserver:3.12.2 (port 5001).

Updated files:
- deployment.yaml: image, containerPort, probes, service port
- ingress.yaml: backend service port
- netpol-mfa.yaml: ingress port + keycloak → keycape label
- netpol-sso.yaml: KeyCape egress port to privacyIDEA

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 23:54:18 +00:00
a96d72193c New Workplans 2026-03-21 00:25:42 +01:00
1d94652ba1 feat(sso-mfa): T04 privacyIDEA manifests (NK-WP-0001-T04)
Deploy privacyIDEA (MFA core) in the mfa namespace:
- pvc.yaml: privacyidea-data (5Gi) and privacyidea-logs (2Gi)
- configmap.yaml: pi.cfg reading secrets from env vars
- deployment.yaml: Deployment + ClusterIP Service (port 8080)
- middleware.yaml: Traefik RateLimit + admin IP AllowList
- ingress.yaml: pink.coulomb.social (portal + admin), pink-account.coulomb.social (self-service)
- create-secrets.sh: creates privacyidea-config Secret
- enckey-bootstrap.sh: post-deploy key extraction + DR Secrets
- bootstrap-admin.sh: pi-admin, trigger-admin, privacyidea-trigger-admin Secret
- verify-t04.sh: 8-section done-criteria checker

Config points CP-NK-002 (pink.coulomb.social) and CP-NK-003
(pink-account.coulomb.social) registered in CONFIG.md.

pink = PrivacyIDEA Net Knights (project mnemonic).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 01:22:41 +00:00
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
3890dca25d chore(workplan): mark NK-WP-0002 fully complete (all 4 stages done)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 08:07:20 +01:00
e7bafd69fc feat(local-identity): Stage 4 — security hardening (NK-WP-0002-T04)
Permission enforcement on startup: enforce_permissions() checks store dir
(700), user files (600), signing key, TLS key, audit.log, revoked.json.
CLI and run_server() call it before any sensitive operation.

New modules:
  security.py  check_store(), enforce_permissions(), print_security_check()
  audit.py     log_event() — append-only TSV audit log (mode 600)
  revoke.py    revoke(jti), is_revoked(jti) — revocation list (mode 600)

New CLI commands:
  security-check          Print per-check pass/warn/fail report; exit 1 on failure
  revoke-token <jti|jwt>  Add JTI to revocation list; accepts raw JTI or full JWT

Serve integration:
  Audit log written for auth request, token issuance, and userinfo calls
  Revocation checked at /userinfo; revoked tokens return 401

Docs: security model section in LocalIdentity.md — threat model,
assumptions, non-guarantees, SELinux/AppArmor guidance, revocation usage.

138 tests passing (34 new for Stage 4).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 08:06:56 +01:00
ec4626fb84 chore(workplan): mark NK-WP-0002-T03 done, record commit hash
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 01:06:01 +01:00
d35823df08 feat(local-identity): Stage 3 — minimal native OIDC provider (NK-WP-0002-T03)
Add local-identity serve command: a minimal Authorization Code flow OIDC
server backed by file-store users.  Implemented natively with no heavy
OIDC library — only stdlib http.server and the cryptography package.

New modules:
  keys.py      RSA-2048 signing key generation + JWKS helpers
  tls.py       Self-signed TLS certificate (localhost/127.0.0.1 SANs)
  jwt_utils.py RS256 JWT creation and verification
  serve.py     OIDCHandler + make_handler() factory + run_server()

Endpoints: /.well-known/openid-configuration, /jwks, /auth, /token,
/userinfo.  Server binds to 127.0.0.1 only; tokens carry iss: local-identity
which production Keycloak rejects by design.

104 tests passing (16 new for Stage 3).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 01:05:50 +01:00
25c92863cf chore(workplan): mark NK-WP-0002-T02 done, record commit hash 2026-03-02 00:24:04 +01:00
dad8365e6a feat(local-identity): Stage 2 — Keycloak export & bootstrap integration (NK-WP-0002-T02)
export.py:
  - split_fullname(): last-token strategy (Bernd Worsch → firstName/lastName)
  - _deterministic_id(): uuid5(DNS, "local-identity.{realm}.{username}") for stable,
    re-import-idempotent Keycloak IDs
  - user_to_keycloak(): full Keycloak Admin REST API user representation;
    production_identity mapping applied to username + realm; isolation attributes
    (local_identity_environment, local_identity_generated) always present;
    validate_keycloak_user() called on every conversion to catch schema drift
  - bulk_export_body(): partial import body (ifResourceExists/realm/users)

cli.py: add `export` subcommand
  - export <username>         single user, prints Keycloak JSON
  - export (no args)          bulk; primary users only; stderr note on skipped test users
  - export --include-test     bulk; all users including generated
  - --realm / --if-resource-exists flags

docs/LocalIdentity.md: add two new sections
  - Keycloak import procedure: export → partialImport API → password reset → retire
  - Isolation guarantee: attribute schema, Keycloak Condition authenticator config,
    production_identity mapping walkthrough

tests/test_export.py: 34 new tests (88 total, all passing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 00:23:39 +01:00
45cba35054 chore(workplan): mark NK-WP-0002-T01 done (Stage 1 complete)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 00:02:40 +01:00
6ed0061962 feat(local-identity): add NK-WP-0002 workplan and LocalIdentity.md
Follows resolved decisions D4 and D5 (2026-03-01, Tegwick):

D4 — ESO chosen as secret injection strategy. NK-WP-0001 T01 Phase 0b
updated to specify ESO; T01 done-criteria updated to require a working ESO
test injection.

D5 — Local Identity implemented in-repo (not a separate repo). Four
deliverables:
- docs/LocalIdentity.md: capability overview, design principles, user
  schema, OIDC provider description, risk mitigations, scope boundaries
- workplans/NK-WP-0002-local-identity.md: four-stage implementation plan
  (core file store, bootstrap integration, minimal OIDC, security hardening)
  with State Hub task IDs
- NK-WP-0001 updated: D2/D4/D5 rows resolved, T07 bootstrap section now
  references NK-WP-0002 and documents the export→Keycloak migration path,
  Open Questions condensed to two remaining artefacts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 23:49:06 +01:00
873fbcf052 docs(workplan): add D4/D5 decisions, T02 prerequisite, EP-NK-001 reference
- Extend decisions table with D4 (secret injection, pending) and D5
  (file-based bootstrap user store, pending with SWOT)
- Add explicit prerequisite block to T02: T01 Phase 0a must complete first
- Update T07: reference EP-NK-001 (LDAP/Entra extension point) by ID
- Condense Open Questions into a reference table pointing to State Hub artefacts
- Ecosystem ADR recommendation recorded as [repo:custodian] task in hub

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 23:11:51 +01:00
534906d509 docs(workplan): update NK-WP-0001 with resolved decisions D1/D2/D3
- Add Decisions table summarising D1 (KeePassXC→Vault), D2 (Keycloak-internal
  hybrid + file-based bootstrap), D3 (plain Helm, AI-first philosophy)
- Split T01 into Phase 0a (pre-cluster KeePassXC) and Phase 0b (in-cluster
  Vault transition) per D1
- Update T05 to explicitly reference D3 (plain Helm first)
- Update T06 to state the D2 identity decision rather than re-opening it
- Update T07: remove "decide" language, implement decided approach, add
  D2 bootstrap user management scope note
- Update T08: add Vault unseal key backup to the backup list
- Replace Open Questions with remaining unresolved items (5 items)
- Add DECISIONS.md (decision log auto-generated by State Hub)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 22:51:11 +01:00
004a8d6e6b Add CLAUDE.md, wiki protoplans, and NK-WP-0001 workplan
Initialises the net-kingdom project structure:
- README.md: updated title and description
- CLAUDE.md: project instructions and State Hub integration config
- wiki/: three reference docs (NetKingdom overview, ChatGPT and Grok
  protoplans for the SSO/MFA platform)
- workplans/NK-WP-0001-sso-mfa-platform.md: combined workplan (8 phases,
  8 tasks) synthesised from the two protoplans; registered in the
  Custodian State Hub (workstream 39263c4b)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 17:21:51 +01:00