137 lines
7.9 KiB
Markdown
137 lines
7.9 KiB
Markdown
|
|
# 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.
|