Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
9.9 KiB
| id | type | title | domain | repo | status | flavor | owner | topic_slug | created | updated | depends_on | related_repos | state_hub_workstream_id | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| KEY-WP-0038 | workplan | Forgejo as a NetKingdom OIDC client, so the forge can close | infotech | key-cape | active | implementation | claude-code | railiance | 2026-10-08 | 2026-10-16 |
|
098e3e2c-a138-560e-b2d3-3a15eb49d8a9 |
KEY-WP-0038 - Forgejo as a NetKingdom OIDC client, so the forge can close
Why
forgejo.coulomb.social is closing: private by default, no anonymous access
(prj-forgejo-org-refactor ORGREF-WP-0002, decision
decisions/forge-visibility-policy.md). The founder's condition is that Forgejo
sign-in runs through NetKingdom before anything closes, so that every human,
agent and service reader has a governed identity rather than an ad-hoc local
account. This plan is ORGREF-WP-0002-T04. Its Forgejo-side counterpart is
railiance-apps RAPPS-WP-0016 (ORGREF-WP-0002-T05), which owns the Forgejo
Helm release.
Boundaries
- Registration follows the existing human browser-client pattern
(
docs/approval-engine-provisioning-request.yaml,human_registration) and the client fields validated in KEY-WP-0028. Redirect URIs are exact, never wildcards. - The client secret goes to OpenBao through railiance-platform custody. No secret value in git, State Hub, logs or chat.
- Founder guardrail for the whole closure: tighten gradually, never lock anyone out, never risk assets. Nothing in this plan changes who can read the forge today. It only makes the NetKingdom path available.
T01 — Define what Forgejo receives
id: KEY-WP-0038-T01
status: done
priority: high
state_hub_task_id: "5f019d13-1fa3-5b88-a27a-75a3339ca96e"
Write the claim contract Forgejo consumes, as a non-secret request packet under
docs/:
- issuer
https://kc.coulomb.social; confidential clientforgejo; authorization code with PKCE; scopesopenid profile email groups - redirect URI
https://forgejo.coulomb.social/user/oauth2/netkingdom/callback. The authentication-source namenetkingdommust match railiance-apps' configuration exactly. - subject and username: canonical directory subject, plus a stable
preferred_usernamethat Forgejo can match to the existing local accounts (founder and agent accounts) for linking groupsnaming the Forgejo organisations and teams to map to (for exampleforge:coulomb:owners,forge:coulomb:readers), andprincipal_typeso that human and service principals stay distinguishable- MFA: forge administrators and owners require assurance with a fresh second factor; plain readers follow the client-aware MFA policy (KEY-WP-0008)
Acceptance: the founder accepts the packet. The group names are agreed with railiance-apps.
2026-10-08: packet drafted at docs/forgejo-oidc-client-request.yaml. It covers a
confidential client forgejo with PKCE and mfaRequired: true, the exact
callback, scopes, a custody path, the claims as emitted at this revision, new
LLDAP groups forge-admins, forge-coulomb-owners and forge-coulomb-readers
with a required-claim gate, no automatic account creation, and linking of local
accounts. It also proposes that agents and services use scoped tokens bound to
service identities, not browser sign-in.
2026-10-08: accepted by the founder (in session). railiance-apps' RAPPS-WP-0016
uses the same authentication-source name netkingdom and the same group names,
so the agreement condition holds. Before T02, the LLDAP groups forge-admins,
forge-coulomb-owners and forge-coulomb-readers must exist, with the founder
in the first two.
T02 — Register the client and hand over its secret
id: KEY-WP-0038-T02
status: wait
depends_on: [KEY-WP-0038-T01, NK-WP-0048-T06]
blocking_reason: "Registration runs as the first KnownSecurityCase of type oidc-browser-relying-party (NK-WP-0048-T06), not as a hand-built rollout."
priority: high
state_hub_task_id: "ddcfb482-8f33-5c81-9ce8-84be8fa5dc30"
Changed 2026-10-08 (founder direction): no case-specific helper script.
Registration is the first case of the SecurityCaseType oidc-browser-relying-party
(net-kingdom NK-WP-0048, canon security-case-types_v0.1). The parameters
accepted in T01 become the case; ops-mason materializes it (MASON-WP-0010) and
ops-warden follows through (WARDEN-WP-0044). The registration capability is
net-kingdom's (net-kingdom.keycape-client-registration); key-cape's part is its
field rules and reviewing the type's composition.
The original intent below still describes what must result.
Register forgejo from the packet. Mint the client secret straight into custody
(OpenBao path platform/workloads/keycape/forgejo, field CLIENT_SECRET, derived
by the case type since net-kingdom 074b3a0; custody owner railiance-platform,
consumers KeyCape via ESO and Forgejo). Record a receipt with no
secret value.
Acceptance: discovery metadata lists the client's redirect URI. The secret is readable by Forgejo's custody path only.
2026-10-10: key-cape reviewed the type's composition
(docs/oidc-browser-relying-party-type-review.md). net-kingdom fixed the findings
in 61ab6bc, a 1.0 patch: redirects with ? or # refused, the groups scope
required, and descriptions corrected. A new 1.1 (e2174ce, founder go) adds the
consumer-enforces-groups verification. For Forgejo, that is the required-claim
setting railiance-apps configures. security-cases/forgejo-netkingdom-oidc.yaml
is re-pinned to @1.1, with parameters unchanged. KeyCape added keycape check-config (c528daa), which register-client runs before the restart. T02 still
waits on NK-WP-0048-T06, which needs both executors' light paths (MASON-WP-0010-T03,
WARDEN-WP-0044-T03).
Exact offline checker owner review — 2026-10-16
KeyCape owner review under KEY-WP-0038-T02 endorses only the offline config
validation behavior of source 3c71226a1a7b8a2bdb710e9c497e1a1f7f8a3987,
src tree f0010b9cab17dbc3a787628a29657d98b900320f, compiled artifact
sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5.
The exact source/archive, 108 source files, 9876 cached Go 1.23.0 toolchain
files and all ten selected module trees matched the candidate closure. Fourteen
actual artifact checks and the cmd/config/policy Go tests passed using only
synthetic inputs. The check dispatches before private-key loading, upstream
adapter construction or server startup and uses placeholder client secrets.
Owner review records the
exact evidence and limits: non-secret portal/logout URL environment overlays,
optional/nonempty env-name assertion and policy-store assertion, permissive YAML
loading, and no key/custody/readiness or authentication proof. It does not endorse
the caller's inherited environment, executable storage/custody, the NetKingdom
descriptor/type, Warden admission or any browser/native identity. Parent review
identified caller environment inheritance; NetKingdom owns its correction and
regression checks. T02 remains wait; T03 and all live acceptance gates remain
unchanged. No live config, credentials, cluster objects or paid calls were used.
T03 — Prove the claims for each kind of identity
id: KEY-WP-0038-T03
status: wait
depends_on: [KEY-WP-0038-T02]
blocking_reason: "Claims are verified against the registered client."
priority: high
state_hub_task_id: "40ddaa29-7245-508c-ad48-ddc063e25115"
Before Forgejo uses the client, verify the issued ID token and UserInfo for one
human (the founder, with MFA), one agent identity and one service identity:
subject, preferred_username, groups, principal_type, assurance. Record the
claims, minus tokens, as evidence.
Decide with railiance-apps whether agents and services sign in to Forgejo at all, or receive scoped Forgejo tokens bound to a NetKingdom service identity (ORGREF-WP-0002-T06). Record the decision.
Acceptance: evidence for all three principals; the agent and service decision is recorded. Then hand over to RAPPS-WP-0016.
T04 — Implement the keycape-client entry point
id: KEY-WP-0038-T04
status: cancel
priority: high
state_hub_task_id: "583cf1f1-16dc-515f-83bc-1efc45024a89"
Cancelled 2026-10-08: moved to net-kingdom NK-WP-0048-T09 (done). The live
registration machinery (contained kubectl, cluster and issuer pins) already lives
in net-kingdom sso-mfa/k8s/keycape/, where KeyCape is deployed; a copy here
would drift. The entry point is net-kingdom/sso-mfa/k8s/keycape/keycape-client.py
and the declaration is net-kingdom.keycape-client-registration; key-cape's draft
declaration is removed. key-cape still owns the client field rules (canonical
model) and their enforcement at authorization time.
capabilities/playbooks/key-cape.oidc-client-registration.yaml (contract PASS,
maturity: planned) declares client registration as a playbook capability, so
that the SecurityCaseType oidc-browser-relying-party (net-kingdom NK-WP-0048)
can compose it. Implement the entry point it names, tools/keycape-client/:
keycape-client register --client-file <rendered-client.yaml>with modesinspect,dry-run,applyandremove; adds, updates or removes exactly one client in the live registry; idempotent; never prints or writes secret values; a confidential client's secret is read from its custody reference- one implementation replacing the per-client helpers in net-kingdom
sso-mfa/k8s/keycape/(register-coulomb-social, portal-client-rollout, vergabe-client-rollout, secrets-engine-openbao-client-rollout), keeping their safeguards (byte-preserving merge, compare-and-swap, cluster pin, safe receipts) and their tests as regression cases - client field validation by the KEY-WP-0028 rules
- then set the declaration's
maturitytoimplemented
Longer term, loading clients from a non-secret registry with secrets referenced from custody would remove the type's only attended step (see the type README, "Attended steps").