{ "$id": "https://stella.ops/schema/vex-decision.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "VexDecision", "description": "VEX-style statement attached to a finding + subject, representing a vulnerability exploitability decision", "type": "object", "required": [ "id", "vulnerabilityId", "subject", "status", "justificationType", "createdBy", "createdAt" ], "properties": { "id": { "type": "string", "format": "uuid", "description": "Internal stable ID for this decision" }, "vulnerabilityId": { "type": "string", "description": "CVE, GHSA, or other vulnerability identifier", "examples": ["CVE-2023-12345", "GHSA-xxxx-yyyy-zzzz"] }, "subject": { "$ref": "#/$defs/SubjectRef", "description": "The artifact or SBOM component this decision applies to" }, "status": { "type": "string", "enum": [ "NOT_AFFECTED", "UNDER_INVESTIGATION", "AFFECTED_MITIGATED", "AFFECTED_UNMITIGATED", "FIXED" ], "description": "VEX status following OpenVEX semantics" }, "justificationType": { "type": "string", "enum": [ "CODE_NOT_PRESENT", "CODE_NOT_REACHABLE", "VULNERABLE_CODE_NOT_IN_EXECUTE_PATH", "CONFIGURATION_NOT_AFFECTED", "OS_NOT_AFFECTED", "RUNTIME_MITIGATION_PRESENT", "COMPENSATING_CONTROLS", "ACCEPTED_BUSINESS_RISK", "OTHER" ], "description": "Justification type inspired by CSAF/VEX specifications" }, "justificationText": { "type": "string", "maxLength": 4000, "description": "Free-form explanation supporting the justification type" }, "evidenceRefs": { "type": "array", "items": { "$ref": "#/$defs/EvidenceRef" }, "description": "Links to PRs, commits, tickets, docs supporting this decision" }, "scope": { "$ref": "#/$defs/VexScope", "description": "Environments and projects where this decision applies" }, "validFor": { "$ref": "#/$defs/ValidFor", "description": "Time window during which this decision is valid" }, "attestationRef": { "$ref": "#/$defs/AttestationRef", "description": "Reference to the signed attestation for this decision" }, "supersedesDecisionId": { "type": "string", "format": "uuid", "description": "ID of a previous decision this one supersedes" }, "createdBy": { "$ref": "#/$defs/ActorRef", "description": "User who created this decision" }, "createdAt": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp when decision was created" }, "updatedAt": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp when decision was last updated" } }, "$defs": { "SubjectRef": { "type": "object", "required": ["type", "name", "digest"], "properties": { "type": { "type": "string", "enum": ["IMAGE", "REPO", "SBOM_COMPONENT", "OTHER"], "description": "Type of artifact this subject represents" }, "name": { "type": "string", "description": "Human-readable subject name (e.g. image ref, package name)", "examples": ["registry.internal/stella/app-service@sha256:7d9c..."] }, "digest": { "type": "object", "additionalProperties": { "type": "string" }, "description": "Algorithm -> digest map (e.g. sha256 -> hex string)", "examples": [{"sha256": "7d9cd5f1a2a0dd9a41a2c43a5b7d8a0bcd9e34cf39b3f43a70595c834f0a4aee"}] }, "sbomNodeId": { "type": "string", "description": "Optional SBOM node/bomRef identifier for SBOM_COMPONENT subjects" } } }, "EvidenceRef": { "type": "object", "required": ["type", "url"], "properties": { "type": { "type": "string", "enum": ["PR", "TICKET", "DOC", "COMMIT", "OTHER"], "description": "Type of evidence link" }, "title": { "type": "string", "description": "Human-readable title for the evidence" }, "url": { "type": "string", "format": "uri", "description": "URL to the evidence resource" } } }, "VexScope": { "type": "object", "properties": { "environments": { "type": "array", "items": { "type": "string" }, "description": "Environment names where decision applies (e.g. prod, staging)", "examples": [["prod", "staging"]] }, "projects": { "type": "array", "items": { "type": "string" }, "description": "Project/service names where decision applies" } }, "description": "If empty/null, decision applies to all environments and projects" }, "ValidFor": { "type": "object", "properties": { "notBefore": { "type": "string", "format": "date-time", "description": "Decision is not valid before this timestamp (defaults to creation time)" }, "notAfter": { "type": "string", "format": "date-time", "description": "Decision expires after this timestamp (recommended to set)" } } }, "AttestationRef": { "type": "object", "properties": { "id": { "type": "string", "description": "Internal attestation identifier" }, "digest": { "type": "object", "additionalProperties": { "type": "string" }, "description": "Content digest of the attestation" }, "storage": { "type": "string", "description": "Storage location (OCI ref, bundle path, or URL)", "examples": ["oci://registry.internal/stella/attestations@sha256:2e61..."] } } }, "ActorRef": { "type": "object", "required": ["id", "displayName"], "properties": { "id": { "type": "string", "description": "User identifier" }, "displayName": { "type": "string", "description": "Human-readable display name" } } } }, "examples": [ { "id": "8a3d0b5a-1e07-4b57-b6a1-1a29ce6c889e", "vulnerabilityId": "CVE-2023-12345", "subject": { "type": "IMAGE", "name": "registry.internal/stella/app-service@sha256:7d9c...", "digest": { "sha256": "7d9cd5f1a2a0dd9a41a2c43a5b7d8a0bcd9e34cf39b3f43a70595c834f0a4aee" } }, "status": "NOT_AFFECTED", "justificationType": "VULNERABLE_CODE_NOT_IN_EXECUTE_PATH", "justificationText": "Vulnerable CLI helper is present in the image but never invoked in the running service.", "evidenceRefs": [ { "type": "PR", "title": "Document non-usage of CLI helper", "url": "https://git.example.com/stella/app-service/merge_requests/42" } ], "scope": { "environments": ["prod", "staging"], "projects": ["app-service"] }, "validFor": { "notBefore": "2025-11-21T10:15:00Z", "notAfter": "2026-05-21T10:15:00Z" }, "createdBy": { "id": "user-123", "displayName": "Alice Johnson" }, "createdAt": "2025-11-21T10:15:00Z" } ] }