Files
railiance-platform/workplans/RAILIANCE-WP-0005-credential-request-and-lease-broker.md

17 KiB

id, type, title, domain, repo, status, owner, topic_slug, planning_priority, planning_order, created, updated, depends_on_workplans, state_hub_workstream_id
id type title domain repo status owner topic_slug planning_priority planning_order created updated depends_on_workplans state_hub_workstream_id
RAILIANCE-WP-0005 workplan Credential Request and Lease Broker financials railiance-platform blocked codex railiance high 5 2026-06-24 2026-06-27
RAIL-PL-WP-0002
2731fece-6c49-45b8-ab8a-4ea6c04ac603

RAILIANCE-WP-0005 - Credential Request and Lease Broker

Goal

Provide a clean, secure, low-friction way for operators, agents, and approved automations to request, generate, receive, use, renew, and revoke short-lived credentials such as the OpenBao token needed for ops-warden vault-backed SSH signing smoke.

The target experience is self-service for routine, policy-approved leases and explicit human approval for high-risk grants, without ever pasting secret values into Git, State Hub, chat, prompts, workplans, or shell history.

Repository Decision

The primary owner is railiance-platform because OpenBao is the canonical runtime secret custody service and this repo owns platform secrets, identity integration, and shared credential delivery contracts.

Cross-repo responsibilities:

Concern Owner Boundary
OpenBao policies, token roles, lease broker, audit railiance-platform Owns secret custody and credential generation.
Login, OIDC, MFA, IAM profile claims key-cape Authenticates humans and service identities.
Authorization decision for requested grants flex-auth May decide whether actor X may request grant Y for purpose Z.
SSH certificate signing ops-warden Issues SSH certs only; does not vend OpenBao tokens.
Request tracking and progress state-hub Stores non-secret request metadata, status, decision ids, and audit pointers only.
Agent inference/runtime llm-connect and callers Never place secrets in prompts; consume via local env injection or wrapped lease handles.

This work should update the ops-warden routing catalog when complete, but the implementation belongs here. If the broker later becomes a general NetKingdom service, code can split to a dedicated credential-broker repo while OpenBao policies and grants remain owned by railiance-platform.

Design Principles

  • Prefer dynamic or short-lived leases over static secrets.
  • Use response wrapping or local exec-time injection; do not print raw tokens by default.
  • Store non-secret lease metadata only: actor, grant, TTL, purpose, lease id or accessor, decision id, timestamps, and revocation state.
  • Keep OpenBao audit logs as the source of truth for secret access.
  • Make the common path easy: one command to run a task with the right credential.
  • Keep high-risk paths explicit: human approval and MFA for elevated grants.
  • Every grant has a catalog entry, max TTL, allowed actors/subjects, delivery mode, audit expectations, and revocation behavior.

Proposed User Experience

Initial pilot command shapes:

credential request vault-token --grant ops-warden/warden-sign --purpose flex-auth-openbao-smoke --ttl 15m
credential exec --grant ops-warden/warden-sign --ttl 15m -- SMOKE_VAULT=1 /home/worsch/ops-warden/scripts/policy_gate_production_smoke.sh
credential status <lease-handle>
credential revoke <lease-handle>

For the ops-warden smoke, the preferred path is credential exec. It obtains a bounded OpenBao token with the warden-sign policy, injects it as VAULT_TOKEN only into the child process environment, redacts logs, and revokes or lets the lease expire after the command finishes.

Threat Model Summary

Primary risks:

  • token leakage through shell history, logs, prompts, chat, State Hub, or Git;
  • confused-deputy issuance where an agent requests a broader token than needed;
  • stale leases surviving after a task completes;
  • bypassing KeyCape identity or flex-auth authorization checks;
  • replacing one manual secret-handling ritual with another brittle one.

Mitigations required by this workplan:

  • no raw token in command-line arguments, State Hub payloads, workplans, or logs;
  • bounded OpenBao token roles and policies;
  • response wrapping for copy/paste or remote handoff flows;
  • exec-time environment injection for local command execution;
  • default TTLs measured in minutes, with explicit max TTLs per grant;
  • revocation by lease handle/accessor;
  • OpenBao audit verification and non-secret State Hub progress events.

Tasks

T01 - Record ownership and architecture decision

id: RAILIANCE-WP-0005-T01
status: done
priority: high
state_hub_task_id: "cd680de8-a483-40d6-84fa-369bad60e7c7"

Write an ADR or docs section confirming railiance-platform as the owner for OpenBao credential request/generation/delivery, with key-cape, flex-auth, ops-warden, state-hub, and llm-connect boundaries.

Acceptance:

  • Docs state that ops-warden routes SSH certs only and must not vend OpenBao tokens.
  • Docs state that State Hub stores request metadata only, never secret values.
  • Ops-warden credential routing can point OpenBao token requests here.

2026-06-25: Added docs/credential-broker.md as the ownership and architecture decision. It records that railiance-platform owns OpenBao credential request/generation/delivery, ops-warden owns SSH certificate signing only, State Hub stores non-secret request metadata only, and llm-connect/callers must not place secrets in prompts.

T02 - Define credential grant catalog

id: RAILIANCE-WP-0005-T02
status: done
priority: high
state_hub_task_id: "6b64ad4b-90cd-475b-aaa9-73997c6b011b"

Add a non-secret grant catalog schema and initial grant entries.

Initial grant:

  • id: ops-warden/warden-sign
  • credential type: openbao-token
  • policies: warden-sign
  • default TTL: 15 minutes
  • max TTL: 1 hour unless a human approves more
  • purpose examples: flex-auth OpenBao smoke, ops-warden production sign smoke
  • allowed delivery: exec-env, response-wrap, local-token-file mode 0600
  • denied delivery: chat, State Hub body, Git, command-line token argument

Acceptance:

  • Catalog can be validated in CI.
  • The catalog distinguishes self-service, approval-required, and break-glass grants.
  • No grant entry contains a secret.

2026-06-25: Added the non-secret grant catalog at credential-grants/catalog.yaml with the initial ops-warden/warden-sign pilot grant, plus scripts/credential-grants-validate.py and make credential-grants-validate. The validator enforces required fields, TTL bounds, denied delivery modes, disallowed OpenBao policies, audit/revocation expectations, and secret-looking marker rejection.

T03 - Configure bounded OpenBao token roles and policies

id: RAILIANCE-WP-0005-T03
status: wait
priority: high
state_hub_task_id: "d8498e3b-b2fb-47b7-ab88-cd6592c1807e"

Create idempotent scripts/manifests for OpenBao token roles or equivalent lease issuance paths that can generate child tokens only for approved policies and TTLs. Start with warden-sign.

Acceptance:

  • A non-root issuer path can create a warden-sign token with bounded TTL.
  • The resulting token cannot administer OpenBao and can only call the SSH sign paths allowed by openbao/policies/warden-sign.hcl.
  • Verification proves the token can run ops-warden vault signing and cannot list unrelated secrets.

2026-06-26: Added the source-side OpenBao token-grant implementation for the ops-warden/warden-sign pilot: issuer policy openbao/policies/credential-broker-warden-sign-issuer.hcl, idempotent apply and verify scripts, Make targets for dry-run/live apply/live verification, and catalog validation for openbao.issuer_policy. Dry-run validation is expected to work offline. Live closure still requires an approved OpenBao operator token path and successful runs of make openbao-configure-token-grants and make openbao-verify-token-grants-smoke, so T03 remains progress.

2026-06-27: Attempted the live idempotent apply with make openbao-configure-token-grants OPENBAO_TOKEN_GRANT_ARGS=--use-token-helper. OpenBao was reachable and unsealed, but the pod token helper received 403 permission denied while writing sys/policies/acl/credential-broker-warden-sign-issuer. T03 is now wait until an approved OpenBao issuer/platform-admin path applies the policy and role, or the pod token helper is granted that narrow capability.

T04 - Build credential helper MVP

id: RAILIANCE-WP-0005-T04
status: wait
priority: high
state_hub_task_id: "0c543cb3-36cb-4b25-9a58-de8efc1216c9"

Build a small CLI/helper in this repo first, for example credential or openbao-lease, with request, exec, status, and revoke commands.

Acceptance:

  • credential exec can run the ops-warden production smoke with VAULT_TOKEN only in the child process environment.
  • request returns a wrapped token or lease handle by default, not the raw token.
  • status and revoke work by non-secret lease handle/accessor.
  • The helper redacts token-looking values from logs and refuses to run in verbose modes that would print secrets.

2026-06-26: Added scripts/credential.py as the source helper MVP with request, exec, status, and revoke subcommands. The helper validates the grant catalog, enforces purpose and TTL bounds, defaults request to a local mode-0600 token file plus non-secret accessor metadata, supports response-wrap handoff, injects VAULT_TOKEN only into the child process for exec, redacts token-looking child output, rejects caller-supplied token env assignments, and revokes exec tokens by accessor in a finally block. Added Make dry-run and ops-warden smoke targets. T04 remains progress until a live OpenBao issuer token is available to prove credential-exec-ops-warden-smoke end to end.

2026-06-27: Extended the helper with optional flex-auth preflight, non-secret State Hub lifecycle metadata, actor/subject binding fields, --decision-id support, and Kubernetes-auth delegation output. Fixed the Make surface so global helper flags such as --use-token-helper are passed before the subcommand. T04 is now wait on the same OpenBao live gate as T03 before ops-warden smoke can be proven end to end.

T05 - Implement secure delivery modes

id: RAILIANCE-WP-0005-T05
status: wait
priority: high
state_hub_task_id: "66f3cd6d-7520-4584-90b8-672866ef3490"

Support safe delivery modes for different runtime contexts.

Required modes:

  • exec-env: inject credential into one child process, then forget it;
  • response-wrap: produce a single-use OpenBao wrapping token for attended handoff;
  • local-token-file: write mode 0600 under an ignored local state directory, with TTL metadata and cleanup;
  • kubernetes-auth: use service-account-bound auth for in-cluster workloads instead of handing them tokens manually.

Acceptance:

  • No delivery mode requires pasting the secret into chat or State Hub.
  • local-token-file paths are gitignored and rejected by secret scans if accidentally staged.
  • response-wrap unwraps once and fails on second use.

2026-06-27: Source support now covers all four delivery modes: exec-env, response-wrap, local-token-file, and kubernetes-auth. The helper refuses caller-supplied token env assignments, writes local leases under the ignored .local/credential-leases/ path with mode 0600, and emits only service account auth metadata for Kubernetes-auth. T05 is wait until live response-wrap single-use behavior and the OpenBao-backed exec path are verified with an approved issuer token.

T06 - Integrate KeyCape identity and agent subject binding

id: RAILIANCE-WP-0005-T06
status: done
priority: medium
state_hub_task_id: "e1dd5973-bf2b-4aa9-842e-9f530afa1ab6"

Define how humans and agents authenticate to request grants.

Acceptance:

  • Human operator path uses KeyCape/OIDC with MFA where required.
  • Agent/service path has a documented subject id shape compatible with IAM profile claims and existing actor naming.
  • Headless automation uses Kubernetes auth or an explicitly approved non-interactive identity; it does not reuse a human token.

2026-06-27: Documented the identity contract in docs/credential-broker.md: KeyCape/OIDC with MFA for human operators, stable IAM-compatible subjects for agents and CI, and Kubernetes service-account subjects for headless workloads. The helper now exposes --actor, --actor-type, and --subject, and validates actor type against the grant catalog. T06 is done source-side.

T07 - Add flex-auth preflight authorization and State Hub request metadata

id: RAILIANCE-WP-0005-T07
status: wait
priority: medium
state_hub_task_id: "1269bb58-0699-43ef-aa4f-43bc49c61a49"

Before issuing a lease, optionally call flex-auth with actor, subject, grant, purpose, TTL, audience, and requested delivery mode. Record non-secret request metadata and decision ids in State Hub when available.

Acceptance:

  • flex-auth can deny overbroad TTL, wrong actor type, wrong purpose, or disallowed delivery mode.
  • State Hub records request lifecycle without token values.
  • The helper works in offline/degraded mode only for pre-authorized local flows; it never caches new secret material in State Hub.

2026-06-27: Added optional flex-auth preflight via --flex-auth-url / FLEX_AUTH_URL, strict --require-flex-auth, provided decision ids via --decision-id, and opt-in State Hub lifecycle notes via --record-state-hub. The helper records only non-secret metadata. T07 is wait until a live flex-auth credential authorization endpoint is available and the OpenBao live gate is cleared.

T08 - Integrate ops-warden smoke and routing catalog

id: RAILIANCE-WP-0005-T08
status: wait
priority: high
state_hub_task_id: "4571d4c9-d4de-4ee9-97e0-ff03e49e65ec"

Replace the manual VAULT_TOKEN step in ops-warden smoke docs with the credential helper flow and update the credential routing catalog.

Acceptance:

  • FLEX-WP-0007 T4 can be run with one command once the grant is configured: credential exec --grant ops-warden/warden-sign --ttl 15m -- SMOKE_VAULT=1 /home/worsch/ops-warden/scripts/policy_gate_production_smoke.sh
  • ops-warden docs still make clear it owns SSH cert signing, not OpenBao token vending.
  • warden route find VAULT_TOKEN points to this railiance-platform flow.

2026-06-27: Added make credential-exec-ops-warden-smoke for the intended one-command smoke and confirmed credential routing locally with uv run warden route show openbao-api-key --json: OpenBao/API/dynamic lease needs belong to railiance-platform; ops-warden executes SSH cert issuance only. T08 is wait because this workspace cannot update the external ops-warden routing catalog and the live OpenBao grant apply is still denied.

T09 - Verification, audit, and red-team checks

id: RAILIANCE-WP-0005-T09
status: wait
priority: high
state_hub_task_id: "78d1db83-12fb-4ac2-95eb-54c91ac125b5"

Add tests and operator verification for the complete flow.

Acceptance:

  • Unit tests cover grant validation, TTL bounds, redaction, and delivery-mode restrictions.
  • Dry-run tests require no secrets.
  • Live smoke proves OpenBao audit logs record issuance and use.
  • Negative tests prove denied grants do not mint tokens.
  • Documentation includes emergency revocation and cleanup commands.

2026-06-27: Added tests/test_credential_helper.py and make credential-tests covering TTL bounds, actor-type restrictions, token redaction, unsafe env rejection, local lease mode/cleanup, Kubernetes-auth delegation, and gitignore coverage for local lease files. Offline validation is passing. T09 is wait until live OpenBao audit evidence, response-wrap unwrap-once evidence, and negative live mint checks can be collected.

T10 - Rollout and migration

id: RAILIANCE-WP-0005-T10
status: wait
priority: medium
state_hub_task_id: "44ce4082-fa8f-44d0-8f86-172d14ecfb0e"

Roll out in phases.

Phases:

  1. warden-sign VAULT_TOKEN pilot for flex-auth/ops-warden smoke.
  2. Platform-readonly token helper for diagnostics.
  3. Workload-specific grants for app repositories.
  4. Optional split to a dedicated credential-broker repo if code grows beyond railiance-platform ownership.

Acceptance:

  • The VAULT_TOKEN blocker from FLEX-WP-0007 is cleared without manual token paste.
  • Operators have a documented fast path and a break-glass path.
  • State Hub, ops-warden, key-cape, and flex-auth docs link to the same routing truth.

2026-06-27: Documented rollout phases, emergency revocation, delivery modes, identity binding, flex-auth preflight, State Hub metadata, and routing ownership in docs/credential-broker.md. T10 is wait on the live warden-sign pilot and external routing-doc/catalog updates.

Exit Criteria

  • A policy-approved actor can request or exec with a short-lived OpenBao token without seeing or pasting the raw token.
  • The ops-warden vault-backed smoke can run without manual VAULT_TOKEN handling.
  • All issued credentials are bounded, auditable, and revocable.
  • State Hub and workplans contain only non-secret metadata.
  • The credential routing catalog points token/dynamic-lease requests to railiance-platform.