railiance-apps/workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md
tegwick 3fb031a47f
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Compose Forgejo private-input and authenticated decision build candidate
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a14bfc-9643-7872-aa12-98326dcf25e7
2026-10-18 02:21:33 +02:00

13 KiB

id type title domain repo status flavor owner topic_slug created updated depends_on related_repos state_hub_workstream_id
RAPPS-WP-0016 workplan Forgejo sign-in through NetKingdom, before the forge closes infotech railiance-apps active implementation claude-code railiance 2026-10-08 2026-10-18
KEY-WP-0038
prj-forgejo-org-refactor
key-cape
railiance-platform
f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b

RAPPS-WP-0016 - Forgejo sign-in through NetKingdom, before the forge closes

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 sign-in runs through NetKingdom first. railiance-apps owns the Forgejo Helm release (docs/forgejo-on-railiance01.md: S5 Helm release, ingress, operator Makefile), so the Forgejo side lands here. This plan is ORGREF-WP-0002-T05. The NetKingdom side is key-cape KEY-WP-0038.

Boundaries

  • Founder guardrail: tighten gradually; never lock anyone out; never risk assets; never reach a state that is hard to repair. Every step keeps the current sign-in path working until the new one is proven.
  • No visibility change in this plan. Repositories, packages and REQUIRE_SIGNIN_VIEW are ORGREF-WP-0002-T08.
  • Configuration in git. The authentication source is declared in helm/forgejo-values.yaml (gitea.oauth), with its secret drawn from an ExternalSecret over OpenBao. No click-ops, and no secret value in git.
  • Open registration is already disabled (service.DISABLE_REGISTRATION: true). This plan keeps it that way.

Tasks

id: RAPPS-WP-0016-T01
status: done
priority: high
state_hub_task_id: "98004ed0-83e6-5f6e-9b18-15b8b2aec2e7"

T01 — Make the local administrator a sealed break-glass

Before anything about sign-in changes: confirm the local administrator account works, keep its credential only in OpenBao, and document recovery (who, how, where it is logged) in docs/forgejo-on-railiance01.md. Verify one break-glass sign-in and record it without the credential.

Acceptance: a recorded break-glass sign-in, with the recovery path written down. This is the "never lock ourselves out" floor for every later step.

Done 2026-10-17: founder sealed forgejo_admin into OpenBao platform/workloads/forgejo/break-glass-admin (version 1) and verified a local sign-in (HTTP 200, site admin): docs/evidence/2026-10-17-forgejo-breakglass-signin.json. Recovery path: docs/forgejo-on-railiance01.md § Break-glass administrator.

id: RAPPS-WP-0016-T02
status: wait
depends_on: [RAPPS-WP-0016-T01, KEY-WP-0038-T02]
blocking_reason: "Break-glass done (T01); needs the NetKingdom client registered with its secret in custody (KEY-WP-0038-T02)."
priority: high
state_hub_task_id: "13cd3aec-c87d-5d3f-a421-39d8ff131edd"

T02 — Add the NetKingdom authentication source

  • an ExternalSecret delivering the forgejo client secret from OpenBao to a Secret in the forgejo namespace. Custody path is platform/workloads/keycape/forgejo, field CLIENT_SECRET, read by ESO through Kubernetes-auth role external-secrets-keycape-forgejo-forgejo, which carries only policy workload-kv-read-keycape-forgejo-forgejo (net-kingdom 074b3a0; replaces the earlier platform/workloads/forgejo/netkingdom-oidc-client proposal). The SA/SecretStore/ExternalSecret shape follows the NK-WP-0048 deliver-consumer-secret receipt contract (docs/evidence/nk48-t16-owner-review/owner-review-railiance-apps.json)
  • gitea.oauth: name netkingdom (must match the redirect URI registered in key-cape), provider openidConnect, auto-discovery from https://kc.coulomb.social/.well-known/openid-configuration, scopes openid profile email groups, group-claim name groups
  • oauth2_client settings: no automatic account creation for unknown subjects; account linking to existing local accounts by username after a successful local sign-in (so the founder and agent accounts keep their history)
  • Helm upgrade with the previous revision noted for rollback

Local password sign-in stays enabled.

Acceptance: the "Sign in with netkingdom" option appears. Local sign-in still works. Rollback is one helm rollback to the noted revision.

id: RAPPS-WP-0016-T03
status: wait
depends_on: [RAPPS-WP-0016-T02]
blocking_reason: "Linking and team mapping follow a working authentication source."
priority: high
state_hub_task_id: "81f072aa-c316-511e-a2cd-21dd1b1d0a00"
  • The founder links their account through NetKingdom (MFA), then signs in again through NetKingdom only and sees the same repositories, organisations and admin rights.
  • Map NetKingdom groups (names agreed in KEY-WP-0038-T01) to organisation teams: owners and readers at least. Create the read-only teams that ORGREF-WP-0002-T06 consumers will use.
  • Apply KEY-WP-0038-T03's decision on agents and services: NetKingdom sign-in, or scoped tokens bound to service identities.

Acceptance: founder and one agent work through NetKingdom; group-to-team mapping verified by adding and removing one test membership; break-glass still works.

id: RAPPS-WP-0016-T04
status: wait
depends_on: [RAPPS-WP-0016-T03]
needs_human: true
blocking_reason: "Restricting local password sign-in is a founder decision once NetKingdom sign-in is proven."
priority: medium
state_hub_task_id: "32c54737-c40f-5fde-9b91-163f8dcb0068"

T04 — Decide on local password sign-in

Once NetKingdom sign-in has been used for a while without problems, the founder decides whether local password sign-in is turned off for everyone except break-glass. This is not required to close the forge; it is the next tightening step, taken separately.

id: RAPPS-WP-0016-T05
status: wait
depends_on: [RAPPS-WP-0016-T02]
blocking_reason: "Waits for net-kingdom's answer to the Apps 1.3 needs-change record (the-custodian docs/changes/netkingdom-target-2026-10-17/nk48-1.3-owner-review/owner-review-railiance-apps.json: RAPPS-1.3-C1..C3) and the re-frozen 1.3 candidate."
priority: medium
state_hub_task_id: "728786c9-f1f9-5983-a6a4-dea21faf67f5"

T05 — Apps owner seams for NK-WP-0048 consumer steps

Implement the real Apps capabilities behind the deliver-consumer-secret and hand-over adapters, as owner-run paths (option C): owner_apply / owner_remove emitting netkingdom.consumer-secret-delivery.v1 receipts from the T02 objects; a consumer verifier that observes Forgejo sign-in and the T03 positive/negative group probes; and a committed-evidence hand-over receipt store. See the owner-review record for the contract.

Acceptance: receipts produced from the live T02/T03 run validate against the adapters' checks with no value-bearing keys.

Also in scope: stale node credential

The k3s registries.yaml on railiance01 still holds a login for the frozen Gitea host 92.205.130.254 (ORGREF-WP-0002-T02). Coordinate its removal with the node owner when ORGREF-WP-0002-T06 adds the forge registry login, in the same change.

T06 — Package the reviewed consumer source through the Apps build path

id: RAPPS-WP-0016-T06
status: done
priority: high
state_hub_task_id: "08ab8921-7801-5309-b84b-bc2a3ceea1e4"

Completed 2026-10-18, source build tooling only. The existing Apps Makefile now has explicit prepare, public-dependency acquisition, offline build, artifact verification and local OCI export targets for the pinned official Forgejo11.0.3 source plus reviewed multi-value claim patch. Source/toolchains/locks/compiler inputs/base image are fixed. Third-party application source stays in a new /tmp workspace; Apps holds the release input lock, patch and build recipe.

The original build profile produced identical frontend assets, bindata sources and complete static executable in two workspaces, and identical local OCI archives in two no-cache exports. Independent review then found host process argv visibility through /proc (APPSBUILD-R1-F01). The revised recipe adds a private PID namespace; exact source and synthetic canary regression are separately reviewed. The original full builds are historical r1-profile evidence; no full r2 build is claimed. Original packet/review and failure history remain in Custodian apps-forgejo-release-build-r1 and apps-release-independent-review-r1; the correction is apps-forgejo-release-build-r2. This is coordinator source integration after independent technical review, not formal owner assent or image admission. Helm values, deployed image, local sign-in and visibility are unchanged. NK-WP-0048-T39 remains progress for the full release acceptance scope.

T07 — Keep the client secret out of process arguments

id: RAPPS-WP-0016-T07
status: progress
priority: high
state_hub_task_id: "786d6584-6db1-5a10-9324-d7b94db0df94"

Implement and independently review a real Forgejo add/update --secret-file path and the actual chart helper/mount adaptation. Preserve the existing CLIENT_SECRET key and custody route; use no agent-value argument or environment fallback. Test bounded stable nofollow file reads, exact existing minted-secret encoding, mutual exclusion/update preservation, fixed errors and actual Helm rendering. Private mount identity/reader set and new package/type revisions need explicit owner/runtime admission. The in-progress isolated candidate is Custodian forgejo-private-input-r1; source completion is distinct from T02 native delivery.

T08 — Provide a transactional application-source inverse and durable recovery

id: RAPPS-WP-0016-T08
status: progress
priority: high
state_hub_task_id: "4ab8a5e7-ab32-5ee2-aaf2-6da246d1b0c8"

Implement actual owner database primitives that record operation intent/outcome in the same durable database, compare complete raw persisted before/post/current source state privately, and serialize conflicting application writers at the DB boundary. Never emit stored credential/config bytes or delete/detach linked users or a preexisting/shared source. SQLite and PostgreSQL transaction semantics must be tested against the real app packages; unsupported backends refuse.

T05 and NK-WP-0048-T34 additionally require actual authenticated execution and fresh inverse sessions, admitted evidence/recovery and exclusion of every release writer, including Helm/runtime writers. The candidate DB primitive alone does not establish those facilities. Helm rollback/omission does not remove persisted OAuth sources: verify the exact app-state inverse before any image downgrade. If links prevent removal, retain the extended image and reconcile. The earlier T02 single-Helm-rollback statement is not sufficient recovery for this extension; its historical text is retained and corrected here.

T09 — Enforce authenticated Access Engine decisions in the application path

id: RAPPS-WP-0016-T09
status: progress
priority: high
state_hub_task_id: "d3804638-c73d-5b9f-a456-4262f62f9e6b"

Use the producer-owned decision format/canonical bytes and independently admitted signer/policy/request pins. Forgejo must verify the caller's issuer/tenant and assurance facts, obtain and authenticate the exact Access Engine resource/action decision, and refuse missing, stale, wrong-pin, unavailable or malformed replies. Keep the original three-group any-of access set as policy input; its local compatibility gate is not a substitute PDP or an architecture exception. An issuer allowed/denied claim cannot manufacture authorization. Source integration needs real provider/callback/session wiring and meaningful producer-consumer positive/adverse tests before re-freezing the case and package. Existing break- glass/local account and linking behavior remain within the declared owner scope.

2026-10-18 source continuation for T07/T08/T09: the digest-bound build candidate now composes all 37 paths, including private secret-file input, actual source-state transactions/private SQL hooks, the producer-owned Access Engine Check client from ca0cb757 and guarded OIDC callback enforcement. The parser uses the actual KeyCape typed assurance/authentication-time/provenance contract; its actual issuer fixture/callback suite passes 71 test/subtest results, and selected composed packages pass 93 with no skips. The previous incompatible-string-claim rejection is retained. All patch postimages independently replay from the pinned official archive. Complete release build/verification is tracked in Custodian forgejo-keycape-claims-r1; earlier release outputs do not prove this revision.

This is coordinator source integration of a tested build candidate; independent owner review and formal operational admission remain open. T07's chart/private mount admission, T08's fresh authenticated operation/inverse and release-wide writer exclusion, T09's ongoing HTTP/API/Git/SSH paths, private evidence/retention, PostgreSQL/native proof and actual issuer/factor/custody acceptance remain open. No trust, deployed image, Helm values, source DB, user/link state or local sign-in is changed by this build-source update. The preserved legacy patch is historical; the input lock now explicitly selects forgejo-security-extension.patch.