6.5 KiB
6.5 KiB
Contract: Triage Auto-Suppress Predicate (v1)
Status
- Status: DRAFT (2026-02-19)
- Owner: Signals Guild, VexLens Guild
- Sprint: SPRINT_20260219_012
Purpose
Define the stella.ops/triageSuppress@v1 predicate type used when a runtime micro-witness DSSE confirms that a vulnerability's canonical_id matches a VEX not_affected consensus, enabling automatic triage suppression with full auditability.
Predicate Type URI
stella.ops/triageSuppress@v1
When This Predicate Is Emitted
The TriageSuppressJoinService emits this predicate when ALL of the following conditions are met:
- A micro-witness DSSE exists for
(canonical_id, cve_id)with observation typeRuntimeUnobservedor a path witness with lattice stateConfirmedUnreachableorStaticallyUnreachable - VexLens consensus for
(canonical_id, cve_id)has statusnot_affected - VexLens consensus confidence score >= configured threshold (default: 0.75 for production)
Suppression Rules Truth Table
| VEX Status | Reachability State | Action | Requires Human Review |
|---|---|---|---|
not_affected |
ConfirmedUnreachable (CU) |
AUTO-SUPPRESS | No |
not_affected |
StaticallyUnreachable (SU) |
AUTO-SUPPRESS | No |
not_affected |
RuntimeUnobserved (RU) |
AUTO-SUPPRESS | No |
not_affected |
Unknown (U) |
LOG ONLY | Yes |
not_affected |
StaticallyReachable (SR) |
LOG ONLY | Yes |
not_affected |
RuntimeObserved (RO) |
LOG ONLY, FLAG CONFLICT | Yes |
not_affected |
ConfirmedReachable (CR) |
LOG ONLY, FLAG CONFLICT | Yes |
not_affected |
Contested (X) |
LOG ONLY, FLAG CONFLICT | Yes |
affected |
any | NEVER SUPPRESS | Yes |
under_investigation |
any | NEVER SUPPRESS | Yes |
fixed |
any | NEVER SUPPRESS (separate workflow) | No |
Predicate Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Triage Suppress Predicate v1",
"type": "object",
"required": ["cve_id", "suppress_reason", "vex_consensus", "witness_evidence", "reachability_state", "timestamp"],
"properties": {
"cve_id": {
"type": "string",
"description": "CVE identifier (e.g., CVE-2025-0001)",
"pattern": "^CVE-\\d{4}-\\d{4,}$"
},
"suppress_reason": {
"type": "string",
"enum": ["vex_not_affected_with_unreachability_confirmation"],
"description": "Machine-readable reason for suppression"
},
"vex_consensus": {
"type": "object",
"required": ["status", "confidence_score", "consensus_digest", "computed_at"],
"properties": {
"status": { "type": "string", "enum": ["not_affected"] },
"justification": { "type": "string" },
"confidence_score": { "type": "number", "minimum": 0, "maximum": 1 },
"consensus_digest": { "type": "string", "description": "SHA-256 of the VexLens consensus record" },
"source_count": { "type": "integer", "description": "Number of VEX sources contributing" },
"computed_at": { "type": "string", "format": "date-time" }
}
},
"witness_evidence": {
"type": "object",
"required": ["witness_id", "dsse_digest", "observation_type"],
"properties": {
"witness_id": { "type": "string", "description": "Witness ID (wit:sha256:...)" },
"dsse_digest": { "type": "string", "description": "SHA-256 of the witness DSSE envelope" },
"observation_type": { "type": "string", "enum": ["RuntimeUnobserved", "ConfirmedUnreachable", "StaticallyUnreachable"] },
"predicate_type": { "type": "string", "description": "URI of the witness predicate type" }
}
},
"reachability_state": {
"type": "string",
"enum": ["ConfirmedUnreachable", "StaticallyUnreachable", "RuntimeUnobserved"],
"description": "Lattice state from the 8-state reachability model"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "UTC timestamp of suppression evaluation"
},
"deterministic_replay_inputs": {
"type": "object",
"description": "Inputs sufficient to replay this suppression decision",
"properties": {
"canonical_id": { "type": "string" },
"vex_consensus_digest": { "type": "string" },
"witness_id": { "type": "string" }
}
}
}
}
DSSE Envelope Shape
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "artifact",
"digest": {
"sha256": "<canonical_id_hex>"
}
}
],
"predicateType": "stella.ops/triageSuppress@v1",
"predicate": {
"cve_id": "CVE-2025-0001",
"suppress_reason": "vex_not_affected_with_unreachability_confirmation",
"vex_consensus": {
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"confidence_score": 0.92,
"consensus_digest": "sha256:abc123...",
"source_count": 3,
"computed_at": "2026-02-19T12:00:00Z"
},
"witness_evidence": {
"witness_id": "wit:sha256:def456...",
"dsse_digest": "sha256:789abc...",
"observation_type": "ConfirmedUnreachable",
"predicate_type": "https://stella.ops/predicates/path-witness/v1"
},
"reachability_state": "ConfirmedUnreachable",
"timestamp": "2026-02-19T12:05:00Z",
"deterministic_replay_inputs": {
"canonical_id": "sha256:...",
"vex_consensus_digest": "sha256:abc123...",
"witness_id": "wit:sha256:def456..."
}
}
}
Idempotency
Given the same (canonical_id, cve_id, vex_consensus_digest, witness_id), the service MUST produce byte-identical DSSE output. This is enforced by:
- Deterministic JSON serialization (RFC 8785 / JCS)
- Deterministic timestamp: use the latest of
vex_consensus.computed_atand witnessobserved_at - No random or time-varying fields
Policy Opt-In
Auto-suppress is disabled by default. Operators must enable it via policy configuration:
{
"triage_suppress": {
"enabled": true,
"minimum_vex_confidence": 0.75,
"allowed_reachability_states": ["ConfirmedUnreachable", "StaticallyUnreachable", "RuntimeUnobserved"],
"require_rekor_anchor": true
}
}
Audit Trail
Every suppression evaluation (whether it results in suppression or not) is logged:
- Suppressed: triageSuppress@v1 DSSE → Signer → Attestor → Rekor
- Not suppressed: audit log entry with reason (e.g., "vex_status=affected", "reachability=Contested")
References
- SPRINT_20260219_012
- Reachability Lattice:
docs/modules/reach-graph/guides/lattice.md - VexLens Consensus:
docs/modules/vex-lens/architecture.md - Witness Contract:
docs/contracts/witness-v1.md