{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://stellaops.org/schemas/graph.inspect.v1.schema.json", "title": "graph.inspect.v1", "description": "Inspector payload consumed by the Graph Indexer/API. Carries SBOM relationships plus advisory/VEX linkouts with deterministic ordering so downstream graph nodes/edges can be rebuilt or replayed offline.", "type": "object", "additionalProperties": false, "properties": { "schemaVersion": { "const": "graph.inspect.v1", "description": "Version marker; reject if not exactly graph.inspect.v1." }, "tenant": { "type": "string", "minLength": 1, "description": "Tenant identifier applied to all nested records." }, "artifactDigest": { "type": "string", "pattern": "^[A-Za-z0-9_.:+-]{8,}$", "description": "Primary artifact digest (e.g., image digest) that the inspector payload refers to." }, "sbomDigest": { "type": "string", "pattern": "^[A-Za-z0-9_.:+-]{8,}$", "description": "SBOM digest or manifest hash that produced the relationships below." }, "collectedAt": { "type": "string", "format": "date-time", "description": "UTC ISO-8601 timestamp when the inspector snapshot was produced." }, "components": { "type": "array", "minItems": 1, "description": "Component records kept in the same order as the upstream feed (stable ordering expected).", "items": { "$ref": "#/$defs/component" } }, "links": { "type": "object", "additionalProperties": false, "description": "Optional pointers for traceability (event ids, evidence URLs).", "properties": { "sbomObservationEventId": { "type": "string" }, "linksetDigest": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$", "description": "Optional Concelier linkset digest that seeded this payload." } } } }, "required": [ "schemaVersion", "tenant", "artifactDigest", "sbomDigest", "collectedAt", "components" ], "$defs": { "component": { "type": "object", "additionalProperties": false, "required": ["purl", "relationships", "provenance"], "properties": { "purl": { "type": "string", "description": "Normalized PURL for the component." }, "version": { "type": "string", "description": "Optional explicit version if not derivable from the PURL." }, "scopes": { "type": "array", "description": "Sorted, unique scopes such as runtime/build/dev.", "items": { "type": "string" }, "uniqueItems": true }, "relationships": { "type": "array", "minItems": 1, "description": "SBOM relationships that map to graph edges.", "items": { "$ref": "#/$defs/relationship" } }, "advisories": { "type": "array", "description": "Advisory observations used to emit AFFECTED_BY edges.", "items": { "$ref": "#/$defs/advisoryObservation" } }, "vexStatements": { "type": "array", "description": "VEX statements used to emit VEX_EXEMPTS edges.", "items": { "$ref": "#/$defs/vexStatement" } }, "provenance": { "$ref": "#/$defs/provenance" } } }, "relationship": { "type": "object", "additionalProperties": false, "required": ["type", "targetPurl", "source", "evidenceHash"], "properties": { "type": { "type": "string", "enum": ["contains", "depends_on", "provides", "runtime_observed"], "description": "Relationship kind; aligns to graph edge taxonomy." }, "targetPurl": { "type": "string", "description": "Normalized PURL of the target component." }, "scope": { "type": "string", "description": "Scope label propagated to graph edges (e.g., runtime, build)." }, "evidenceHash": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$", "description": "SHA-256 of the evidence payload referenced by this relationship." }, "source": { "type": "string", "description": "Provenance source for the relationship (e.g., concelier.linkset.v1, scanner.sbom.v1)." } } }, "advisoryObservation": { "type": "object", "additionalProperties": false, "required": ["advisoryId", "source", "status", "modifiedAt", "evidenceHash"], "properties": { "advisoryId": { "type": "string" }, "source": { "type": "string", "description": "Advisory source/provider (nvd, ghsa, distro id, etc.)." }, "status": { "type": "string", "enum": ["affected", "not_affected", "fixed", "under_investigation", "unknown"] }, "severity": { "type": "string" }, "cvss": { "type": "object", "additionalProperties": false, "properties": { "vector": { "type": "string" }, "score": { "type": "number" } } }, "justification": { "type": "string" }, "justificationSummary": { "type": "string" }, "linksetDigest": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }, "evidenceHash": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }, "modifiedAt": { "type": "string", "format": "date-time" }, "provenance": { "$ref": "#/$defs/provenance" } } }, "vexStatement": { "type": "object", "additionalProperties": false, "required": ["statementId", "status", "justification", "issuedAt", "evidenceHash", "source"], "properties": { "statementId": { "type": "string" }, "source": { "type": "string" }, "status": { "type": "string", "enum": ["not_affected", "affected", "under_investigation", "fixed"] }, "justification": { "type": "string" }, "impactStatement": { "type": "string" }, "knownExploited": { "type": "boolean" }, "issuedAt": { "type": "string", "format": "date-time" }, "expiresAt": { "type": "string", "format": "date-time" }, "evidenceHash": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }, "provenance": { "$ref": "#/$defs/provenance" } } }, "provenance": { "type": "object", "additionalProperties": false, "required": ["source", "collectedAt"], "properties": { "source": { "type": "string" }, "collectedAt": { "type": "string", "format": "date-time" }, "eventOffset": { "type": "integer", "minimum": 0 }, "linksetDigest": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }, "evidenceHash": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" } } } } }