VIRP v0.2.0: evidence-required execution
Implements draft-howard-virp-06 plus the items in docs/DRAFT07-NOTES.md.
With evidence_required on (the default), an execution VIRP admits is now
either recorded before it happens or does not happen. Before dispatching any
gate-admitted command the daemon commits a gate_intent chain entry (device,
driver, command, tier, mode, uid, session, and for an approved apply the
approval and proposal it consumes); if that record cannot be committed the
operation is refused with a signed ERROR citing evidence-unavailable and the
driver is never called. After the device acts, a closer entry (gate_execution,
or outcome for an approved apply) links back to the intent by hash. An intent
with no closer grades as an OPEN execution in both the C daemon verifier and
report/verify.py: attempted, disposition unknown, reconcile against the
target, and never a broken chain.
What this release contains:
- evidence_required config flag, default true, strict-fatal on a non-boolean
and fatal at startup with no usable chain; opt-out logs a warning on every
dispatch. - Approval consumption is the committed gate_intent (the chain is the
authority; consumed.list is a cache). An apply-time chain replay guard,
the TTL re-check and the intent commit are atomic under one lock; a cache
write that fails after the intent still executes and the replay is blocked
from the chain. - Type-checked closer binding: a closer must cite a real gate_intent whose
device, command, uid, session, proposal and approval match; violations and
double-spends are verifier FAILs. - An outcome append that fails after the device acted latches the daemon
degraded and refuses further dispatch until restart, rather than losing
the record silently. - A node_config chain entry records the boot posture (evidence_required,
gate mode, tier ceilings, build id) so a reader can bound the window in
which unrecorded execution was permitted.
Known limitations (read before relying on this):
- Durability: the intent is committed to the chain before dispatch and is
durable against a process crash (SQLite WAL, synchronous=NORMAL). It is
not power-loss durable; that requires synchronous=FULL, which this build
does not set. - Approved-apply outcome-fail: the unchained-execution marker is returned on
the auto-execute path only. For an approved apply the outcome is written
after the observation is built, so an outcome-append failure there latches
the daemon degraded and leaves the intent OPEN, but that one caller may
receive a normal observation rather than the marker. Reconcile the open
intent against the target. - SHADOW mode: a would-block command still executes, and its intent and
execution are recorded (with the classified and effective tiers), but the
gate's would-block judgment is not written as its own verdict; only
ENFORCE writes a gate_rejection. - Two tests are PENDING, pending gate_execution/2 (three-valued executed):
a driver result with success=false that does not declare no_dispatch or
NOT_SENT is still recorded as an execution. No shipping driver produces
that shape today. - Legacy gate_execution/1 bodies written before this feature carry no intent
citation and are not graded for intent binding; they verify as before
(hash, link, HMAC), and only entries written by this build participate in
open/closed grading. - Chain integrity is HMAC under K_chain unless detached Ed25519 chain
signing (-S) is enabled; without -S a K_chain holder can still rewrite
history. -S adds third-party verifiability with the public key alone. - Release provenance: the manifest carries a keyless Sigstore attestation
from the workflow's OIDC identity. It proves the bundle was built by this
repository's workflow from this commit; no individual has vouched for it.
No operator ed25519 ssh signature is attached (RELEASE_SIGNING_KEY is
unset for this release).
Verifying this release (use the verifier from a fresh checkout of the tag,
not the copy bundled inside the zip):
gh release download v0.2.0 --repo nhowardtli/virp
gh attestation verify virp-v0.2.0.zip --repo nhowardtli/virp
git clone https://github.com/nhowardtli/virp
cd virp && git checkout v0.2.0
./scripts/verify-release-bundle.sh
--bundle ../virp-v0.2.0.zip
--manifest ../virp-v0.2.0.MANIFEST.sha256
--attestation ../virp-v0.2.0.test-attestation.json
The by-hand equivalents are in docs/RELEASE-PROVENANCE.md.
Amended after publication: the gh attestation verify command above requires gh 2.49 or newer. On older gh, verify the keyless Sigstore attestation with cosign, or fetch it from the GitHub attestations API at repos/nhowardtli/virp/attestations/sha256:. Verified with gh 2.99.0: "✓ Verification succeeded!" — SLSA provenance v1, build workflow .github/workflows/release.yml@refs/tags/v0.2.0, OIDC issuer token.actions.githubusercontent.com.