Commit graph

159 commits

Author SHA1 Message Date
ab5cccdcf3 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
2026-10-10 12:29:32 +02:00
213b98feb1 KEY-WP-0038-T04 cancelled: entry point moved to net-kingdom NK-WP-0048-T09
Remove the draft key-cape.oidc-client-registration declaration; net-kingdom
declares net-kingdom.keycape-client-registration beside the live deployment
machinery.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 23:03:58 +02:00
9fab7912f5 chore(consistency): record State Hub ID for KEY-WP-0038-T04
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 22:45:23 +02:00
c737e361ce Declare key-cape.oidc-client-registration; add KEY-WP-0038-T04 entry point
Playbook capability (contract PASS, maturity planned) composed by net-kingdom's
SecurityCaseType oidc-browser-relying-party. T04 implements tools/keycape-client,
generalizing the per-client rollout helpers.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 22:44:43 +02:00
d8f3668a18 KEY-WP-0038-T02: register Forgejo as the first KnownSecurityCase
No hand-built rollout; depends on net-kingdom NK-WP-0048-T06.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 22:17:03 +02:00
05e05aa945 KEY-WP-0038-T01 done: founder accepted the Forgejo client request
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 21:26:37 +02:00
custodian-sync
d11bf87c2b chore(consistency): renormalize lifecycle state [auto]
Updated by fix-consistency on 2026-10-08:
  - workplan status: ready → active

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 19:32:39 +02:00
73d97e3323 KEY-WP-0038-T01: draft the Forgejo OIDC client request packet
Non-secret claim contract for founder acceptance and railiance-apps agreement.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 19:32:00 +02:00
c4a8b75884 chore(consistency): refresh the work-record index
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 19:13:31 +02:00
ff6890788b Add KEY-WP-0038: Forgejo as a NetKingdom OIDC client
ORGREF-WP-0002-T04; founder-approved 2026-10-08. Counterpart: railiance-apps
RAPPS-WP-0016.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 19:12:09 +02:00
e0b5faea52 KEY-WP-0037-T04 done: live issuance verified for secrets-engine-openbao
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 132360@bnt-lap001
Assistant-Session: 769b1afd-4330-4c86-96b2-e510e26db42b
2026-10-07 02:26:03 +02:00
b2e1efcd0e KEY-WP-0037-T03 done: secrets-engine-openbao registered live
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 132360@bnt-lap001
Assistant-Session: 769b1afd-4330-4c86-96b2-e510e26db42b
2026-10-07 02:21:59 +02:00
e583988599 Link KEY-WP-0037-T03 to the in-bao custody design and approval decision
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 132360@bnt-lap001
Assistant-Session: 769b1afd-4330-4c86-96b2-e510e26db42b
2026-10-06 14:29:54 +02:00
457854fad5 Record prepared KEY-WP-0037-T03 dependencies and the corrected KV path
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 132360@bnt-lap001
Assistant-Session: 769b1afd-4330-4c86-96b2-e510e26db42b
2026-10-06 13:47:31 +02:00
5e431eccc5 Record the approved OpenBao custody boundary.
The founder resolved 632a8893 as the custody boundary only. T02 is done.
T03 waits on the still-open live registration decision caafe4be.

Assistant: grok
Assistant-Session: 01a10938-ab49-7280-877a-c06f64c06ddd
2026-10-05 09:30:49 +02:00
7e4c76998d Route the OpenBao custody approval to an open decision.
Assistant: grok
Assistant-Session: 01a10938-ab49-7280-877a-c06f64c06ddd
2026-10-05 02:39:36 +02:00
f485d6fe9c Record managed registration and custody work identities
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1046b-5629-7f52-badd-f718eadb6042
2026-10-04 11:17:19 +02:00
44cc067aa2 Name secrets-engine OpenBao registration and custody owner gates
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1046b-5629-7f52-badd-f718eadb6042
2026-10-04 11:15:44 +02:00
74064e1391 KEY-WP-0013: all tasks done, status blocked -> finished (CUST-WP-0074)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 101414@bnt-lap001
Assistant-Session: 60b5a221-d435-42b9-b778-983c90c7eed6
2026-09-30 12:49:13 +02:00
8be8065347 Send split-horizon origin headers on the discovery/JWKS fetch too
All checks were successful
Authentication acceptance / acceptance (push) Successful in 1m23s
Authentication acceptance / provider-contract (push) Successful in 15s
Build and Publish Container Image / build-and-push (push) Successful in 52s
setPublicOriginHeaders (key-cape@3b0446e) annotated only the token
exchange with X-Forwarded-Proto/Host so Authelia can derive the public
issuer in a split-horizon deployment. idTokenVerifier's separate
provider-metadata/JWKS fetch never got the same treatment, so an
in-cluster discovery request reached Authelia unmarked and Authelia
4.38 failed closed on it ("invalid X-Forwarded-Proto header value
'http'"), breaking every login regardless of client.

Extracted setPublicOriginHeaders to a package-level function and gave
idTokenVerifier the same resolved public base URL so its discovery/JWKS
requests carry the same headers as the token exchange.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 169987@bnt-lap001
Assistant-Session: 322ef1ef-9048-4021-8570-b6d6f6347999
2026-09-27 19:35:51 +02:00
da2543f47f chore(consistency): sync hub ids and work records [auto]
Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 169987@bnt-lap001
Assistant-Session: 322ef1ef-9048-4021-8570-b6d6f6347999
2026-09-27 19:17:09 +02:00
911e9de969 Don't backdate a fresh MFA to a stale kc_login cookie (INFD-IN-0005)
All checks were successful
Authentication acceptance / acceptance (push) Successful in 1m38s
Authentication acceptance / provider-contract (push) Successful in 17s
Build and Publish Container Image / build-and-push (push) Successful in 53s
completeAuthorization reused an existing kc_login session's IssuedAt as
authTime whenever one existed for the same user, even at the two call
sites that had just validated an MFA token in this exact request. A
platform-root sign-in that stepped up with fresh MFA while an older
browser session cookie was still around got that older timestamp
stamped onto the new authentication, understating freshness for every
downstream binding-grade check (flex-auth's 900s review window denied
informed-decision's infd-20260927-b01 approval as a result).

Add a freshMFA parameter so only the carried-forward-assurance call
site (no MFA challenge in this request) reuses the prior session's
IssuedAt; the two call sites following a successful
MFA.ValidateMFAToken always stamp authTime to now.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 169987@bnt-lap001
Assistant-Session: 322ef1ef-9048-4021-8570-b6d6f6347999
2026-09-27 19:03:06 +02:00
717a97408a Correct platform infrastructure client tenant bindings
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e324-abce-7e51-bb2b-496f097afdb0
2026-09-27 16:43:31 +02:00
f16559280c Record the completed fresh login and account switch.
Assistant: grok
Assistant-Session: 01a0d25d-d358-7e13-b84a-d007fbb7e34f
2026-09-25 01:49:42 +02:00
11ce29af8b Enforce login freshness in KeyCape instead of forwarding prompt=login (KEY-WP-0033).
All checks were successful
Authentication acceptance / acceptance (push) Successful in 1m27s
Authentication acceptance / provider-contract (push) Successful in 14s
Build and Publish Container Image / build-and-push (push) Successful in 52s
Authelia 4.38 refuses prompt=login for every real login because it registers
the authorization request after authentication. Send a bounded max_age
upstream and check the verified upstream auth_time against prompt=login /
max_age in the callback, failing closed when auth_time is missing.

Also update the service-client example count left stale by 651625c/1620ce2.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 352750@bnt-lap001
Assistant-Session: de41ef1c-2113-4dd2-9b92-f318ffa7f98b
2026-09-23 21:59:21 +02:00
f67d98ff63 Classify open workplans with flavor (CUST-WP-0072).
Set flavor on open workplans from origin/prose/status. Copy existing
depends_on aliases only. Do not promote residuals.

Assistant: grok
Assistant-Session: 01a09dc1-b21e-77e1-919e-fcad2f82b267
2026-09-14 15:50:43 +02:00
e17b3f4631 Record deployed P06 policy and completed platform acceptance
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
2026-09-14 00:10:25 +02:00
187c49abe5 Pin final P04 release and native ownership-lock evidence
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 21:30:50 +02:00
a10c2f7f98 Record completed P04 recovery rollout and acceptance
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 21:19:13 +02:00
4d893ed3c2 Verify factor identity again after recovery mutation
All checks were successful
Authentication acceptance / acceptance (push) Successful in 1m6s
Authentication acceptance / provider-contract (push) Successful in 12s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 17:30:23 +02:00
3b7df9047e Implement audited lost-factor recovery and track remaining P04 acceptance
All checks were successful
Authentication acceptance / acceptance (push) Successful in 58s
Authentication acceptance / provider-contract (push) Successful in 14s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 17:28:45 +02:00
502a2d5c56 Retain provider acceptance CI and synchronized assurance task binding
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 17:06:32 +02:00
ecca6cb4ba Record verified enrollment assurance release and automate provider contract tests
All checks were successful
Authentication acceptance / acceptance (push) Successful in 1m13s
Authentication acceptance / provider-contract (push) Successful in 28s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 17:03:44 +02:00
122a0d1369 Require confirmed enrollment and genuine OTP evidence for MFA
All checks were successful
Authentication acceptance / acceptance (push) Successful in 1m10s
Build and Publish Container Image / build-and-push (push) Successful in 41s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 16:37:08 +02:00
74b4f7f1bc Establish scoped KeyCape factor custody and verified automatic renewal
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 16:25:33 +02:00
78f5a718e9 Record provider credential renewal release and remaining owner handoff
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 14:27:35 +02:00
632b1f1376 Support provider credential renewal and reject unsuccessful OTP validation
All checks were successful
Authentication acceptance / acceptance (push) Successful in 1m10s
Build and Publish Container Image / build-and-push (push) Successful in 44s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 14:23:24 +02:00
85f5deaf4a Support opt-in MFA per browser client with authoritative enrollment checks
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 00:28:09 +02:00
ac8ed65203 Support opt-in MFA per browser client with authoritative enrollment checks
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 40s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 00:27:28 +02:00
e1e292919a Record generated State Hub recovery task bindings
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-12 17:10:41 +02:00
62a86a4ba0 Record live account recovery and browser sign-out verification
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-12 10:50:35 +02:00
074c2ce498 Add central login recovery and confirmed shared sign-out
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 44s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-12 10:34:41 +02:00
22788787c1 Record attended fresh-login rollout and verification
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-12 03:12:45 +02:00
0647301c03 Record published fresh-login image and attended rollout gate
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-12 02:53:55 +02:00
8d4336e944 Forward fresh-login requirements to the authentication provider
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 44s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-12 02:43:31 +02:00
139994cfac chore(consistency): register KEY-WP-0032 and refresh records [auto]
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV9oijZukGyGbRQGGKnK4P

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713576@bnt-lap001
Assistant-Session: 384c511d-9bce-4cb8-a676-2aef6c0c8df6
2026-09-10 23:07:49 +02:00
f247d3529d Close T04 and pin the single route by which a principal becomes human
KEY-WP-0014-T04 sat `wait` with nothing outstanding, which is a contradiction.
Its title is admit rotation and verify consumer handoff, and both are delivered:
the semantics are published, the executor, authority and transport are named, the
CCR will be prepared on request, and step 4 shipped as keycape verify-client;
ops-warden took option (a) for the reason given, with both lanes owner-confirmed
and no route changed. Executing a rotation was never its deliverable, so treating
the owner's deferral as an open item would have kept the task open against work
it was not scoped to do. The deferral stands separately, revisited on evidence.

GH-DEC-2026-016 §5 applies A-16 to what makes a principal human. Verified against
source that `human` has exactly one route here -- a literal on the
authorization-code path after an upstream login resolved to a directory user,
with no configuration able to assert it -- so A-16 does not yet bite and no
provenance claim is warranted. Adding one would encode a distinction that does
not exist.

Asserting the behaviour would not protect that: a test checking a human token
says human passes just as happily when the value starts coming from a
registration. The guard parses the package and requires every principal_type
assignment to be a string literal, the set being exactly human and service. It
covers both shapes -- the browser path assigns into a map, the service path uses
a key-value pair in a map literal -- and checking only assignments found one of
two routes and passed, which the pinned literal set caught. Verified by mutation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV9oijZukGyGbRQGGKnK4P

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713576@bnt-lap001
Assistant-Session: 384c511d-9bce-4cb8-a676-2aef6c0c8df6
2026-09-10 23:05:16 +02:00
c9bb7fac58 Register the approver client now its callback exists
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 47s
informed-decision submitted client_id informed-decision-approver and redirect
https://decisions.coulomb.social/auth/callback, with the origin already live and
verified by them rather than reported: both / and /auth/callback return 200 on a
Let's Encrypt certificate valid to 2026-12-09. The host is decisions, not the
decide of an earlier draft. Its path serves a placeholder for now, which does not
matter -- the redirect is matched as an exact string and never fetched.

Published as a public authorization_code client with S256 PKCE, audience
approval-engine, scopes openid/approval:read/approval:approve, mfaRequired true
and a declared tenant:platform. No secretRef, since PKCE is the whole proof.

TestApproverRegistrationShapeIsExact pins every field, so widening a scope or
relaxing MFA fails the build rather than reading as an edit, and asserts the
registration passes startup validation -- proving the KEY-WP-0028 tenant
exemption holds for the registration that actually depends on it.

Two existing guards fired on the way in and neither was loosened. The tenant pin
refused an unreviewed client carrying a tenant, which is its purpose, so the
approver was added to its reviewed set deliberately. And the audience test
panicked slicing secretRef[4:], an assumption that held while the fixture had
only confidential clients; the approver is the first public one, so the loop now
guards on the env: prefix.

The declared tenant reaches the token by the GH-DEC-2026-013 gap route by
construction, and tenant_source says so: registration, never directory.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV9oijZukGyGbRQGGKnK4P

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713576@bnt-lap001
Assistant-Session: 384c511d-9bce-4cb8-a676-2aef6c0c8df6
2026-09-10 22:50:13 +02:00
324b5e056d Record the owner decision: Qonto rotation deferred, not refused
The repository owner declined to schedule the rotation now. Recorded with the
reasoning rather than as a bare status so it is revisited on evidence instead of
re-litigated: nothing indicates compromise, the offer stands open, and one
founder-attended window is already pending for the fail-closed startup changes.

Names what should reopen it -- an actual or suspected exposure, the secret's age
becoming a stated concern, a consumer requiring proof of rotation, or a decision
to prove rotation step 4 before relying on it -- and says plainly that a calendar
date is not one of them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV8zoCKpA1WRAxsKRYbdH

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1182213@bnt-lap001
Assistant-Session: 966597b9-ae61-46a4-8b9e-1594ab3ec4ad
2026-09-10 09:15:48 +02:00
ed67780da8 Record the rotation authority answer and why it was not scheduled
The Qonto rotation blocker is narrowed from an open question to a schedulable
act: railiance-platform named the executor, transport and authority, and will
prepare the CCR if KeyCape asks. Not asked -- requesting a production credential
rotation with a restart window is the operator's decision, so it was put to him.

Established first that this rotation has no incident driver. The 2026-08-23
exposure covered credentials embedded in config.yaml and the signing key; the
rapp-qonto secret is an env: secretRef in a separate Secret and was not in that
payload. Lifecycle hygiene, not remediation -- which changes what a reasonable
window looks like, and means nobody should be carrying it as leftover incident
work.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV9oijZukGyGbRQGGKnK4P

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713576@bnt-lap001
Assistant-Session: 384c511d-9bce-4cb8-a676-2aef6c0c8df6
2026-09-10 08:10:34 +02:00