RFC-0014: Enclosed Execution
Purpose
Define the client-side requirements for full chain of custody, enabling court-defensible attestation of user input before it enters the CAA pipeline.
This RFC implements the enclosed enforcement locus from the doctrine: "Gate is mechanical and non-bypassable — every step signed and attested."
The Chain of Custody Problem
RFC-0004 (State Extraction) verifies that extracted values appear literally in source text. But it assumes the source text is authentic.
The Gap:
User types "My INR is 4.8"
↓
[??? untrusted gap ???]
↓
System receives "My INR is 4.8"
↓
RFC-0004 verifies extraction
Without enclosed execution, a malicious intermediary could:
- Modify user input before it reaches the system
- Inject fabricated input the user never typed
- User could later deny they provided specific input (repudiation)
For court-defensible scenarios, the system must prove what the user actually entered.
Core Principle
Input attestation must occur at the point of capture, not the point of processing.
The user's input must be cryptographically signed before it leaves the trusted client boundary. The signature travels with the input through the entire pipeline.
Attestation Envelope
Every input in enclosed execution mode MUST be wrapped in an attestation envelope:
interface InputAttestation {
// The actual user input
content: string;
content_hash: string; // SHA-256 of content
// Capture metadata
captured_at: string; // RFC 3339 timestamp
capture_method: CaptureMethod;
// Client attestation
client_signature: ClientSignature;
// Optional: user signature (for high-stakes scenarios)
user_signature?: UserSignature;
// Chain of custody
attestation_chain: AttestationLink[];
}
type CaptureMethod =
| "keyboard_direct" // User typed in trusted client
| "paste_verified" // Pasted, with clipboard attestation
| "voice_transcription" // Speech-to-text with audio hash
| "file_upload" // File with content hash
| "api_injection"; // Programmatic input (requires API key attestation)
Client Signature Requirements
The trusted client MUST sign all captured input:
interface ClientSignature {
// Client identity
client_id: string; // Unique client installation ID
client_version: string; // Semantic version
client_hash: string; // SHA-256 of client binary/bundle
// Platform attestation
platform: PlatformAttestation;
// Signature
algorithm: "Ed25519" | "ECDSA-P256";
public_key: string; // Base64-encoded
signature: string; // Base64-encoded signature over content_hash + captured_at
// Certificate chain (for verified clients)
certificate_chain?: string[];
}
interface PlatformAttestation {
os: string;
os_version: string;
// Hardware attestation (when available)
tpm_quote?: string; // TPM 2.0 quote
secure_enclave?: string; // Apple Secure Enclave attestation
android_attestation?: string; // Android SafetyNet/Play Integrity
// Browser context (for extensions)
browser?: string;
extension_id?: string;
}
User Signature (Optional)
For court-defensible scenarios, the user MAY be required to explicitly sign their input:
interface UserSignature {
// User identity
user_id: string;
identity_provider: string; // e.g., "passkey", "oauth:google", "certificate"
// Signature
algorithm: "Ed25519" | "ECDSA-P256" | "RSA-PSS";
public_key: string;
signature: string; // Over content_hash + captured_at + client_signature.signature
// Authentication context
auth_method: "passkey" | "certificate" | "oauth" | "hardware_token";
auth_timestamp: string;
}
When User Signature is Required:
| Domain | Scenario | User Signature |
|---|---|---|
| Medical | Dosage confirmation | Required |
| Legal | Contract acceptance | Required |
| Finance | Transaction authorization | Required |
| General | Standard queries | Optional |
Trusted Client Types
Browser Extension
Chrome/Firefox extension with:
- Code signed by Ontic
- Manifest V3 with minimal permissions
- Content script isolation
- Secure communication with backend
interface ExtensionAttestation {
extension_id: string; // Chrome Web Store ID
extension_version: string;
manifest_hash: string; // SHA-256 of manifest.json
code_signature: string; // Ontic signature over extension bundle
// Chrome-specific
crx_hash?: string; // Hash of .crx file
}
Extension Security Requirements:
- Minimal DOM Access: Only access designated input fields
- No Network Except Backend: CSP restricts all external requests
- Tamper Detection: Self-integrity check on load
- Secure Storage: Keys stored in
chrome.storage.localwith encryption
Native Application
Desktop/mobile app with:
- Code signed by platform (Apple/Microsoft/Google)
- Additional Ontic signature layer
- Hardware attestation where available
interface NativeAppAttestation {
app_id: string; // Bundle ID / Package name
app_version: string;
platform_signature: string; // Apple/Microsoft/Google signature
// Code integrity
binary_hash: string;
ontic_signature: string; // Ontic signature over binary
// Hardware binding (when available)
device_id?: string; // Hardware-derived, privacy-preserving
}
API Client
Programmatic access for integrations:
interface APIClientAttestation {
api_key_id: string; // Not the key itself
client_certificate: string; // mTLS certificate
request_signature: string; // HMAC or asymmetric signature
// Rate limiting context
request_id: string;
request_timestamp: string;
}
Attestation Chain
For multi-hop scenarios, the attestation chain tracks custody:
interface AttestationLink {
hop_index: number; // 0 = original capture
component_id: string; // Which component handled
component_type: "client" | "proxy" | "gateway" | "service";
// Timestamps
received_at: string;
forwarded_at: string;
// Integrity
input_hash: string; // Hash of input received
output_hash: string; // Hash of output forwarded (should match)
signature: string; // Component's signature over this link
// Verification
verified_previous: boolean; // Did this component verify the previous link?
}
Chain Verification:
function verifyAttestationChain(
attestation: InputAttestation,
): VerificationResult {
const chain = attestation.attestation_chain;
// Verify chain continuity
for (let i = 1; i < chain.length; i++) {
if (chain[i].input_hash !== chain[i - 1].output_hash) {
return { valid: false, error: "Chain discontinuity at hop " + i };
}
if (!chain[i].verified_previous) {
return { valid: false, error: "Unverified link at hop " + i };
}
}
// Verify final hash matches content
const finalHash = chain[chain.length - 1].output_hash;
if (finalHash !== attestation.content_hash) {
return { valid: false, error: "Final hash mismatch" };
}
// Verify all signatures
for (const link of chain) {
if (!verifyLinkSignature(link)) {
return {
valid: false,
error: "Invalid signature at hop " + link.hop_index,
};
}
}
return { valid: true };
}
Timestamp Authority
For legal defensibility, timestamps MUST be verifiable:
interface TimestampAuthority {
// RFC 3161 Time-Stamp Protocol
tsa_url: string;
tsa_certificate: string;
// The timestamp token
timestamp_token: string; // Base64-encoded RFC 3161 response
// Verified timestamp
verified_time: string; // RFC 3339
accuracy_ms: number; // Claimed accuracy
}
Timestamp Requirements:
| Enforcement Locus | Timestamp Requirement |
|---|---|
none | No timestamp required |
post_hoc | Client timestamp sufficient |
pre_emission | Server timestamp required |
enclosed | RFC 3161 TSA required |
Offline Attestation
For scenarios without network connectivity:
interface OfflineAttestation {
// Deferred verification
offline_captured: true;
sync_deadline: string; // Must sync before this time
// Local attestation
local_timestamp: string; // Device clock (untrusted)
local_signature: string; // Signed with cached key
// Sync record (filled when online)
synced_at?: string;
server_timestamp?: string;
verification_status?: "verified" | "expired" | "rejected";
}
Offline Constraints:
- Offline attestations MUST sync within 24 hours
- Expired attestations are treated as
unverifiedinput - High-stakes domains MAY reject offline attestations entirely
Key Management
Client Key Generation
interface ClientKeyGeneration {
// Key generation context
generated_at: string;
generated_by: "secure_enclave" | "tpm" | "software";
// Key binding
bound_to_device: boolean;
bound_to_user: boolean;
// Rotation
rotation_policy: "annual" | "on_compromise" | "manual";
previous_key_hash?: string; // For key rotation verification
}
Key Escrow (Optional)
For enterprise scenarios with recovery requirements:
interface KeyEscrow {
escrow_enabled: boolean;
escrow_provider: string; // e.g., "enterprise_hsm", "ontic_escrow"
// Recovery
recovery_threshold: number; // M-of-N recovery
recovery_parties: string[]; // Party identifiers
// Audit
escrow_access_log: boolean;
}
Integration with CAA Pipeline
Enclosed execution integrates with existing RFCs:
User Input
↓
[RFC-0013: Enclosed Capture] → InputAttestation
↓
[RFC-0004: State Extraction] → Trusts attestation, extracts state
↓
[RFC-0006: Evidence Binding] → Attestation becomes evidence
↓
[RFC-0009: Authorization Envelope] → Attestation hash in provenance
Provenance Extension:
interface Provenance {
// Existing fields from RFC-0009
oracle_records: OracleVerificationRecord[];
derived_from?: string[];
generated_at: string;
envelope_id: string;
// RFC-0013 extension
input_attestation?: {
attestation_hash: string; // SHA-256 of full InputAttestation
capture_method: CaptureMethod;
client_verified: boolean;
user_signed: boolean;
chain_length: number;
};
}
Enforcement Modes
| Mode | Client Requirement | Attestation | Chain | TSA |
|---|---|---|---|---|
standard | Any client | Optional | No | No |
verified_client | Signed extension/app | Required | No | No |
full_custody | Signed + platform attestation | Required | Required | No |
enclosed | All above + user signature | Required | Required | Required |
Acceptance Criteria
A system is compliant with RFC-0013 if:
- Trusted clients sign all captured input with verifiable keys
- Attestation envelopes include content hash and timestamp
- Multi-hop chains maintain hash continuity
- Platform attestation is collected where available
- User signatures are required for designated high-stakes domains
- Offline attestations sync within deadline or are rejected
- Attestation hashes appear in envelope provenance
Relationship to Other RFCs
| RFC | Relationship |
|---|---|
| RFC-0004 | Receives attested input, trusts attestation for extraction |
| RFC-0006 | Attestation becomes evidence in binding |
| RFC-0009 | Attestation hash included in provenance |
| RFC-0012 | Agentic tool calls may require attestation for side effects |