KEY-WP-0038: Forgejo custody path derived by case type; propose KEY-WP-0039 negative-probe tokens
Forgejo's secret now lives at platform/workloads/keycape/forgejo, as derived by oidc-browser-relying-party 1.0 (net-kingdom 074b3a0). KEY-WP-0039 answers railiance-platform's CCR-2026-0038 question with one-mismatch probe registrations instead of an issuer path that could mint arbitrary claims. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 779409@bnt-lap001 Assistant-Session: c658ca06-19b5-468d-be64-2985dc20bfd3
This commit is contained in:
parent
f8ef4d418c
commit
ab5cccdcf3
4 changed files with 103 additions and 4 deletions
|
|
@ -9,7 +9,7 @@ flavor: implementation
|
|||
owner: claude-code
|
||||
topic_slug: railiance
|
||||
created: "2026-10-08"
|
||||
updated: "2026-10-08"
|
||||
updated: "2026-10-10"
|
||||
depends_on: []
|
||||
related_repos:
|
||||
- prj-forgejo-org-refactor
|
||||
|
|
@ -111,8 +111,9 @@ 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
|
||||
(proposed OpenBao path `platform/workloads/forgejo/netkingdom-oidc-client`,
|
||||
custody owner railiance-platform, consumer Forgejo). Record a receipt with no
|
||||
(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
|
||||
|
|
|
|||
92
workplans/KEY-WP-0039-openbao-negative-probe-tokens.md
Normal file
92
workplans/KEY-WP-0039-openbao-negative-probe-tokens.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
---
|
||||
id: KEY-WP-0039
|
||||
type: workplan
|
||||
title: "Negative-check tokens for the secrets-engine OpenBao JWT role"
|
||||
domain: infotech
|
||||
repo: key-cape
|
||||
status: proposed
|
||||
flavor: implementation
|
||||
owner: claude-code
|
||||
topic_slug: netkingdom
|
||||
created: "2026-10-10"
|
||||
updated: "2026-10-10"
|
||||
depends_on: []
|
||||
related_repos:
|
||||
- railiance-platform
|
||||
- secrets-engine
|
||||
---
|
||||
|
||||
# KEY-WP-0039 - Negative-check tokens for the secrets-engine OpenBao JWT role
|
||||
|
||||
## Why
|
||||
|
||||
CCR-2026-0038 (railiance-platform RPF-WP-0035-T02) requires the OpenBao role
|
||||
`secrets-engine-openbao` on `auth/keycape-services` to refuse JWTs with a wrong
|
||||
`aud`, `sub`, `tenant`, `principal_type`, `roles` or `scope`, a coding-agent JWT
|
||||
and an expired JWT. The positive login proof passed on 2026-10-10 (secrets-engine
|
||||
`docs/evidence/2026-10-10-keycape-openbao-probe.json`). railiance-platform asked
|
||||
whether KeyCape can issue the negative tokens without touching the
|
||||
`secrets-engine` registration.
|
||||
|
||||
KeyCape signs only what a registration declares. It has no way to mint a token
|
||||
with arbitrary claims, and adding one would create a forging path in the issuer.
|
||||
So the negative tokens must come from real, separate registrations that differ
|
||||
from `secrets-engine` in exactly one property each.
|
||||
|
||||
## Boundaries
|
||||
|
||||
- The `secrets-engine` registration is not changed.
|
||||
- Probe clients are confidential `client_credentials` clients with the minimum
|
||||
60-second lifetime, scopes that grant nothing, and secrets minted into custody
|
||||
like any other client. They are removed after the proof.
|
||||
- The probe script prints only accept or refuse booleans per case, never tokens or
|
||||
secrets. It runs attended.
|
||||
|
||||
## Tasks
|
||||
|
||||
```task
|
||||
id: KEY-WP-0039-T01
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
### T01 — Define the probe registrations
|
||||
|
||||
Write a non-secret request packet under `docs/` with one probe client per claim
|
||||
mismatch, each identical to `secrets-engine` except for:
|
||||
|
||||
- `aud`: a different access-token resource audience
|
||||
- `sub`: a different service subject
|
||||
- `tenant`: a tenant other than `platform`
|
||||
- `roles`: a role other than `secrets-engine`
|
||||
- `scope`: a scope outside the role's bound scope
|
||||
|
||||
Two cases need no probe client. A service token always carries
|
||||
`principal_type: service` (`src/internal/server/oidc/token.go`), so the wrong
|
||||
`principal_type` case uses a human access token from an attended login. The
|
||||
coding-agent case uses the existing `codex-railiance-platform` registration (role
|
||||
`coding-agent`, `docs/openbao-service-auth-contract.md`) if it is registered live;
|
||||
T01 confirms that.
|
||||
|
||||
The expired-JWT case reuses any probe client: request a token, wait past its
|
||||
60-second lifetime, then present it.
|
||||
|
||||
Acceptance: railiance-platform agrees the packet covers every refusal that
|
||||
CCR-2026-0038 names.
|
||||
|
||||
```task
|
||||
id: KEY-WP-0039-T02
|
||||
status: wait
|
||||
depends_on: [KEY-WP-0039-T01]
|
||||
blocking_reason: "Live registration and custody need owner authorization."
|
||||
priority: medium
|
||||
```
|
||||
|
||||
### T02 — Register the probe clients, run the attended probe, then remove them
|
||||
|
||||
Write the attended script, which prints booleans only. Register the clients
|
||||
through the normal registration path, hand the run to railiance-platform, record
|
||||
a value-free receipt in `docs/evidence/`, and deregister the clients afterwards.
|
||||
|
||||
Acceptance: every case is refused, the receipt is committed, and the probe clients
|
||||
are gone.
|
||||
Loading…
Add table
Add a link
Reference in a new issue