diff --git a/README.md b/README.md index 184058f..922f840 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ SECRETS_ENGINE_HUB_URL="" bash scripts/demo-e2e.sh - ops-warden routing contract: [docs/ops-warden-routing-contract.md](docs/ops-warden-routing-contract.md) - Hardening backlog (exit bootstrap mode): [docs/hardening-backlog.md](docs/hardening-backlog.md) - Existing-lane catalog admission: [docs/catalog-admission.md](docs/catalog-admission.md) +- Native lane cutover (WP-0006 T05/T06): [docs/native-lane-cutover.md](docs/native-lane-cutover.md) - KeyCape service-auth consumer boundary: [docs/service-auth.md](docs/service-auth.md) - Approval consume-before-OpenBao (GH-DEC-2026-003): [docs/approval-consumption.md](docs/approval-consumption.md) - OpenBao JWT login contract (engine consumer): [docs/openbao-jwt-login.md](docs/openbao-jwt-login.md) diff --git a/catalog/openrouter-llm-connect.yaml b/catalog/openrouter-llm-connect.yaml index 0a8b7f1..2ae3a7f 100644 --- a/catalog/openrouter-llm-connect.yaml +++ b/catalog/openrouter-llm-connect.yaml @@ -46,6 +46,8 @@ approval: notes: >- CCR-2026-0003 approves the existing workload lane. A live native AppRole apply remains gated by SECRETS-WP-0006-T05 review and operator approval. + First native-cutover candidate (docs/native-lane-cutover.md); not an + authorization to apply. verification: positive: approved delivery AppRole can read OPENROUTER_API_KEY without printing it diff --git a/docs/native-lane-cutover.md b/docs/native-lane-cutover.md new file mode 100644 index 0000000..df7d775 --- /dev/null +++ b/docs/native-lane-cutover.md @@ -0,0 +1,68 @@ +# Native lane cutover (SECRETS-WP-0006-T05 / T06) + +Status: procedure only. Live apply is still fail-closed until +`SECRETS-WP-0007-T04` serves an exact-action approval and railiance-platform +grants scoped attended authority. CCR references below are workload-lane +provenance, not executable authorization for the native AppRole. + +This document does not authorize production mutation. + +## Scope + +Five admitted KV lanes on the existing `platform` mount. Workload delivery +(ESO/OIDC) stays with current owners. Native apply adds only an exact-path +read policy and bounded AppRole. + +Do not batch-retire ops-warden interim proxies. T06 is per lane, after native +evidence. + +## Cutover order + +Chosen for increasing blast radius, not CCR age. + +| Order | Lane | Why this position | +| --- | --- | --- | +| 1 | `openrouter-llm-connect` | One field, one ESO consumer besides operator exec | +| 2 | `email-connect-transactional` | Three fields; ingest bearer shared with user-engine | +| 3 | `issue-core-ingestion-api-key` | Two fields, two ESO consumers | +| 4 | `reuse-surface-hub-write-token` | Hub write + webhook HMAC, two coordinated consumers | +| 5 | `forgejo-admin-api-token` | Site-admin PAT; last on purpose | + +## What live apply would mutate (once approved) + +Re-rendered 2026-09-02 against current `build_plan`. Every lane: + +- `[kv-mount-check] platform` — no mount create +- `[policy]` exact `platform/data/` read + metadata read +- `[approle]` 15m TTL, 30m max, 15m single-use secret_id, 8 token uses + +No KV put/patch, no ESO change, no provider rotation. + +## First-lane packet: `openrouter-llm-connect` + +Provenance CCR: `CCR-2026-0003` (existing workload lane only). + +Required before OpenBao: + +1. Canonical ActionAuthorization for `action=apply`, resource + `catalog:openrouter-llm-connect`, stage `prod`, exact policy/auth targets + `se-prod-openrouter-llm-connect`. +2. Successful approval-engine CAS consume of that request digest + (`GH-DEC-2026-003`). +3. Scoped attended production authority from railiance-platform (not a + standing bootstrap token). +4. llm-connect owner ready to confirm ESO/application health after apply. + +Apply: `secrets-engine apply openrouter-llm-connect --stage prod` +then metadata-safe verify of field presence and unrelated-identity denial. +No value in evidence. Delivery session must self-revoke. + +Rollback (native only): delete AppRole and policy +`se-prod-openrouter-llm-connect`. Leave KV and ESO untouched. Keep the +ops-warden proxy until T06. + +## Explicit non-goals for T05 + +- Provision or rotate the live OpenRouter key. +- Retire all five proxies in one batch. +- Treat CCR status or a local fixture as apply authorization. diff --git a/tests/test_wp0006_cutover.py b/tests/test_wp0006_cutover.py new file mode 100644 index 0000000..f8f1693 --- /dev/null +++ b/tests/test_wp0006_cutover.py @@ -0,0 +1,31 @@ +from secrets_engine.catalog import load_catalog +from secrets_engine.config import repo_root +from secrets_engine.plan import build_plan + +ADMITTED = ( + "openrouter-llm-connect", + "email-connect-transactional", + "issue-core-ingestion-api-key", + "reuse-surface-hub-write-token", + "forgejo-admin-api-token", +) +FIRST_LANE = "openrouter-llm-connect" + + +def test_admitted_lanes_plan_existing_mount_and_exact_approle(): + catalog = load_catalog(repo_root() / "catalog") + assert FIRST_LANE == ADMITTED[0] + for lane_id in ADMITTED: + entry = catalog[lane_id] + assert entry.stage == "prod" + assert entry.mount == "platform" + assert entry.mount_management == "existing" + plan = build_plan(entry, "prod", decision_id=entry.approval.get("decision_ref", "")) + kinds = [action.kind for action in plan.actions] + assert kinds[0] == "kv-mount-check" + assert "kv-mount" not in kinds + assert "policy" in kinds + assert "approle" in kinds + assert "platform/data/" in plan.policy_hcl + assert '"create"' not in plan.policy_hcl + assert "capabilities = [\"read\"]" in plan.policy_hcl diff --git a/workplans/SECRETS-WP-0006-catalog-lane-adoption.md b/workplans/SECRETS-WP-0006-catalog-lane-adoption.md index 827c293..6e53e42 100644 --- a/workplans/SECRETS-WP-0006-catalog-lane-adoption.md +++ b/workplans/SECRETS-WP-0006-catalog-lane-adoption.md @@ -8,7 +8,7 @@ status: active owner: codex topic_slug: custodian created: "2026-08-21" -updated: "2026-09-02" +updated: "2026-09-03" state_hub_workstream_id: "31f7f8ea-7f73-516c-8877-f03a13f1db82" --- @@ -198,6 +198,16 @@ priority: high state_hub_task_id: "fb103f1e-2ff7-5de5-9a2c-191a19c43542" ``` +Progress 2026-09-03. Re-rendered guarded plans on the post-hardening engine. +Every admitted lane is still `kv-mount-check` + exact-path read policy + +bounded AppRole. First live candidate is `openrouter-llm-connect` (narrowest +consumer/field set). Procedure: `docs/native-lane-cutover.md`. Coordinated: +railiance-platform `0190c9b3` (AppRole-only apply, no KV/ESO mutation), +ops-warden `c2c01262` (keep all five proxies), llm-connect `6f9b460a` (ESO +stays theirs). Live apply still wait on T04 serving plus a canonical +`action=apply` approval and scoped attended authority. CCR-2026-0003 remains +provenance, not that approval. Proxies stay until T06 per lane. + Readiness update 2026-08-21: rendered non-mutating production dry-runs for all five lanes. Every plan checks the externally managed `platform` mount without mutation, writes one exact-path read policy, and proposes the reviewed bounded