Files
git.stella-ops.org/docs/schemas/lnm-overlay.schema.json
StellaOps Bot 4042fc2184
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
release-manifest-verify / verify (push) Has been cancelled
Add unit tests for PackRunAttestation and SealedInstallEnforcer
- Implement comprehensive tests for PackRunAttestationService, covering attestation generation, verification, and event emission.
- Add tests for SealedInstallEnforcer to validate sealed install requirements and enforcement logic.
- Introduce a MonacoLoaderService stub for testing purposes to prevent Monaco workers/styles from loading during Karma runs.
2025-12-06 22:25:30 +02:00

682 lines
19 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stella-ops.org/schemas/lnm-overlay.schema.json",
"title": "StellaOps Link-Not-Merge Overlay Schema",
"description": "Schema for Link-Not-Merge (LNM) overlay metadata and graph inspector integration. Unblocks EXCITITOR-GRAPH-21-001 through 21-005.",
"type": "object",
"definitions": {
"LnmOverlay": {
"type": "object",
"description": "Link-Not-Merge overlay structure for VEX observation and linkset merge metadata",
"required": ["overlay_id", "source_type", "timestamp"],
"properties": {
"overlay_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for this overlay"
},
"source_type": {
"type": "string",
"enum": ["observation", "linkset", "advisory", "vex", "sbom"],
"description": "Type of source contributing to this overlay"
},
"source_ref": {
"$ref": "#/definitions/SourceRef"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "When this overlay was created"
},
"version": {
"type": "string",
"description": "Version of the overlay schema"
},
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/OverlayLink"
},
"description": "Links to related entities"
},
"conflicts": {
"type": "array",
"items": {
"$ref": "#/definitions/ConflictMarker"
},
"description": "Conflict markers from merge operations"
},
"provenance": {
"$ref": "#/definitions/OverlayProvenance"
},
"indexes": {
"$ref": "#/definitions/OverlayIndexes"
}
}
},
"SourceRef": {
"type": "object",
"description": "Reference to the source document/entity",
"required": ["type", "identifier"],
"properties": {
"type": {
"type": "string",
"enum": ["advisory", "vex", "sbom", "scan_result", "linkset", "observation"]
},
"identifier": {
"type": "string",
"description": "Unique identifier of the source (e.g., advisory ID, SBOM digest)"
},
"digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "Content-addressable digest of the source"
},
"uri": {
"type": "string",
"format": "uri",
"description": "URI to retrieve the source"
},
"fetched_at": {
"type": "string",
"format": "date-time"
}
}
},
"OverlayLink": {
"type": "object",
"description": "Link between entities in the overlay graph",
"required": ["link_type", "source", "target"],
"properties": {
"link_id": {
"type": "string",
"format": "uuid"
},
"link_type": {
"type": "string",
"enum": [
"affects",
"mitigates",
"remediates",
"supersedes",
"references",
"contains",
"depends_on",
"exploits",
"derived_from"
],
"description": "Semantic relationship type"
},
"source": {
"$ref": "#/definitions/EntityRef"
},
"target": {
"$ref": "#/definitions/EntityRef"
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Confidence score for this link"
},
"evidence": {
"type": "array",
"items": {
"$ref": "#/definitions/LinkEvidence"
}
},
"metadata": {
"type": "object",
"additionalProperties": true
}
}
},
"EntityRef": {
"type": "object",
"description": "Reference to an entity in the graph",
"required": ["entity_type", "identifier"],
"properties": {
"entity_type": {
"type": "string",
"enum": ["vulnerability", "component", "product", "advisory", "vex_statement", "sbom", "finding"]
},
"identifier": {
"type": "string",
"description": "Entity identifier (CVE ID, PURL, product ID, etc.)"
},
"version": {
"type": "string",
"description": "Version specifier if applicable"
}
}
},
"LinkEvidence": {
"type": "object",
"description": "Evidence supporting a link relationship",
"required": ["type"],
"properties": {
"type": {
"type": "string",
"enum": ["explicit", "inferred", "heuristic", "manual"]
},
"source_ref": {
"$ref": "#/definitions/SourceRef"
},
"statement": {
"type": "string",
"description": "Evidence statement or justification"
},
"score": {
"type": "number",
"minimum": 0,
"maximum": 1
}
}
},
"ConflictMarker": {
"type": "object",
"description": "Marker for merge conflicts between overlapping sources",
"required": ["conflict_type", "entities", "resolution_status"],
"properties": {
"conflict_id": {
"type": "string",
"format": "uuid"
},
"conflict_type": {
"type": "string",
"enum": [
"status_mismatch",
"severity_mismatch",
"version_range_overlap",
"product_identity_conflict",
"justification_conflict",
"timestamp_ordering"
],
"description": "Type of conflict detected"
},
"entities": {
"type": "array",
"items": {
"$ref": "#/definitions/ConflictingEntity"
},
"minItems": 2,
"description": "Entities involved in the conflict"
},
"resolution_status": {
"type": "string",
"enum": ["unresolved", "auto_resolved", "manually_resolved", "deferred"],
"description": "Current resolution status"
},
"resolution": {
"$ref": "#/definitions/ConflictResolution"
},
"detected_at": {
"type": "string",
"format": "date-time"
}
}
},
"ConflictingEntity": {
"type": "object",
"description": "Entity involved in a conflict",
"required": ["source_ref", "value"],
"properties": {
"source_ref": {
"$ref": "#/definitions/SourceRef"
},
"value": {
"type": "object",
"additionalProperties": true,
"description": "The conflicting value from this source"
},
"trust_level": {
"type": "string",
"enum": ["authoritative", "trusted", "community", "unknown"],
"description": "Trust level of this source"
},
"precedence": {
"type": "integer",
"minimum": 0,
"description": "Precedence rank for resolution"
}
}
},
"ConflictResolution": {
"type": "object",
"description": "Resolution decision for a conflict",
"required": ["strategy", "resolved_at"],
"properties": {
"strategy": {
"type": "string",
"enum": [
"latest_wins",
"highest_precedence",
"most_specific",
"manual_selection",
"merge_composite"
],
"description": "Resolution strategy used"
},
"selected_source": {
"$ref": "#/definitions/SourceRef"
},
"resolved_value": {
"type": "object",
"additionalProperties": true,
"description": "The resolved value"
},
"justification": {
"type": "string",
"description": "Justification for the resolution"
},
"resolved_at": {
"type": "string",
"format": "date-time"
},
"resolved_by": {
"type": "string",
"description": "User or system that resolved the conflict"
}
}
},
"OverlayProvenance": {
"type": "object",
"description": "Provenance information for the overlay",
"properties": {
"created_at": {
"type": "string",
"format": "date-time"
},
"created_by": {
"type": "string"
},
"pipeline_id": {
"type": "string",
"description": "ID of the ingestion pipeline that created this overlay"
},
"pipeline_version": {
"type": "string"
},
"input_digests": {
"type": "array",
"items": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"description": "Digests of all inputs used to create this overlay"
},
"attestation_ref": {
"type": "string",
"description": "Reference to DSSE attestation for this overlay"
}
}
},
"OverlayIndexes": {
"type": "object",
"description": "Index configuration for graph inspector queries",
"properties": {
"by_vulnerability": {
"$ref": "#/definitions/IndexConfig"
},
"by_component": {
"$ref": "#/definitions/IndexConfig"
},
"by_product": {
"$ref": "#/definitions/IndexConfig"
},
"by_source": {
"$ref": "#/definitions/IndexConfig"
},
"by_conflict_status": {
"$ref": "#/definitions/IndexConfig"
}
}
},
"IndexConfig": {
"type": "object",
"description": "Configuration for a specific index",
"properties": {
"enabled": {
"type": "boolean",
"default": true
},
"fields": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fields to include in the index"
},
"materialized": {
"type": "boolean",
"default": false,
"description": "Whether to use a materialized view"
},
"refresh_interval_seconds": {
"type": "integer",
"minimum": 0,
"description": "Refresh interval for materialized views (0 = immediate)"
}
}
},
"BatchVexFetchRequest": {
"type": "object",
"description": "Request for batched VEX document fetches",
"required": ["product_ids"],
"properties": {
"product_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Product identifiers (PURLs, CPEs) to fetch VEX for"
},
"vulnerability_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional: filter to specific vulnerabilities"
},
"include_overlays": {
"type": "boolean",
"default": true,
"description": "Include overlay metadata in response"
},
"include_conflicts": {
"type": "boolean",
"default": false,
"description": "Include conflict markers in response"
},
"max_results": {
"type": "integer",
"minimum": 1,
"maximum": 1000,
"default": 100
},
"continuation_token": {
"type": "string",
"description": "Token for pagination"
}
}
},
"BatchVexFetchResponse": {
"type": "object",
"description": "Response from batched VEX document fetch",
"required": ["results", "total_count"],
"properties": {
"results": {
"type": "array",
"items": {
"$ref": "#/definitions/VexOverlayResult"
}
},
"total_count": {
"type": "integer",
"minimum": 0
},
"continuation_token": {
"type": "string"
},
"fetch_timestamp": {
"type": "string",
"format": "date-time"
}
}
},
"VexOverlayResult": {
"type": "object",
"description": "VEX result with overlay metadata",
"required": ["product_id"],
"properties": {
"product_id": {
"type": "string"
},
"vex_statements": {
"type": "array",
"items": {
"$ref": "#/definitions/VexStatementSummary"
}
},
"overlay": {
"$ref": "#/definitions/LnmOverlay"
},
"conflicts_count": {
"type": "integer",
"minimum": 0
}
}
},
"VexStatementSummary": {
"type": "object",
"description": "Summary of a VEX statement",
"required": ["vulnerability_id", "status"],
"properties": {
"vulnerability_id": {
"type": "string"
},
"status": {
"type": "string",
"enum": ["not_affected", "affected", "fixed", "under_investigation"]
},
"justification": {
"type": "string"
},
"source_ref": {
"$ref": "#/definitions/SourceRef"
},
"timestamp": {
"type": "string",
"format": "date-time"
}
}
},
"GraphInspectorQuery": {
"type": "object",
"description": "Query for the graph inspector UI",
"required": ["query_type"],
"properties": {
"query_type": {
"type": "string",
"enum": [
"entity_neighbors",
"path_between",
"conflicts_for_entity",
"overlay_history",
"affected_products",
"vulnerability_coverage"
]
},
"entity_ref": {
"$ref": "#/definitions/EntityRef"
},
"filters": {
"$ref": "#/definitions/QueryFilters"
},
"depth": {
"type": "integer",
"minimum": 1,
"maximum": 10,
"default": 2,
"description": "Graph traversal depth"
},
"include_metadata": {
"type": "boolean",
"default": true
}
}
},
"QueryFilters": {
"type": "object",
"description": "Filters for graph queries",
"properties": {
"link_types": {
"type": "array",
"items": {
"type": "string"
},
"description": "Filter by link types"
},
"entity_types": {
"type": "array",
"items": {
"type": "string"
},
"description": "Filter by entity types"
},
"source_types": {
"type": "array",
"items": {
"type": "string"
},
"description": "Filter by source types"
},
"time_range": {
"type": "object",
"properties": {
"from": {
"type": "string",
"format": "date-time"
},
"to": {
"type": "string",
"format": "date-time"
}
}
},
"min_confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"include_conflicts": {
"type": "boolean",
"default": false
},
"conflict_status": {
"type": "array",
"items": {
"type": "string",
"enum": ["unresolved", "auto_resolved", "manually_resolved", "deferred"]
}
}
}
}
},
"properties": {
"overlays": {
"type": "array",
"items": {
"$ref": "#/definitions/LnmOverlay"
}
}
},
"examples": [
{
"overlays": [
{
"overlay_id": "550e8400-e29b-41d4-a716-446655440000",
"source_type": "vex",
"source_ref": {
"type": "vex",
"identifier": "CSAF-2025-0001",
"digest": "sha256:abc123def456789...",
"uri": "https://security.vendor.com/csaf/2025-0001.json"
},
"timestamp": "2025-12-06T10:00:00Z",
"version": "1.0.0",
"links": [
{
"link_id": "660e8400-e29b-41d4-a716-446655440001",
"link_type": "affects",
"source": {
"entity_type": "vulnerability",
"identifier": "CVE-2025-1234"
},
"target": {
"entity_type": "component",
"identifier": "pkg:npm/lodash@4.17.20"
},
"confidence": 0.95,
"evidence": [
{
"type": "explicit",
"statement": "Vendor advisory explicitly lists lodash@4.17.20 as affected"
}
]
}
],
"conflicts": [
{
"conflict_id": "770e8400-e29b-41d4-a716-446655440002",
"conflict_type": "status_mismatch",
"entities": [
{
"source_ref": {
"type": "vex",
"identifier": "CSAF-2025-0001"
},
"value": {
"status": "affected"
},
"trust_level": "authoritative",
"precedence": 1
},
{
"source_ref": {
"type": "vex",
"identifier": "OPENVEX-COMM-2025-0001"
},
"value": {
"status": "not_affected"
},
"trust_level": "community",
"precedence": 3
}
],
"resolution_status": "auto_resolved",
"resolution": {
"strategy": "highest_precedence",
"selected_source": {
"type": "vex",
"identifier": "CSAF-2025-0001"
},
"resolved_value": {
"status": "affected"
},
"justification": "Authoritative vendor source has highest precedence",
"resolved_at": "2025-12-06T10:05:00Z",
"resolved_by": "lnm-pipeline"
},
"detected_at": "2025-12-06T10:00:00Z"
}
],
"provenance": {
"created_at": "2025-12-06T10:00:00Z",
"created_by": "lnm-pipeline",
"pipeline_id": "lnm-ingestion-001",
"pipeline_version": "2025.10.0",
"input_digests": [
"sha256:abc123...",
"sha256:def456..."
]
},
"indexes": {
"by_vulnerability": {
"enabled": true,
"fields": ["vulnerability_id", "status", "timestamp"],
"materialized": true,
"refresh_interval_seconds": 60
},
"by_component": {
"enabled": true,
"fields": ["component_purl", "version_range"],
"materialized": false
}
}
}
]
}
]
}