8.4 KiB
| id | demand_source | consumer_repo | credential_type | derived_from_type | render_digest | status | case_acceptance | reference_case | approved_by | approved_at |
|---|---|---|---|---|---|---|---|---|---|---|
| case-forgejo-netkingdom-oidc | SecurityCase forgejo-netkingdom-oidc (owner railiance-apps) | railiance-apps | security-case | oidc-browser-relying-party@1.2 | sha256:c0afd5576cdae0cbc807eccb2b9fa87ac668f15e32ec7cf79d295bdb23c75b35 | draft | null | true | null | null |
Construction plan (derived-from-type): forgejo-netkingdom-oidc
Rendered from oidc-browser-relying-party@1.2 (Browser OIDC relying party for an internal service). Do not edit by hand:
re-run ops-mason plan --case instead. Render digest sha256:c0afd5576cdae0cbc807eccb2b9fa87ac668f15e32ec7cf79d295bdb23c75b35.
Reference case: the type is acknowledged, not yet implemented. This case
is the one whose live materialization takes the type to implemented.
1. Demand
Let an internal web service sign its human users in through NetKingdom (KeyCape): an exact-redirect OIDC client, optional MFA pin, the LLDAP groups the service maps to its own roles, and, for confidential clients, a client secret minted straight into OpenBao custody. Replaces the per-client rollout scripts in sso-mfa/k8s/keycape. First case: Forgejo (KEY-WP-0038).
2. Existing-structure survey
Survey source: none (metadata only).
No collision with existing policies, roles, KV paths or catalog entries.
3. Objects (from the type's materialization)
| Item | Kind | Name |
|---|---|---|
| client-secret-path | kv_path | platform/workloads/keycape/forgejo |
| keycape-reader-policy | openbao_policy | workload-kv-read-keycape-forgejo-eso |
| consumer-reader-policy | openbao_policy | workload-kv-read-keycape-forgejo-forgejo |
| eso-role | openbao_role | external-secrets-keycape-forgejo |
| consumer-eso-role | openbao_role | external-secrets-keycape-forgejo-forgejo |
| catalog-entry | catalog_entry | forgejo-keycape-client |
client-secret-path
field CLIENT_SECRET; minted by the credential broker, never written by hand
keycape-reader-policy
path "platform/data/workloads/keycape/forgejo" {
capabilities = ["read"]
}
consumer-reader-policy
path "platform/data/workloads/keycape/forgejo" {
capabilities = ["read"]
}
eso-role
auth: kubernetes
bound_service_account_names: [external-secrets]
bound_service_account_namespaces: [external-secrets]
token_policies: [workload-kv-read-keycape-forgejo-eso]
token_no_default_policy: true
token_ttl: 15m
token_max_ttl: 15m
consumer-eso-role
auth: kubernetes
bound_service_account_names: [forgejo-keycape-forgejo-eso]
bound_service_account_namespaces: [forgejo]
audience: openbao
token_policies: [workload-kv-read-keycape-forgejo-forgejo]
token_no_default_policy: true
token_ttl: 15m
token_max_ttl: 15m
catalog-entry
id: forgejo-keycape-client
owner_repo: key-cape
warden_executes: false
risk: high
status: active once verification passes
workload_ref: applicable, name forgejo, declaration_ref of the consumer's published declaration or the explicit unknown form, never inferred
path_template: platform/workloads/keycape/forgejo
field: CLIENT_SECRET
delegation: native, intended_owner key-cape
rotation: mint-secret then verification; automatable false until a run has been proven
4. Review notes
Shape reviewed once, when the type was acknowledged; this review checks only this case's names against existing structure (section 2).
Follow-through (ops-warden):
- ensure-groups — net-kingdom (attended): identity-provisioner ensure_service_groups, run inside the provisioner pod through the session's contained cluster access (groups forge-admins,forge-coulomb-owners,forge-coulomb-readers; members exactly forge-admins=tegwick;forge-coulomb-owners=tegwick as recorded in the accepted case, nothing else)
- mint-secret — railiance-platform: railiance-platform credential broker: generate a client secret inside custody at bao:platform/workloads/keycape/forgejo
- deliver-secret — railiance-platform: ExternalSecret sso/keycape-forgejo-client (key client-secret) from bao:platform/workloads/keycape/forgejo
- bind-env — net-kingdom (attended): patch Deployment sso/keycape: env KEYCAPE_FORGEJO_CLIENT_SECRET from sso/keycape-forgejo-client
- register-client — net-kingdom (attended): sso-mfa/k8s/keycape/keycape-client.py apply --client-file --case-acceptance --check-config (net-kingdom.keycape-client-registration)
- deliver-consumer-secret — railiance-apps: Owner applies dedicated ServiceAccount forgejo/forgejo-keycape-forgejo-eso (automount=false, no legacy tokens), namespace SecretStore openbao-keycape-forgejo-consumer with serviceAccountRef and audiences [openbao], and ExternalSecret forgejo-netkingdom-oidc-client with Owner target, Retain remote deletion and only CLIENT_SECRET from workloads/keycape/forgejo. Admission validates actual installed ESO TokenRequest support and common controller RBAC before any owner-approved apply.
- hand-over — railiance-apps: configure forgejo with issuer https://kc.coulomb.social, client forgejo and custody bao:platform/workloads/keycape/forgejo, and make it require one of forge-admins,forge-coulomb-owners,forge-coulomb-readers in the groups claim before sign-in completes
Verification:
- authorize-accepts-redirects (present): GET https://kc.coulomb.social/authorize with client forgejo and each of https://forgejo.coulomb.social/user/oauth2/netkingdom/callback returns the login page
- authorize-refuses-other-redirect (deny): GET https://kc.coulomb.social/authorize with client forgejo and an unregistered redirect returns an OAuth error
- custody-denied-to-default (deny): a default-only OpenBao identity has no read capability on bao:platform/workloads/keycape/forgejo
- custody-allowed-to-consumer (allow): policy workload-kv-read-keycape-forgejo-forgejo grants read on bao:platform/workloads/keycape/forgejo (capabilities check only)
- groups-present (present): LLDAP groups forge-admins,forge-coulomb-owners,forge-coulomb-readers exist, with exactly the memberships of the accepted case added
- consumer-enforces-groups (present): forgejo's OIDC source for forgejo (owner railiance-apps) requires one of forge-admins,forge-coulomb-owners,forge-coulomb-readers in the groups claim (configuration read, no secret value)
- secret-delivered (present): the delivery for sso/keycape-forgejo-client reports Ready=True (status only)
- mfa-pinned (present): keycape-client.py inspect for forgejo shows the MFA pin on the registered client (non-secret client view)
- consumer-secret-delivered (present): forgejo SecretStore openbao-keycape-forgejo-consumer and ExternalSecret forgejo-netkingdom-oidc-client Ready=True, exact dedicated SA/audience role binding, fixed CLIENT_SECRET mapping; no Secret value read
Rollback, in order:
- remove the OIDC source for forgejo from forgejo (owner railiance-apps)
- After reverting consumer secret reference, delete only authenticated created ExternalSecret/owned target by UID and ownerReference, then SecretStore and dedicated SA; preserve preexisting-matched resources and never delete a shared target. Retain audit and ownership receipts; removing SecretStore/SA alone is not immediate OpenBao token revocation.
- keycape-client.py apply --operation remove for forgejo
- remove env KEYCAPE_FORGEJO_CLIENT_SECRET from Deployment sso/keycape, after register-client is reversed
- delete ExternalSecret sso/keycape-forgejo-client and its target
- covered by client-secret-path: one metadata delete, after deliver-secret is reversed
- identity-provisioner revoke_service_groups inside the provisioner pod (attended, as ensure-groups) with the case's memberships; delete_if_empty only if no other case uses forge-admins,forge-coulomb-owners,forge-coulomb-readers
- delete metadata and all versions at platform/workloads/keycape/forgejo, after the ExternalSecret is gone (this also reverses mint-secret)
- delete Kubernetes-auth role external-secrets-keycape-forgejo
- delete policy workload-kv-read-keycape-forgejo-eso, after eso-role
- Delete only this case-created role external-secrets-keycape-forgejo-forgejo, before deleting consumer-reader-policy; revoke case-issued OpenBao tokens or prove expiration before declaring deactivation.
- delete policy workload-kv-read-keycape-forgejo-forgejo
- remove catalog entry forgejo-keycape-client
5. Case acceptance (replaces the executive summary)
Not accepted yet. The case must carry its acceptance record before a build.