Problem Statement
RecourseOS evaluates consequences of actions before execution. But there's no way to prove that evaluation happened.
Today, an agent can claim "I checked with RecourseOS and it said allow" without verification. The agent might have:
- • Lied about checking
- • Hallucinated the response
- • Skipped evaluation entirely
- • Received a different verdict than claimed
Solution: Cryptographic Attestation
Attestations provide cryptographic proof that:
- 1. A specific input was evaluated
- 2. By a specific RecourseOS instance
- 3. At a specific time
- 4. Producing a specific verdict
The killer feature is non-repudiation: agents cannot claim they checked without producing a signed artifact from RecourseOS.
Attestation Schema
interface ConsequenceAttestation {
// Protocol version
version: 'recourse.attestation.v1';
// What was evaluated
input: {
hash: string; // SHA-256 of canonical input
source: 'terraform' | 'shell' | 'mcp';
timestamp: string; // ISO 8601, evaluation time
};
// Replay/freshness protection
nonce: string; // Random 128-bit value, hex-encoded
expires_at: string; // ISO 8601, attestation validity window
// The evaluation result
evaluation: {
riskAssessment: 'allow' | 'warn' | 'escalate' | 'block';
worstTier: 1 | 2 | 3 | 4 | 5;
reportHash: string; // SHA-256 of full ConsequenceReport
mutationCount: number;
hasUnrecoverable: boolean;
};
// Who evaluated
evaluator: {
instanceId: string; // Unique RecourseOS instance identifier
version: string; // RecourseOS version
publicKey: string; // PEM-encoded public key
};
// Cryptographic binding
signature: string; // Ed25519 signature over all fields
signatureAlgorithm: 'Ed25519';
}Key Management
Each key exists in exactly one of five states:
| State | Signing | Verification | Description |
|---|---|---|---|
pending | MUST NOT | MUST fail | Key generated but not yet valid |
active | MAY | MUST succeed | Key available for signing new attestations |
deprecated | MUST NOT | MUST succeed | Key no longer signs but attestations remain verifiable |
retired | MUST NOT | MUST succeed | Key permanently out of rotation |
compromised | MUST NOT | MUST fail | Key cannot be trusted |
Verification Model
| Model | Description | v1? |
|---|---|---|
| Inline (execution) | Target system refuses to execute without attestation | No |
| Async (audit) | Actions execute, attestations logged, audit later | Partial |
| Hybrid | Inline for high-stakes, async otherwise | Future |
| Opt-in by agent | Agent decides whether to verify before proceeding | Yes |
Why opt-in by agent for v1: RecourseOS doesn't control terraform, kubectl, or AWS CLI. It doesinfluence agent behavior through MCP. The agent's decision loop is the boundary where RecourseOS has leverage.
Threat Model
What the protocol protects against
- • Agents that fabricate or hallucinate consequence reports
- • Compromised agents that bypass evaluation entirely
- • Audit trail tampering
- • Repudiation by agent operators
What it does NOT protect against
- • Compromised RecourseOS instances (attacker can sign anything)
- • Compromised signing keys
- • Coercion (operators can force specific verdicts)
- • Out-of-band actions that skip evaluation
Honest framing: The protocol provides integrity of the evaluation chain, not correctness of the evaluation itself.
Why Attestation Matters
The shift from advisory to verifiable changes RecourseOS's security posture:
Advisory (today)
Agent: "Should I delete this bucket?"
RecourseOS: "Block: unrecoverable data loss"
Agent: *deletes bucket anyway*
Audit log: *nothing*Verifiable (with attestation)
Agent: "Should I delete this bucket?"
RecourseOS: ConsequenceReport + Attestation(block)
Agent: *attempts to delete*
CI system: "Show attestation"
Agent: *presents block attestation*
CI system: "Attestation says block. Denied."The attestation protocol doesn't change how evaluation works. It changes whether evaluation matters.