net-kingdom/workplans/NK-WP-0051-sign-in-diagnosis.md
tegwick 9442858535
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Complete NK-WP-0051 with attended member and refusal evidence
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a13eab-1e6a-7b33-9c37-372e90ada3a2
2026-10-15 19:23:19 +02:00

9.4 KiB

id type title domain repo status flavor owner topic_slug created updated depends_on related state_hub_workstream_id
NK-WP-0051 workplan Show who a workload sign-in actually is infotech net-kingdom finished implementation codex netkingdom 2026-10-14 2026-10-15
MASON-WP-0011
NK-WP-0034
NK-WP-0042
c1771c07-4466-5aa2-ad43-df63a471946b

Show who a workload sign-in actually is

Goal

Make the next attended workload login show the uid, the directory group names, and whether this authorization verified a one-time code, before OpenBao accepts or refuses it.

MASON-WP-0011 took a day because those three facts were split across the account site, Authelia, and OpenBao. The account site stayed on bernd.worsch-3 while bao login reused another Authelia session. OpenBao then said only claim "groups" does not match any associated bound claim values. A user with no one-time password never reached that refusal.

Done when an attended bao login with the T05 fixture uid shows, before OpenBao answers, the uid, its group display names, and aal2; and the ops-mason receipt for the refused login names the same uid and the OpenBao error text. A routine login to a client that has not opted in gains no extra screen.

Boundaries

NetKingdom orchestrates this. It does not re-implement the issuer, the account page, or OpenBao.

Change Owner
Pre-redirect diagnosis and the uid on the KeyCape auth log key-cape
Account-site uid and Authelia uid as two lines user-engine
Authelia session hint, memberOf preview, negative-login fixture name net-kingdom
Fresh browser for bao login, receipt fields, capabilities-self on the lane token ops-mason, applied by railiance-platform
Role choice on the OpenBao UI. platform-admin stays the admin role railiance-platform

Out of scope: widening ops-mason-survey, attaching workload-kv-read-reuse-surface-runtime to admin entity 4a1f663c-0621-0483-edd0-f852274f4b6b, verbose_oidc_logging, and any log of a token, authorization code, email address, or one-time password. Group display names and the uid are the diagnosis. They are not secret.

Completion review — 2026-10-15

All six tasks are done. The founder selected existing MFA-enrolled tegwick for the negative fixture and confirmed its sole directory group is railiance-admins. Its attended diagnosis showed that uid/group and aal2 before the workload role refused the groups claim; the native verifier receipt names the same uid and preserves the error. The member proof as bernd.worsch-3 passed all capability checks and revoked its token.

CCR-2026-0045 was approved by the founder in both requested roles and applied through a contained platform-root OIDC/MFA session (exit 0). The approved login overlay was deployed and its HTTP verification passed. The existing owner task RPF-WP-0057-T04 retains separate UI role-selector clickthrough; this does not block the completed native attended diagnosis/refusal goal.

Evidence: acceptance and sanitized receipts. Directory-helper verification: 68 passed. Platform checks: 64 passed, 2 unrelated failures (CCR-2026-0035 schema and core-hub resource-list expectation); CCR-2026-0045 validates and its dry-run has no warnings.

Security orientation: Emergent Knowledge 0.2.6, package digest 8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02; start and identity were withheld / orientation-only because sources changed. Reviewed their source cards, current SECURITY-COMPANION.md, owner declarations and the current owner procedures directly. Retrieval grants no live authority.

Write the diagnosis contract

id: NK-WP-0051-T01
status: done
priority: high
state_hub_task_id: "c969161a-cf81-57b0-9bbf-12989134e0eb"

Write docs/sign-in-diagnosis.md. It is the contract the other tasks implement. It names three facts, for this authorization and no earlier one:

  • the uid KeyCape resolved from Authelia preferred_username
  • the directory group display names copied from that uid's memberOf
  • whether this authorization verified a one-time code (aal2) or did not (aal1)

The contract also says where each fact appears: the page before KeyCape returns to the application, the KeyCape log line (client_id and uid), the account site (account-site uid and Authelia uid on separate lines), and the ops-mason receipt (uid and the OpenBao error text, no token).

Each fact has one field name, used unchanged on every surface: uid, groups (sorted display names), assurance (aal1 or aal2), plus client_id and, on the receipt only, openbao_error. The document also lists what never appears: tokens, authorization codes, email addresses, one-time passwords, raw memberOf DNs, and session cookies.

assurance describes this authorization request, from KeyCape's assurance decision (MFAVerified). A reused session that was aal2 earlier is aal1 here unless this request asked for and verified the one-time code.

Done when that document is the only copy of the field list and the other tasks link to it instead of restating it.

KeyCape shows the principal before the callback

id: NK-WP-0051-T02
status: done
depends_on: [NK-WP-0051-T01]
priority: high
state_hub_task_id: "a78219bb-2355-5a2e-8750-0b32a57f87bc"

key-cape shows the three facts before it redirects to the application, and adds the uid and client_id to the existing auth log line.

The page is opt-in per client (a client registration flag, default off), enabled first for the OpenBao client. Routine logins elsewhere keep their current flow. The page has one action, continue, and a line that says how to sign in as someone else. A groups refusal from OpenBao then follows a screen that already named the uid.

The live flag is set with sso-mfa/k8s/keycape/openbao-signin-diagnosis-rollout.py (inspect, server dry-run, attended apply on the observed uid/resourceVersion; --operation remove is the rollback), followed by an issuer restart.

Acceptance is a deployed key-cape image. The log line contains no token, code, email, or one-time password. This repo records the image digest in the T01 document.

Account site shows both sessions

id: NK-WP-0051-T03
status: done
depends_on: [NK-WP-0051-T01]
priority: high
state_hub_task_id: "bdc8b414-94fe-52cb-8e26-85c9914d4068"

users.coulomb.social keeps the account-site session. It adds the current Authelia uid beside it. Authelia's cookie domain stays coulomb.social. This repo only points at that requirement from docs/sign-in-diagnosis.md.

Preview directory groups for a uid

id: NK-WP-0051-T04
status: done
depends_on: [NK-WP-0051-T01]
priority: high
state_hub_task_id: "65f85a11-8512-5700-b258-feb2ead84372"

Add a read-only groups --user <uid> operation to sso-mfa/k8s/lldap/lldap_admin.py. It reuses the existing snapshot and custody login, has no --apply, and prints the T01 fields uid and groups. An unknown uid is a refusal, not an empty list. No mail, no password, no one-time password. Tests extend tests/test_lldap_group_maintenance.py; GROUP-MAINTENANCE.md documents the command. Matching those names to an OpenBao role stays a metadata read in ops-mason.

Name one negative-login fixture in the T01 document (tegwick): a uid that is not in reuse-surface-hub-writers, is not a platform admin, and will hold a one-time password. Do not create that user in git.

Enroll the negative-login factor

id: NK-WP-0051-T05
status: done
depends_on: [NK-WP-0051-T04]
priority: medium
state_hub_task_id: "afb5816f-5657-5fc8-856f-00ce5b431939"

Founder confirmed in this session (2026-10-15) that the existing account tegwick already has MFA set up, and selected it instead of creating signin-probe-negative. T05 is done on that confirmation. Founder confirmed directory membership is railiance-admins only; the attended negative-login diagnosis showed the same group. No directory changes were made.

Enrollment is not aal2. A later login is aal2 only when that login asks for the one-time password.

Hand the OpenBao proof back to its owners

id: NK-WP-0051-T06
status: done
depends_on: [NK-WP-0051-T01]
priority: medium
state_hub_task_id: "86fb4a6b-6655-57c2-b166-38c18e183eb0"

Ask ops-mason and railiance-platform to do four things, and no others:

  • bao login for a named role uses a fresh browser profile, or prints the address and waits. It does not reuse the default Authelia session.
  • The verifier receipt records the uid and the OpenBao error text. It still records no token and no KV value.
  • The lane policy gains a generated sys/capabilities-self read so the proof does not call sys/capabilities with a root token.
  • The OpenBao UI can select the workload role. The existing button remains role platform-admin.

ops-mason-survey stays read-only. The workload policy stays off the admin entity. This task is done when both repos have accepted those four items, not when this repo edits them.

Accepted live 2026-10-15: CCR-2026-0045 applied, overlay deployed/verified, and both MASON-WP-0012-T04 proofs passed. The contract evidence records the attended principal, group and assurance observations and native receipt references. The pre-existing RPF-WP-0057-T04 retains separate UI control clickthrough; no such browser interaction is claimed here.