12 KiB
12 KiB
Sentinel v1 Contract Matrix
Purpose: Define what must be recorded, by whom, when, and what the verifier must enforce.
Legend:
- Emitter: system responsible for writing the event
- Trigger: when the event must be emitted
- Hard rule: verifier MUST fail if violated
- Soft rule: verifier MAY warn/fail in strict mode
0) Bundle & Schema Contracts (Seal Bundle)
| Contract ID | Invariant | Evidence Artifact(s) | Verifier Enforcement | Failure Codes |
|---|---|---|---|---|
B-1 |
Bundle MUST contain seal.json, integrity.json, verifier_manifest.json, plus the paths referenced by seal.json.files.*. |
seal.json |
File presence checks in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:557. |
E_MISSING_REQUIRED_FILE, E_SCHEMA_INVALID |
B-2 |
Bundle MUST be offline-verifiable (no network assumptions). | Entire bundle | Verifier MUST rely only on bundle bytes; no network calls are permitted by design. | E_MISSING_REQUIRED_FILE, E_SCHEMA_INVALID (derived from missing/incomplete artifacts) |
seal.json (vm-sentinel-seal-v1)
| Contract ID | Invariant | Evidence Artifact(s) | Verifier Enforcement | Failure Codes |
|---|---|---|---|---|
S-1 |
seal.json.format MUST equal vm-sentinel-seal-v1. |
seal.json |
Format allowlist check in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:594. |
E_SCHEMA_INVALID |
S-2 |
seal.json.hash_algo MUST be blake3 or sha256. |
seal.json |
hash_algo validation in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:604. |
E_SCHEMA_INVALID |
S-3 |
Seal MUST declare a sequence range (since_seq, until_seq). |
seal.json.range |
Schema validation in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:582. |
E_SCHEMA_INVALID |
S-4 |
Seal MUST declare root.start and root.end. |
seal.json.root |
Schema validation in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:582. |
E_SCHEMA_INVALID |
S-5 |
Seal MUST point to receipts/roots/integrity/verifier_manifest files (and they must exist in the bundle). | seal.json.files.* |
Path resolution + existence checks in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:640. |
E_MISSING_REQUIRED_FILE, E_SCHEMA_INVALID |
integrity.json (vm-sentinel-integrity-v1)
| Contract ID | Invariant | Evidence Artifact(s) | Verifier Enforcement | Failure Codes |
|---|---|---|---|---|
I-1 |
integrity.json.format MUST equal vm-sentinel-integrity-v1. |
integrity.json |
Format allowlist check in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:689. |
E_SCHEMA_INVALID |
I-2 |
integrity.json.hash_algo MUST match seal.json.hash_algo. |
integrity.json, seal.json |
Cross-check in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:697. |
E_SCHEMA_INVALID |
I-3 |
Each listed file MUST have path + digest, and the digest MUST match. |
integrity.json.files[] |
Digest recomputation + compare in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:766. |
E_MANIFEST_HASH_MISMATCH, E_SCHEMA_INVALID, E_MISSING_REQUIRED_FILE |
I-4 |
If size_bytes is present, it MUST match file size. |
integrity.json.files[].size_bytes |
Size check in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:822. |
E_SCHEMA_INVALID |
verifier_manifest.json (vm-sentinel-verifier-manifest-v1)
| Contract ID | Invariant | Evidence Artifact(s) | Verifier Enforcement | Failure Codes |
|---|---|---|---|---|
V-1 |
verifier_manifest.json.format MUST equal vm-sentinel-verifier-manifest-v1. |
verifier_manifest.json |
Format allowlist check in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:874. |
E_SCHEMA_INVALID |
V-2 |
MUST declare sentinel_version, schema_version, canonicalization_version. |
verifier_manifest.json |
Schema validation in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:866. |
E_SCHEMA_INVALID |
V-3 |
If hash_algo is present, it MUST match seal.json.hash_algo. |
verifier_manifest.json, seal.json |
Cross-check in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:898. |
E_SCHEMA_INVALID |
V-4 |
verifier object MAY include name/version/sha256; if present, include it in reports. |
verifier_manifest.json |
Report inclusion in vaultmesh-orgine-mobile/tools/vm_verify_sentinel_bundle.py:912. |
N/A |
A) Action Lifecycle Events (Intent → Decision → Outcome)
| Event Type | Emitter | Trigger | Required Fields (minimum) | Hard Verification Rules |
|---|---|---|---|---|
action_intent |
Actor system (Cloudflare ops / guardian / CLI / RTOS host) | Before any attempt to execute an operation | seq, ts, event_type, actor, op, op_digest, trace_id, cap_hash, prev_event_hash, event_hash |
No execution without prior intent: Every action_executed must reference a prior action_intent with same trace_id. |
policy_decision (recommended v1; can be embedded in intent payload to keep schema lean) |
Policy engine (Layer0/classifier) | After intent, before allow/deny | seq, ts, actor, trace_id, op_digest, result (allow/deny), payload.reason_code, payload.classification, prev_event_hash |
Policy recording: if system claims policy enforcement, then every allow/deny must have a recorded decision (either as this event or as a signed payload embedded in intent). |
action_executed |
Actor system | Immediately after side-effect completes | seq, ts, actor, trace_id, op_digest, result (ok/error), root_before, root_after, prev_event_hash, event_hash |
Must have matching prior action_intent. Must not exist if corresponding denial exists for same trace_id (no split reality). |
shadow_receipt |
Sentinel core (or Actor if core is embedded) | On any denial (capability fail, policy deny, budget deny, degraded mode) | seq, ts, actor, trace_id, op_digest, result (deny), payload.reason_code, payload.side_effects="none", prev_event_hash, event_hash |
No silent denial: if an intent does not lead to action_executed, there must be a shadow_receipt unless explicitly marked “write-impossible” (rare). Shadow receipts must assert side_effects="none". |
Notes:
- If you want to avoid a separate
policy_decisionevent, put the decision inaction_intent.payload.policyand require it to be present whenresult != "unknown".
B) Trust / Authority Events (Capabilities)
| Event Type | Emitter | Trigger | Required Fields | Hard Verification Rules |
|---|---|---|---|---|
cap_grant |
Authority issuer (operator tool / provisioning process) | When a capability is created/issued | seq, ts, actor (issuer), payload.capability_json, cap_hash, prev_event_hash |
Capability used later must hash to a previously granted token OR be in a pinned trust root (bootstrap). |
cap_revoke |
Authority issuer | When revoking capability | seq, ts, actor, payload.revoked_cap_hash, payload.reason_code, prev_event_hash |
Revocation is authoritative: any subsequent event with cap_hash matching a revoked one MUST be denied (shadow_receipt with reason revoked). |
cap_use (optional; can be derived) |
Sentinel core | Whenever a capability is presented | seq, ts, actor, cap_hash, trace_id, prev_event_hash |
If enabled, must correlate to action_intent/trace_id. Not required if you already store cap_hash on intent/outcome. |
C) Root & Sealing Events (Time Compression / Witness Bundles)
| Event Type | Emitter | Trigger | Required Fields | Hard Verification Rules |
|---|---|---|---|---|
root_published |
Sentinel core | After appending N events or T time window | seq, ts, payload.root_hex, payload.coverage_seq, prev_event_hash |
Root must match recomputation over all events up to coverage_seq. Root determinism required. |
seal_created |
Sentinel core | On schedule OR on tamper/corruption OR on manual request | seq, ts, payload.seal_id, payload.range_since, payload.range_until, payload.end_root, payload.canonicalization_version, prev_event_hash |
Seal must be verifiable offline: receipts + roots + integrity manifest present. Seal completeness is a hard requirement. |
D) Integrity / Tamper / Degradation Events (Hostile Reality)
| Event Type | Emitter | Trigger | Required Fields | Hard Verification Rules |
|---|---|---|---|---|
tamper_signal |
Hardware/host sensor adapter → recorded by Sentinel | Unexpected power cycle, clock jump, enclosure open, seizure sensor | seq, ts, payload.kind, payload.sensor_digest, payload.severity, prev_event_hash |
Presence of tamper signals must tighten policy: subsequent high-risk ops should be denied or require stronger caps (enforced in policy rules; verifier can check if policy recorded). |
corruption_detected |
Storage layer / Sentinel core | On detection of checksum/page/parse failure | seq, ts, payload.affected_ranges, payload.last_good_seq, payload.last_good_root, prev_event_hash |
No silent data loss: corruption must be recorded. Recommended: must trigger immediate seal_created if possible (strict mode can enforce). |
boot_event |
Sentinel core | On startup | seq, ts, payload.version, payload.schema_version, payload.hash_algo, prev_event_hash |
Boot events should be monotonic across sessions; verifier can warn if missing across long ranges. |
E) Minimal Verifier Rules (Derived from Matrix)
Hard fails (always):
- Schema invalid for any required file/event →
E_SCHEMA_INVALID seqnon-monotonic / duplicate / missing in covered range →E_SEQ_NON_MONOTONICprev_event_hashchain discontinuity →E_CHAIN_DISCONTINUITY- Root mismatch for declared coverage →
E_ROOT_MISMATCH - Seal missing required artifacts (receipts + roots + integrity + verifier manifest) →
E_MISSING_REQUIRED_FILE,E_SCHEMA_INVALID - Revoked capability used without denial →
E_REVOKED_CAPABILITY_USED
Strict-mode fails (recommended):
7. Missing shadow_receipt where intent didn’t execute
8. Corruption without subsequent seal (when seal could be created)
9. Policy enforcement claim without recorded policy decision
F) Boundary Rules (encoded)
- Actor Replaceability: actor systems can change; evidence format cannot.
- Policy Recording: decisions go into receipts.
- Tamper Evidence: tamper events must exist for power/clock anomalies.
- Export Redundancy: portable artifacts exist independent of runtime.
- Verifier Independence: no network/secrets required.
- Version Compatibility: verifier supports N-2.
G) Failure Code Map (v1)
Source of truth: vaultmesh-orgine-mobile/tools/sentinel_failure_codes.py
E_SCHEMA_INVALID: Any required schema/format/cross-field validation fails.E_MISSING_REQUIRED_FILE: A required file is missing from the bundle (or referenced but absent).E_MANIFEST_HASH_MISMATCH: A file’s computed digest does not matchintegrity.json.E_OVERSIZE_INPUT: Input exceeds configured maximum bytes.E_EVENT_HASH_MISMATCH:event_hashdoes not match recomputation from canonical bytes.E_CHAIN_DISCONTINUITY:prev_event_hashchain breaks (tamper/reorder/rollback evidence).E_SEQ_NON_MONOTONIC: Duplicate, missing, or non-monotonicseqvalues.E_RANGE_MISMATCH: Seal declares a range that does not match included events.E_CANON_VERSION_UNSUPPORTED: Declaredcanonicalization_versionis unknown/unsupported.E_ROOT_MISMATCH: Recomputed Merkle end root does not match declared/observed root.E_REVOKED_CAPABILITY_USED: A revoked capability is used after revoke without denial semantics.
Warnings (non-fatal unless strict-mode elevates):
W_FILE_NOT_IN_MANIFEST: A file exists in the bundle but is not listed inintegrity.json(or recommendedseal.jsoncoverage is missing).W_RANGE_ROOT_PARTIAL: Verifier cannot fully verify roots/chain due to missing prior context (eg.since_seq > 0without continuation state).