ops-warden/docs/security-case-execution-proposal.md
tegwick 1b8261917e
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Prepare reviewed durable case execution kernel and accepted layer pins
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 02:21:03 +02:00

7.9 KiB

SecurityCase execution contract proposal — 2026-10-10

Status: proposed owner review; not an accepted runtime protocol or authority. Owner: ops-warden. Related: WARDEN-WP-0044-T03, NK-WP-0048, MASON-WP-0010.

warden case plan now gives a valid descriptive run, but the type's entry_point, auth, verification check and rollback action fields are prose. No warden case run or rollback implementation exists. A case becoming materialized cannot turn those descriptions into executable commands.

The proposal preserves caller authority and routes by owner. It introduces no new credential, policy grant, shell command inferred from prose, or authority for Warden to configure a consumer. Architectural contract acceptance belongs to net-kingdom and adapter interfaces to their owners. Founder review is needed only if the acknowledged type's authorization/session boundary changes; the current absence of a machine contract is not an excuse to fabricate one.

Proposed machine seam

Keep human descriptions. Add a separately validated execution reference to steps and checks, resolving to owner-provided closed adapters. An adapter has:

  • immutable reference (owner repo, interface id, version, source digest);
  • closed parameter schema (no secret-sensitivity fields; no free shell text);
  • declared actor mode and catalog lane, which must agree with the case plan;
  • explicit side-effect class and target identifier deriving from case parameters;
  • idempotency/reconciliation contract and metadata-only receipt schema;
  • supported rollback reference or explicit owner-only undo.

Warden does not invent an argv contract for ExternalSecrets, group membership, KeyCape registration or Forgejo configuration. Owner adapters may internally call their reviewed tools. Warden invokes only the fixed entry point provided by that adapter, with validated separate argv fields, and refuses unknown adapters or templates. entry_point prose never goes to shell=True or sh -c.

An owner may initially supply a receipt-only adapter: the run sheet records that step as pending until the owner performs it and provides independent evidence. This gives useful resumable orchestration before every live adapter exists, without implying native completion or transferring ownership.

Run sheet and receipts

The run sheet pins exact case bytes (case-ref), accepted type bytes/version, owner adapter digests, catalog revision, acceptance reference and ordered step identities. Changed pins require a newly reviewed sheet; never inherit previous success into a different exact revision without explicit reconciliation.

Each attempt yields an immutable metadata receipt containing these pins, step id, owner, target, attempt id, result enum and evidence-reference fingerprints. Allowed results: pending-owner, not-started, running, verified-success, verified-no-change, failed-before-change, failed-after-change, uncertain. Neither subprocess output nor arbitrary owner payload is copied into receipts. Adapter error strings are not evidence and must not be logged verbatim.

Stop on failure or uncertainty. A thrown exception or lost process receipt is uncertain, not failed-before-change. Uncertain/failed-after-change blocks retry until the owner reconciles target state. verified-success and verified-no-change are not repeated. Retry after failed-before-change requires the same pins and adapter's explicit retry-safe classification; a replay-safe CAS0 receipt is reconciled, not retried into secret generation. State persistence must write running before dispatch and result afterwards; interruption between those writes leaves uncertain on resume. Outbox failures remain visible and do not get rewritten as verified audit delivery.

Owner receipt ingestion must authenticate provenance or be explicitly manual attended evidence, never a bare trusted JSON argument. Source/local receipts are attributive preparation until their owner contract defines independent native verification. Overall native completion requires every applicable step and verification plus confirmed session revocation; pending-owner is never success.

Sessions, values and rollback

Reuse proxy_attended_login_exec containment/output suppression/revocation rather than add a second login helper. A key-cape login lane and the OpenBao broker issuer role are distinct grants; the executor must represent both and never silently share/inherit a token. Grouping is permitted only within the same declared identity/lane and preserves follow-through order. An agent principal cannot dispatch generated-in-custody mint-secret. The broker continues to rederive the exact case-ref independently.

Rollback traverses successful step receipts in reverse order and only invokes an owner's reviewed undo for target changes that receipt proves were created by this case. Existing shared groups, membership and policies cannot be deleted by interpreting a type rollback sentence literally. 'No change' yields no undo; failed/uncertain states require reconciliation first. Do not restore a prior secret value by extracting it into Warden; custody rollback is owner-native.

Owner acceptance requests to prepare

  1. net-kingdom: accept the closed machine seam separately from descriptive type fields, document materialized = structural acceptance, and avoid gating that state on mint-secret which is itself a follow-through step. Pin the revised schema/type and keep type acceptance provenance explicit.
  2. railiance-platform: provide a generate adapter over existing credential.py exact --grant, --client-id, --case-file, --case-ref and receipt result codes; clarify reconcile semantics for already-present CAS0 and grant/session revocation evidence. No new credential is required by this proposal.
  3. key-cape/net-kingdom: provide registration/group/env adapters and verify/undo contracts in the existing attended boundary; do not hand Warden a user-engine runtime token or a new broad Kubernetes credential.
  4. railiance-apps/Forgejo: provide consumer OIDC + groups enforcement adapter or receipt-only step, exact auth binding for CCR-2026-0042, and source/native group-denial verification. This stays consumer ownership.
  5. ops-mason: give a hash-pinned materialization receipt and list of objects created vs pre-existing, sufficient for collision checks and scoped rollback.

No coordination messages have been sent by preparation of this proposal.

Implementation and verification after owner seam acceptance

Implement case_run.py with injected typed adapters and receipt storage, then CLI run-sheet/receipt import/resume/rollback commands. Keep case_plan read-only. Add type machine-seam validation without turning valid descriptive planning into an unreviewed source-breaking schema migration.

Required tests: rejected changed pins; unaccepted/unmaterialized cases; unsupported adapter/argv refusal; agent mint refusal; pending owner keeps native gate open; verified success never replayed; lost receipt resumes as uncertain; crash after running persistence prevents duplicate side effect; failed-before-change retries only with declared retry-safe adapter; failed-after-change needs owner reconcile; malicious/secret output excluded; inability to revoke remains unverified; rollback visits created successful objects only, preserves shared memberships, and stops on uncertain undo. Inject runners; no live login or target required.

WARDEN-WP-0044-T03 remains open. This packet resolves the precise source contract deficit; it is not case materialization, a native run, or a type decision.

Local reducer prototype

src/warden/case_receipt_state.py is proposed local source preparation, not an accepted wire format. Its pure immutable transitions can be tested without any owner adapter or shell dispatch. Persist the returned running intent before an external side effect; on a lost result, recover marks uncertainty and blocks replay. No receipt provenance, durable storage, CLI dispatch or live action is implemented. tests/test_case_receipt_state.py covers the failure boundaries.