rotate: LIVE-REAL proof level + execute-time proof gate (M2)

Add ProofLiveReal (highest level, no driver yet) and enforce it at
execute time: rotate --execute only runs drivers with proof >= LIVE-VM
(MinExecuteProof). MOCK-ONLY/UNPROVEN drivers are skipped before any
provider call unless --allow-mock-proven is passed. ExecuteResult gains
Skipped/SkipReason; the CLI reports and audit-logs skips separately from
failures. Closes the last structural gap where an emulator-only driver
could touch a real credential unattended. Covered by execute_gate_test.go.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
leetcrypt
2026-07-15 11:29:07 -07:00
parent 96c9aeeb7a
commit 2459cd4fd8
7 changed files with 229 additions and 24 deletions
+15
View File
@@ -16,6 +16,8 @@ package rotate
// ProofLevel records how a driver's real-cutover behaviour has been validated.
type ProofLevel int
// Ordered lowest→highest: a higher level is a strictly stronger cutover proof.
// The execute-time gate (see execute.go) compares against ProofLiveVM.
const (
// ProofUnproven: no cutover proof recorded (e.g. the dry-run noop helper).
ProofUnproven ProofLevel = iota
@@ -26,11 +28,24 @@ const (
// ProofLiveVM: cutover proven against the REAL target software running in the
// sandbox VM (real PostgreSQL/MariaDB/Redis/wireguard-tools/Gitea/local files).
ProofLiveVM
// ProofLiveReal: cutover proven against a REAL, host-owned credential at the
// real provider (not the VM, not an emulator) — the highest level, recorded
// only after an authorized per-credential rotation on the safe-candidate ladder
// (ROADMAP M2). No driver carries this yet; promotions land here as data.
ProofLiveReal
)
// MinExecuteProof is the minimum proof level a driver must carry to run under
// `rotate --execute` WITHOUT the explicit --allow-mock-proven opt-in. Anything
// below this (MOCK-ONLY, UNPROVEN) is gated off by default so a driver never
// proven against real target software cannot touch a real credential unattended.
const MinExecuteProof = ProofLiveVM
// String renders the level as the token shown in the CLI and the manifest.
func (p ProofLevel) String() string {
switch p {
case ProofLiveReal:
return "LIVE-REAL"
case ProofLiveVM:
return "LIVE-VM"
case ProofMockOnly: