Files
git.stella-ops.org/docs/schemas/verdict-manifest.schema.json
StellaOps Bot 5146204f1b feat: add security sink detection patterns for JavaScript/TypeScript
- Introduced `sink-detect.js` with various security sink detection patterns categorized by type (e.g., command injection, SQL injection, file operations).
- Implemented functions to build a lookup map for fast sink detection and to match sink calls against known patterns.
- Added `package-lock.json` for dependency management.
2025-12-22 23:21:21 +02:00

229 lines
6.5 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stella-ops.org/schemas/verdict-manifest/1.0.0",
"title": "Verdict Manifest Schema",
"description": "Schema for DSSE-signed verdict manifests enabling deterministic replay and audit compliance",
"type": "object",
"required": [
"manifest_id",
"tenant",
"asset_digest",
"vulnerability_id",
"inputs",
"result",
"policy_hash",
"lattice_version",
"evaluated_at",
"manifest_digest"
],
"properties": {
"manifest_id": {
"type": "string",
"description": "Unique identifier for the verdict manifest",
"examples": ["verd:acme-corp:abc123:CVE-2025-12345:1703235600"]
},
"tenant": {
"type": "string",
"minLength": 1,
"description": "Tenant identifier for multi-tenancy"
},
"asset_digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "SHA256 digest of the asset/SBOM"
},
"vulnerability_id": {
"type": "string",
"pattern": "^(CVE-[0-9]{4}-[0-9]+|GHSA-[a-z0-9-]+|[A-Z]+-[0-9]+)$",
"description": "Vulnerability identifier (CVE, GHSA, or vendor ID)"
},
"inputs": {
"$ref": "#/$defs/VerdictInputs"
},
"result": {
"$ref": "#/$defs/VerdictResult"
},
"policy_hash": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "SHA256 hash of the policy file used"
},
"lattice_version": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
"description": "Trust lattice version (semver format)"
},
"evaluated_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC timestamp of evaluation"
},
"manifest_digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "SHA256 digest of the canonical manifest"
},
"signature_base64": {
"type": "string",
"description": "Base64-encoded DSSE signature (optional)"
},
"rekor_log_id": {
"type": "string",
"description": "Sigstore Rekor transparency log entry ID (optional)"
}
},
"additionalProperties": false,
"$defs": {
"VerdictInputs": {
"type": "object",
"description": "All inputs pinned for deterministic replay",
"required": [
"sbom_digests",
"vuln_feed_snapshot_ids",
"vex_document_digests",
"clock_cutoff"
],
"properties": {
"sbom_digests": {
"type": "array",
"items": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"description": "SHA256 digests of SBOM documents used"
},
"vuln_feed_snapshot_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Identifiers for vulnerability feed snapshots"
},
"vex_document_digests": {
"type": "array",
"items": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"description": "SHA256 digests of VEX documents considered"
},
"reachability_graph_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Identifiers for call graph snapshots"
},
"clock_cutoff": {
"type": "string",
"format": "date-time",
"description": "Timestamp used for freshness calculations"
}
},
"additionalProperties": false
},
"VerdictResult": {
"type": "object",
"description": "The verdict outcome with full explanation",
"required": [
"status",
"confidence",
"explanations"
],
"properties": {
"status": {
"type": "string",
"enum": ["affected", "not_affected", "fixed", "under_investigation"],
"description": "Final VEX status"
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Confidence score (0.0 to 1.0)"
},
"explanations": {
"type": "array",
"items": {
"$ref": "#/$defs/VerdictExplanation"
},
"description": "Per-source breakdown of scoring"
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string"
},
"description": "Links to attestations and proof bundles"
}
},
"additionalProperties": false
},
"VerdictExplanation": {
"type": "object",
"description": "Explanation of a single claim's contribution to the verdict",
"required": [
"source_id",
"reason",
"claim_score"
],
"properties": {
"source_id": {
"type": "string",
"description": "Identifier of the VEX source"
},
"reason": {
"type": "string",
"description": "Human-readable reason for the claim"
},
"provenance_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Provenance (P) component score"
},
"coverage_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Coverage (C) component score"
},
"replayability_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Replayability (R) component score"
},
"strength_multiplier": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Claim strength multiplier (M)"
},
"freshness_multiplier": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Freshness decay multiplier (F)"
},
"claim_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Final claim score: BaseTrust * M * F"
},
"asserted_status": {
"type": "string",
"enum": ["affected", "not_affected", "fixed", "under_investigation"],
"description": "Status asserted by this claim"
},
"accepted": {
"type": "boolean",
"description": "Whether this claim was accepted as the winner"
}
},
"additionalProperties": false
}
}
}