Fix case render self-lifecycle stanzas; record overnight replies

case_build: policies carry lookup-self/revoke-self when the CCR declares
token_self_lifecycle (CCR-2026-0041 review); Forgejo bundle updated.
WP-0004: six descriptions completed from owner replies (draft, awaiting
acceptance). WP-0009-T05: login proof passed. WP-0010-T03: CCR-2026-0041
applied. WP-0005-T06: ops-warden catalogued the entry as draft.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 327203@bnt-lap001
Assistant-Session: 55028ae3-4914-4bd1-8f5c-815f3527aef0
This commit is contained in:
tegwick 2026-10-10 12:41:20 +02:00
parent ae403c8402
commit c9b1cea83b
10 changed files with 120 additions and 39 deletions

View file

@ -4,8 +4,8 @@
"catalog-proposal.yaml": "8bb3faedca22c7fa995e26978a0f040def032882fb9072b3a818cd40d5ff3818",
"credential-change-requests/CCR-DRAFT-FORGEJO-NETKINGDOM-OIDC-ESO.yaml": "50940969383a9c7a6a8a3c2d03a0aa6fbed574a12139072b5388402651550b3e",
"credential-change-requests/CCR-DRAFT-FORGEJO-NETKINGDOM-OIDC-FORGEJO.yaml": "691423c684da31d4611b15adb601f622f89c9cd465b55c637aed0836bb9ac9c8",
"openbao/policies/workload-kv-read-keycape-forgejo-eso.hcl": "92fa2aa74b6d4254b7b15dd7f376566afdafe5bcfbc9546fa9bccdf8d2214ab8",
"openbao/policies/workload-kv-read-keycape-forgejo-forgejo.hcl": "690aa95a2ecd7eb906de87af20e3c0905854e14e864a24f4241216afa4bc9c45",
"openbao/policies/workload-kv-read-keycape-forgejo-eso.hcl": "a25095bba974a6d63674765330abf9bc0dd719c27b446c22d95e79bb21b9631e",
"openbao/policies/workload-kv-read-keycape-forgejo-forgejo.hcl": "1abeb50d99e850e3ea8d8d860216520fb73f4c26c12b551587dc4c95ce754950",
"rollback.yaml": "b8bc1a3c99507183733a246d415fa5508e0f45590e9517d5a70e48ae73206fc9"
},
"kv_path": "platform/workloads/keycape/forgejo",
@ -14,6 +14,7 @@
"catalog activation (ops-warden)",
"client registration (net-kingdom, attended)"
],
"note": "2026-10-10: policy files updated with the token self-lifecycle stanzas (render defect found in CCR-2026-0041 review); filed as CCR-2026-0041/0042.",
"security_case": {
"acceptance_record": "key-cape docs/forgejo-oidc-client-request.yaml (status accepted-2026-10-08, KEY-WP-0038-T01); type acknowledged via informed-decision memo nk-wp-0048-t05-oidc-browser-relying-party-r4, hub decision e418263e",
"accepted_at": "2026-10-08",

View file

@ -4,3 +4,12 @@
path "platform/data/workloads/keycape/forgejo" {
capabilities = ["read"]
}
# ESO validates its own short-lived workload session.
path "auth/token/lookup-self" {
capabilities = ["read"]
}
path "auth/token/revoke-self" {
capabilities = ["update"]
}

View file

@ -4,3 +4,12 @@
path "platform/data/workloads/keycape/forgejo" {
capabilities = ["read"]
}
# ESO validates its own short-lived workload session.
path "auth/token/lookup-self" {
capabilities = ["read"]
}
path "auth/token/revoke-self" {
capabilities = ["update"]
}

View file

@ -12,18 +12,19 @@ operators/nextcloud:
sources: []
used_by: ''
operators/nextcloud/backup:
description: ''
missing:
- description
- used_by
- rotation
- on_loss
on_loss: ''
description: Operator login (BACKUP_USERNAME, BACKUP_PASSWORD) for the dedicated Nextcloud Storage Share
account Backup on nx4069.your-storageshare.de, the independent secondary backup copy lane.
missing: []
on_loss: Resettable by the founder in the Storage Share provider admin (attended). If the share is recreated,
update the workload lane's NC_WEBDAV_TOKEN. Stored backups are unaffected.
owner: railiance-platform
review: draft
rotation: ''
sources: []
used_by: ''
rotation: railiance-platform/docs/backup-credential-recovery.md; railiance-platform/credential-change-requests/CCR-2026-0004-railiance-backup-offsite-lane.yaml
sources:
- railiance-platform reply 3e490cd4 (2026-10-09)
used_by: Attended operator only, to manage the account and its create-only /railiance-backups share.
Never delivered to production; workloads get only the derived NC_WEBDAV_TOKEN/NC_WEBDAV_URL via the
workload lane.
platform/workloads/activity-core/llm-connect/llm-connect-provider-secrets:
description: llm-connect provider access through OpenBao workload KV and External Secrets
missing: []
@ -64,8 +65,7 @@ platform/workloads/activity-core/ops-run-workers/rein-aharness-railiance01:
actcore-runtime-secret in namespace activity-core.
platform/workloads/agent-harness/forgejo-deploy-key:
description: agent-harness Forgejo deploy key (write sandbox; binky-control at cutover)
missing:
- used_by
missing: []
on_loss: 're-establish by railiance-platform: On railiance01 generate a new ed25519 keypair under ~/.local/agent-harness/ssh/
(mode 600); do not paste the private key into chat or Git.'
owner: railiance-platform
@ -73,7 +73,10 @@ platform/workloads/agent-harness/forgejo-deploy-key:
rotation: ops-warden/wiki/playbooks/agent-harness-secrets.md#lane-2-forgejo-deploy-key
sources:
- ops-warden catalog agent-harness-forgejo-deploy
used_by: ''
- railiance-platform reply 3e490cd4 (2026-10-09)
used_by: agent-harness worker on railiance01 (private key at ~/.local/agent-harness/ssh/forgejo-deploy);
this OpenBao copy is the recovery copy, via ops-warden agent-harness-forgejo-deploy (policy workload-kv-read-agent-harness-forgejo).
Deploy key on coulomb/executor-sandbox (write).
platform/workloads/approval-engine/audit-sender:
description: Provide only the approval-engine sender with source=approval-engine, tenants=[tenant:platform],
may_write=true, may_read=false, evidence_kind=load-bearing, secret_policy=redact.
@ -169,8 +172,7 @@ platform/workloads/coulomb-social/backup-primary:
used_by: /etc/coulomb-social-backup/primary.env
platform/workloads/coulomb/whynot-design/npm-publish:
description: npm package publishing through ops-warden caller-scoped fetch/exec
missing:
- used_by
missing: []
on_loss: 'Re-issue per rotation: Replace NPM_AUTH_TOKEN value directly in OpenBao and record non-secret
rotation evidence.'
owner: railiance-platform
@ -179,7 +181,9 @@ platform/workloads/coulomb/whynot-design/npm-publish:
sources:
- CCR-2026-0001-whynot-design-npm-publish.yaml
- ops-warden catalog whynot-design-npm-publish
used_by: ''
- railiance-platform reply 3e490cd4 (2026-10-09)
used_by: Attended whynot-design npm publishing via ops-warden whynot-design-npm-publish (warden access
... --exec -- npm publish), OIDC role whynot-design-workload-kv-read on auth/netkingdom. Field NPM_AUTH_TOKEN.
platform/workloads/email-connect/backup-primary:
description: Read this application backup publisher key pair into the admitted node delivery process;
no other workload credential or escrow.
@ -367,16 +371,18 @@ platform/workloads/railiance-clock/authority-signing:
used_by: /var/lib/railiance-clock/signing.pem
platform/workloads/railiance-telemetry/smtp:
description: Native password-reset notifier; password mounted read-only under /run/secrets/authelia-smtp/password.
missing:
- used_by
- on_loss
on_loss: ''
missing: []
on_loss: 'Resettable by the founder in IONOS mail admin; write a new KV version keeping the other fields,
wait for ESO refresh. Cost: alert mail and Authelia reset emails fail until then; no data loss.'
owner: railiance-platform
review: draft
rotation: railiance-platform/credential-change-requests/CCR-2026-0035-authelia-platform-smtp.yaml#lifecycle.rotate
sources:
- CCR-2026-0035-authelia-platform-smtp.yaml
used_by: ''
- railiance-platform reply 3e490cd4 (2026-10-09)
used_by: railiance-telemetry alert mail (ESO telemetry-smtp-eso -> Secret telemetry/telemetry-alert-smtp,
SMTP_PASSWORD only) and the Authelia password-reset notifier (CCR-2026-0035, /run/secrets/authelia-smtp/password).
Mailbox platform@coulomb.social at IONOS.
platform/workloads/railiance/backup/object-storage:
description: Object-store credentials for Railiance backup destinations.
missing: []
@ -418,8 +424,7 @@ platform/workloads/railiance/scaleway/bootstrap:
used_by: reef-storage/tools/create-platform-audit-bucket.sh (reads, never prints)
platform/workloads/rapp-qonto/keycape-client:
description: rapp-qonto KeyCape workload client
missing:
- used_by
missing: []
on_loss: 'rotate by key-cape: Generate a fresh newline-free secret through an approved execution transport;
never print it. NOT automatable — no admitted execution and rollback contract (see delegation.blocked_on).'
owner: key-cape
@ -427,7 +432,10 @@ platform/workloads/rapp-qonto/keycape-client:
rotation: ops-warden/wiki/CredentialRouting.md#routing-catalog-index
sources:
- ops-warden catalog rapp-qonto-keycape-client
used_by: ''
- key-cape reply 40395cc2 (2026-10-10)
used_by: (1) KeyCape via ESO -> Secret sso/keycape-rapp-qonto-client key client-secret, to verify client_credentials
for rapp-qonto-client. (2) The rapp-qonto runtime, presenting it to keycape service-token; its delivery
transport is for railiance-apps/rapp-qonto to name.
platform/workloads/reuse/reuse-surface/runtime-secrets:
description: reuse-surface federation hub runtime secrets through OpenBao workload KV and External Secrets
missing: []
@ -490,18 +498,19 @@ platform/workloads/state-hub/repository-rename-preflight:
used_by: Namespace SecretStore openbao-state-hub-rename-preflight -> ExternalSecret/Secret state-hub-rename-preflight;
required explicit API-only secretKeyRef. Owner creation, Retain deletion policy.
platform/workloads/telemetry/grafana-admin:
description: ''
missing:
- description
- used_by
- rotation
- on_loss
on_loss: ''
description: Grafana native administrator for rapp-telemetry on railiance01 (ADMIN_USERNAME, ADMIN_PASSWORD),
the attended bootstrap credential.
missing: []
on_loss: 'Resettable by a cluster operator with Grafana''s admin reset in the pod, then a new KV version
(not yet exercised). Cost: short loss of admin access; dashboards and data unaffected.'
owner: railiance-platform
review: draft
rotation: ''
sources: []
used_by: ''
rotation: 'railiance-platform/docs/credential-lane-designs/telemetry-grafana.md (attended: change the
Grafana DB admin password and OpenBao together, then test old fails and new works)'
sources:
- railiance-platform reply 3e490cd4 (2026-10-09)
used_by: Grafana in namespace telemetry via ExternalSecret telemetry-grafana-admin (ESO SA/role telemetry-grafana-eso,
policy telemetry-grafana-admin-eso), plus the attended check scripts/telemetry_grafana_access.py.
platform/workloads/tenant-engine/audit-core-sender:
description: tenant-engine's audit-core sender token, a copy of its entry in the audit-core sender registry.
Not the registry itself.

View file

@ -123,10 +123,24 @@ def _ccr(case: dict, rendered: dict, policy: dict, role: dict | None, kv_path: s
return doc
# The CCR drafts set token_self_lifecycle: true, so the platform applier generates
# these two stanzas and refuses a policy file without them (CCR-2026-0041 review).
_SELF_LIFECYCLE = """
# ESO validates its own short-lived workload session.
path "auth/token/lookup-self" {
capabilities = ["read"]
}
path "auth/token/revoke-self" {
capabilities = ["update"]
}
"""
def _policy_hcl(policy: dict, prov: dict) -> str:
head = (f"# {policy['template']}: rendered by ops-mason from SecurityCase {prov['case']} "
f"({prov['type']}, render {prov['render_digest']}).\n# Do not edit: re-run ops-mason build --case.\n\n")
return head + policy["body"].rstrip() + "\n"
return head + policy["body"].rstrip() + "\n" + _SELF_LIFECYCLE
def validate_with_platform(ccr_paths: list[Path], platform: Path = RAILIANCE_PLATFORM) -> list[str]:

View file

@ -55,6 +55,10 @@ def test_builds_bundle_naming_case_type_and_acceptance(tmp_path, types_root):
assert doc["security_case"]["acceptance_record"] and "case acceptance replaces" in doc["requester"]["reason"]
hcl = (out / "openbao/policies/workload-kv-read-keycape-forgejo-eso.hcl").read_text()
assert 'path "platform/data/workloads/keycape/forgejo"' in hcl and '["read"]' in hcl and "forgejo-netkingdom-oidc" in hcl
# token_self_lifecycle: true needs the self stanzas, or the platform applier refuses the file.
assert 'path "auth/token/lookup-self"' in hcl and 'path "auth/token/revoke-self"' in hcl
stanzas = [l for l in hcl.splitlines() if l.startswith("path ")]
assert len(stanzas) == 3
rollback = yaml.safe_load((out / "rollback.yaml").read_text())
assert rollback["removes_exactly"][-1] == {"kind": "kv_path", "name": "platform/workloads/keycape/forgejo"}
assert rollback["removes_exactly"][0]["kind"] == "catalog_entry"

View file

@ -178,6 +178,17 @@ stays a draft until that exists. railiance-platform retired the duplicate
`activity-core/default/llm-connect-provider-secrets` (message `af873813`), and
the four `infotech` fluid-telegram entries were moved to `coulomb`.
2026-10-10: answers filled into the manifest (still `review: draft`, awaiting
founder acceptance and an apply run): railiance-platform (message `3e490cd4`)
completed `operators/nextcloud/backup`, `railiance-telemetry/smtp`,
`telemetry/grafana-admin`, `agent-harness/forgejo-deploy-key` and
`whynot-design/npm-publish`; key-cape (message `40395cc2`) named the two readers
of `rapp-qonto/keycape-client` (the rapp-qonto runtime's transport is for
railiance-apps to name). Still open: `operators/nextcloud` (railiance-platform
is asking the founder what it holds), `keycape-factor-issuer` rotation
(railiance-platform gap) and `user-engine/runtime` on_loss (ops-mason, after
its rotation rehearsal).
## Make an undescribed path visible before it accumulates
```task

View file

@ -293,6 +293,11 @@ role.
`applied-pending-verify` (message `856bd6ba`); activation stays with
ops-warden after T05.
2026-10-10: ops-warden catalogued it (`23ba584`, message `b73aa5f0`) as
`fluid-telegram-operator`, pointer-only, status `draft` (its catalog has no
applied-pending-verify), with playbook `wiki/playbooks/fluid-telegram-operator.md`.
It activates on the member receipt and the FT-WP-0002 salt probe.
## Loose-end review — 2026-09-28
T01–T06 remain wait: accepted tenant/matrix, confirmed identity/MFA/callbacks, approved matching writer contracts, live survey, explicit construction approval and verification are outstanding. The platform design remains proposed. No lane was built or activated.

View file

@ -127,8 +127,8 @@ exist yet" whenever `bao policy read` failed, including when the founder's
```task
id: MASON-WP-0009-T05
status: wait
blocked_on: message-from:secrets-engine
blocking_reason: "CCR-2026-0038 applied by the founder 2026-10-08T22:42Z (readback matched). Waits on the login proof with a real KeyCape service JWT (SECRETS-WP-0012-T03 probe-openbao); then ops-mason checks 1-3 and 6 and invariant (ii) (deny on both guarded paths) and proposes the pointer-only route."
blocked_on: human
blocking_reason: "Check 6 passed 2026-10-10 (secrets-engine probe-openbao). Remaining: invariant (ii) and the policy/role checks under a survey grant; operator/ESO capability checks and non-member refusal are owner-run; then propose the pointer-only route."
priority: medium
state_hub_task_id: "1b1a0566-add7-59c1-94b0-6bb81d2d1537"
```
@ -152,3 +152,9 @@ on the founder's approve, confirm-binding and delegated apply.
approval, binding confirmation and delegated apply at 2026-10-08T22:42Z, with a
matching value-free readback (evidence in the CCR). RPF-WP-0035-T02 now waits
only on the login proof (SECRETS-WP-0012-T03).
2026-10-10: check 6 passed. The founder ran `secrets-engine service-auth
probe-openbao`: ok, auth provider service-jwt, secret source
openbao-oidc-in-memory, both revoke-self true (secrets-engine evidence
`docs/evidence/2026-10-10-keycape-openbao-probe.json`, `a963a77`; message
`6ed92390`). SECRETS-WP-0012 is finished.

View file

@ -189,3 +189,16 @@ state_hub_task_id: "f6ad0d3c-8f47-5fdf-8115-6ca9d8a1fead"
Once `oidc-browser-relying-party` (or the confidential service client type) is
implemented, express MASON-WP-0009's placement as a case of that type without
changing the live structure, and close the hand-built path.
2026-10-10 (T03): railiance-platform filed the drafts as CCR-2026-0041 (ESO
reader) and CCR-2026-0042 (consumer reader, in_flight until railiance-apps binds
it), messages `83465dcd`/`be3a762d`; the founder applied CCR-2026-0041 at
2026-10-09T18:09Z. Its review found a render defect: the CCRs declare
`token_self_lifecycle: true` but the policies lacked the lookup-self/revoke-self
stanzas, so the applier refused them. Fixed in `case_build.py` (test asserts
the three stanzas; output now equals the platform-generated policy apart from
comments) and in the committed bundle. Two follow-ups for the next render:
net-kingdom changed the type to `KEYCAPE_{client_id:env}_CLIENT_SECRET`
(ops-warden `23ba584`), so the render digest will change; and a live re-render
of a partly applied case will report its own objects as collisions. The KV
value waits on mint-secret (RPF-WP-0054).