flex-auth's flex-auth-ops-warden pin (FLEX-WP-0016) TokenReviews the caller and
binds resource.system: ops-warden to system:serviceaccount:ops-warden:ops-warden.
policy.py posted /v1/check with no Authorization header, so the pin logs
"caller authentication warning" and can only run callerAuth.mode: warn — which,
under ADHOC-2026-08-17-T01, is exactly what blocks policy.enabled: true.
- policy.caller_auth (none | file | env | command) + src/warden/caller_identity.py:
token resolved per call, never cached, written, or logged (ADR-0002)
- both check_sign_policy and check_fetch_policy attach the bearer header; an
unobtainable token fails closed rather than retrying anonymously
- scripts/check_policy_caller_identity.py: read-only gate, prints length and a
truncated fingerprint only, distinguishes 401 (audience/binding) from 403
- example config: caller_auth block, and flex_auth_url corrected — it pointed at
flex-auth.flex-auth.svc, a Service that does not exist
- WARDEN-WP-0031, PolicyGatedSigning caller-identity section and flip sequence
Default stays mode: none, so behaviour is unchanged until an operator opts in.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Inbox triage (ADHOC-2026-08-17), three messages, all answered and marked read.
flex-auth (FLEX-WP-0015 T02) reported that /v1/check and /v1/batch_check
authenticate no caller — any workload with cluster reach can assert any subject
and get an authoritative allow. It lands here because ops-warden owns workload
identity in this estate and its pre-sign gate is a flex-auth PEP.
Recommendation recorded in wiki/NetKingdomSecurityMap.md: Kubernetes
ServiceAccount TokenReview with a projected, audience-scoped token. Rejected the
shared-secret header — it manufactures a risk: high lane with a rotation owner
per caller on the authorization path, the exact interim-proxy debt WP-0030
exists to stop growing. Deferred mTLS pending an owner for a workload X.509 CA.
Bind `system` to the authenticated SA at auth time, but keep the resource-type
allowlist in the policy package rather than the admission layer. Warn-only
rollout; policy.enabled must not flip while /v1/check answers unauthenticated
callers. Recorded as a pattern, not a catalog entry.
Catalog delegation refreshes:
- coulomb-social-runtime-env: USER_ENGINE_PROXY_SECRET ownership settled
(decision 8fe22037, USER-WP-0021) — intended_owner stays railiance-apps,
answered clause dropped from blocked_on, consumers: [user-engine] recorded.
- rapp-qonto-keycape-client: blocked_on no longer implies an in-flight
KEY-WP-0008 dependency; the key-cape-native exchange command is unopened work.
uv run pytest -q → 338 passed, 4 deselected.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every execution position is now explicit. Catalog entries carry
delegation.mode (permanent / native / interim) with intended owner and
blocker. warden route gaps lists the interim set. Promotion requires
the ownership question. Doctrine lives in AccessRouting.md; the
register was published to the named owner repos.
Revised the classification axis after inspecting the entries: sorting by
subsystem was wrong. Nine of eleven lanes are a generic KV read with the
caller's own token, duplicating no owner procedure. Test is now
procedure-or-lifecycle vs generic read.
Interim now: rapp-qonto-keycape-client (key-cape), binky-company-email-imap
and binky-qonto-api (tenant-engine), railiance-backup-offsite-lane and
agent-harness-forgejo-deploy (re-establish procedures).
Held: the six thin-wrapper lanes are permanent only if secrets-engine exec
stays per-lane; asked whether it generalizes (msg 7d55d332).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Founder decision 2026-08-11: neither withdraw nor proceed. The broker covers
the workstation, but unattended signing on a remote tunnel host is unresolved,
and there the AppRole is narrower than placing the broker's issuer token.
Recorded where each trigger will be hit: WP-0027 break-glass task (trust-root
design), and the ops-bridge cutover playbook (token source must be resolved
before going live). secrets-engine told to stop holding apply readiness.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Founder directive: ops-warden works with, never replaces or duplicates,
secrets-engine / tenant-engine / user-engine. Covering an unfilled gap is
acceptable only as a tracked interim with a named intended owner.
- INTENT §9 "Cover gaps, but never silently own them"; success criterion 7;
tenant-engine and user-engine added to the literacy table; non-goal on
permanently owning another component's lane
- WP-0030 (proposed): delegation: metadata, backfill, warden route gaps,
promotion gate, publish the register to owner repos
- history/2026-08-11-delegation-surface-assessment.md: 2 of 24 lanes carry
exec_owner; 11 proxies record no intended owner
- SCOPE refreshed to 2026-08-11 (was 6 workplans behind); completeness C5 -> C4
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Answers owed were sent and all 11 marked read: railiance-platform front-door
thread confirmed closed (both lanes active, selector is openrouter-llm-connect),
railiance01/activity-core and llm-connect requests superseded, secrets-engine
warden-sign referred back to the operator.
Leaves T03 open: whether to keep or withdraw the warden-sign AppRole now that
the credential broker serves the VAULT_TOKEN lane.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The catalog pointed at wiki/CredentialRouting.md#credential-routing-catalog,
which does not exist; the live heading is "Routing catalog index". Restores
tests/test_routing.py to 61/61.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ship posture-aware access planning: organization_posture=build (axis C),
catalog freshness warnings, warden plan verdicts, localhost founder desk,
and playbook/agent guidance that retire /tmp file-drop patterns.
Compose route catalog + handoff rather than a second routing layer.
Founder directive 2026-07-18: agents ask ops-warden what a credential
need requires; the founder is escalated to only for policy-required
decisions/identity acts, preferably via a local web interaction surface
— never tasked with raw mechanics (UI clicks, /tmp file drops).
Organization posture 'build' becomes declared configuration. Workplan:
warden plan front door, posture declaration, warden desk, file-drop
retirement, catalog freshness + agent guidance.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
C-23 forces active when tasks are wait/progress; C-15 preferred wait over
todo. Park Strand B as backlog and cancel T01–T03 until an activation gate
fires (then re-open as todo).
- warden/mask.py: fingerprint()/mask_value() — presence, length, 8-char sha256
prefix; never the value.
- proxy.proxy_fetch_fingerprint + `warden access --fingerprint`: masked status view
(presence/length/hash) that emits no value, so it bypasses the T02 stdout guard.
Lets two parties compare sha256 prefixes to confirm a shared value without seeing
it (e.g. rotation landed).
- documented as defense-in-depth (raw bao bypasses it) in OperatorAccessAssist.md
and the module docstring.
- tests: tests/test_mask.py + CLI fingerprint test. 299 pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
T01 (done): canonical capabilities-based verify pattern in the fleet promotion
checklist (catalog-lane-promotion.md) and applied to the railiance-backup and
forgejo-admin lane playbooks. Verification proves allow/deny via
`bao token capabilities` against the KV v2 data path, never `bao kv get`; a denied
default-policy token-create is a pass, not a privileged-fallback trigger.
T07 (progress): lessons-learned note for the 2026-07-16 CCR-2026-0004 disclosure
(three root causes). Live re-verify + rotation block remain (depend on T06).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Captures the heavyweight governance work deliberately deferred from WP-0026
(Strand A): executable mass rotation, graded lockdown/break-glass with a
designed trust-root, and tamper-evident policy governance + reconcile.
Status backlog with an explicit activation gate — captured, not scheduled;
implemented only when the gate is met and promoted to ready.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Follow-up to the 2026-07-16 CCR-2026-0004 verify disclosure incident. Strand A:
capabilities-based verification, safe access transport, masking (defense-in-depth),
agent read-boundary, EXPOSED taint convention, and a structured-but-advisory
rotation/re-establishment guidance registry surfaced via warden. Strand B deferred.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Notified the-custodian (949e8ed1) + railiance-platform (5be8e500) /
activity-core (9ed1af98) / railiance-apps (2e47b6e5) that the
forgejo-admin-api-token OpenBao lane is active. No secret values shared.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PAT attended-minted and stored at platform/workloads/forgejo/forgejo-admin
under field API_TOKEN (re-stored from initial Token field to match
CCR/catalog/playbook fetch_command). Positive fetch verified: PAT valid
against forgejo.coulomb.social (/api/v1/user -> login=tegwick, is_admin=true).
- catalog: draft -> active, resolvable: true, verification evidence, reviewed 2026-07-13
- playbook: header active/resolvable, drop post-promotion caveat
- workplan: T04 done
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Draft routing entry and worker playbook for Forgejo site-admin PAT custody
in OpenBao. Workplan WARDEN-WP-0025 tracks approval, apply, and verification.
Integrate phase-memory across worker ticks, coding agent sessions, and
operator CLI with shared store, OpenRouter efficiency, and unchanged guardrails.
Add unified metadata-only audit.jsonl with secret-material guard, instrument
sign/access/worker paths, and expose warden activity CLI. Surface broker hint
when VAULT_TOKEN is unset, refresh INTENT/SCOPE docs, and add production
integration checklists plus catalog lane promotion playbook.
Persist the 2026-07-01 assessment, register the alignment workplan with
tasks for INTENT refresh, production integration coordination, broker UX,
and catalog promotion. Promote WP-0022 to ready and update SCOPE links.
Draft workplan for a unified, metadata-only audit log of every ops-warden action (sign,
access proxy, worker send/tick) and a single `warden activity [--days N] [--kind] [--json]`
command to read it. Secret-material guard so no value ever lands in the audit; folds in the
existing signatures.log / access-audit.log; optional --hub for the progress-note narrative.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
T4 (review→send loop): conservative tick persists structured drafts to
state_dir/worker-drafts.json; `warden worker drafts` lists them, `warden worker approve
<id> [--body …]` sends the reviewed draft as the reply + marks read + drops it. Escalated
plans persist no draft. Live-verified end-to-end.
T3 (visibility): `warden worker status` (pending drafts, triage count, last digest, timer
state); best-effort notify-send nudge in the tick when drafts are pending.
T5: wiki/playbooks/scheduled-worker.md (enable/disable, the approve loop, failure modes,
conservative-only posture) + SCOPE note.
WARDEN-WP-0021 finished: the conservative worker now runs on a systemd --user timer
(enabled, every 15 min), triages new inbox messages into drafts you approve with one
command, degrades gracefully, and stops with one command. 249 tests, lint clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
T1: systemd --user units (ops-warden-worker.{service,timer}) + scripts/install-worker-timer.sh
(--enable opt-in, cron fallback documented) + examples/worker.env.example. Kill switch:
`systemctl --user disable --now ops-warden-worker.timer` or WORKER_ENABLED=0. Installed and
ENABLED — verified a real systemd run (Result=success, used the llm brain) and the timer is
active (next run +15min).
T2: hardened worker-tick.sh — State Hub /state/health precheck → graceful skip (exit 0) when
unreachable; worker-run failure logged but never fails the unit (retry next tick). Verified
hub-down skip and a live tick.
Conservative tier only; nothing auto-sent. Kill switch is one command.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>