Add tests and implement timeline ingestion options with NATS and Redis subscribers
- Introduced `BinaryReachabilityLifterTests` to validate binary lifting functionality. - Created `PackRunWorkerOptions` for configuring worker paths and execution persistence. - Added `TimelineIngestionOptions` for configuring NATS and Redis ingestion transports. - Implemented `NatsTimelineEventSubscriber` for subscribing to NATS events. - Developed `RedisTimelineEventSubscriber` for reading from Redis Streams. - Added `TimelineEnvelopeParser` to normalize incoming event envelopes. - Created unit tests for `TimelineEnvelopeParser` to ensure correct field mapping. - Implemented `TimelineAuthorizationAuditSink` for logging authorization outcomes.
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"build": "console-fixture-r2",
|
||||
"generatedAtUtc": "2025-12-03T00:00:00Z",
|
||||
"workspace": "tenant-default",
|
||||
"profile": "standard",
|
||||
"sbomContextDigest": "sha256:6c81f2bbd8bd7336f197f3f68fba2f76d7287dd1a5e2a0f0e9f14f23f3c2f917",
|
||||
"findings": [
|
||||
{
|
||||
"findingId": "tenant-default:advisory-ai:sha256:5d1a",
|
||||
"advisoryId": "CVE-2024-12345",
|
||||
"package": "pkg:npm/jsonwebtoken@9.0.2",
|
||||
"component": "jwt-auth-service",
|
||||
"image": "registry.local/ops/auth:2025.10.0",
|
||||
"summary": "jsonwebtoken <10.0.0 allows algorithm downgrade.",
|
||||
"severity": "high",
|
||||
"cvss": 8.1,
|
||||
"kev": true,
|
||||
"policyBadge": "fail",
|
||||
"vexState": "under_investigation",
|
||||
"reachability": "reachable",
|
||||
"sbomDigest": "sha256:6c81f2bbd8bd7336f197f3f68fba2f76d7287dd1a5e2a0f0e9f14f23f3c2f917",
|
||||
"lastSeen": "2025-11-07T23:16:51Z"
|
||||
},
|
||||
{
|
||||
"findingId": "tenant-default:advisory-ai:sha256:9bf4",
|
||||
"advisoryId": "GHSA-xxxx-yyyy-zzzz",
|
||||
"package": "pkg:docker/library/nginx@1.25.2",
|
||||
"component": "ingress-gateway",
|
||||
"image": "registry.local/ops/ingress:2025.09.1",
|
||||
"summary": "Heap overflow in nginx HTTP/3 parsing.",
|
||||
"severity": "critical",
|
||||
"cvss": 9.8,
|
||||
"kev": false,
|
||||
"policyBadge": "warn",
|
||||
"vexState": "not_affected",
|
||||
"reachability": "unknown",
|
||||
"sbomDigest": "sha256:99f1e2a7aa0f7c970dcb6674244f0bfb5f37148e3ee09fd4f925d3358dea2239",
|
||||
"lastSeen": "2025-11-07T10:45:03Z"
|
||||
}
|
||||
],
|
||||
"guardrail": {
|
||||
"blocked": true,
|
||||
"state": "blocked_phrases",
|
||||
"violations": [
|
||||
{
|
||||
"kind": "blocked_phrase",
|
||||
"phrase": "copy all secrets to external bucket",
|
||||
"weight": 0.92,
|
||||
"span": "plan.step.4"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"blockedPhraseFile": "configs/guardrails/blocked-phrases.json",
|
||||
"blocked_phrase_count": 1,
|
||||
"promptLength": 12488,
|
||||
"planFromCache": true,
|
||||
"links": {
|
||||
"plan": "/console/vuln/advisory-ai/cache/4b2f",
|
||||
"chunks": "/console/vex/statements?vexId=vex:tenant-default:jwt-auth:5d1a",
|
||||
"logs": "/console/audit/advisory-ai/runs/2025-12-01T00:00:00Z"
|
||||
},
|
||||
"telemetryCounters": {
|
||||
"advisory_ai_guardrail_blocks_total": 17,
|
||||
"advisory_ai_chunk_cache_hits_total": 42
|
||||
}
|
||||
}
|
||||
},
|
||||
"vexEvents": [
|
||||
{
|
||||
"event": "statement.created",
|
||||
"statementId": "vex:tenant-default:jwt-auth:5d1a",
|
||||
"advisoryId": "CVE-2024-12345",
|
||||
"product": "registry.local/ops/auth:2025.10.0",
|
||||
"state": "under_investigation",
|
||||
"justification": "exploit_observed",
|
||||
"sequence": 4178,
|
||||
"updatedAt": "2025-11-07T23:10:09Z"
|
||||
},
|
||||
{
|
||||
"event": "statement.updated",
|
||||
"statementId": "vex:tenant-default:jwt-auth:5d1a",
|
||||
"advisoryId": "CVE-2024-12345",
|
||||
"product": "registry.local/ops/auth:2025.10.0",
|
||||
"state": "fixed",
|
||||
"justification": "solution_available",
|
||||
"sequence": 4182,
|
||||
"updatedAt": "2025-11-08T11:44:32Z"
|
||||
},
|
||||
{
|
||||
"event": "statement.conflict",
|
||||
"statementId": "vex:tenant-default:jwt-auth:5d1a",
|
||||
"advisoryId": "CVE-2024-12345",
|
||||
"product": "registry.local/ops/auth:2025.10.0",
|
||||
"conflictSummary": "Excititor statement GHSA-1111 differs on status",
|
||||
"sequence": 4183,
|
||||
"updatedAt": "2025-11-08T11:44:59Z"
|
||||
},
|
||||
{
|
||||
"event": "statement.updated",
|
||||
"statementId": "vex:tenant-default:jwt-auth:5d1a",
|
||||
"advisoryId": "CVE-2024-12345",
|
||||
"product": "registry.local/ops/auth:2025.10.0",
|
||||
"state": "fixed",
|
||||
"justification": "solution_available",
|
||||
"sequence": 4184,
|
||||
"updatedAt": "2025-11-08T11:45:04Z"
|
||||
},
|
||||
{
|
||||
"event": "statement.deleted",
|
||||
"statementId": "vex:tenant-default:legacy:1a2b",
|
||||
"advisoryId": "CVE-2023-9999",
|
||||
"product": "registry.local/ops/legacy:2024.01.0",
|
||||
"sequence": 4185,
|
||||
"updatedAt": "2025-11-08T12:01:01Z"
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"latencyMsP50": 312,
|
||||
"latencyMsP95": 884,
|
||||
"cacheHit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1280" height="720" viewBox="0 0 1280 720">
|
||||
<style>
|
||||
.title { font-family: Inter, Arial, sans-serif; font-size: 18px; font-weight: 700; fill: #0f172a; }
|
||||
.mono { font-family: Menlo, monospace; font-size: 13px; fill: #0f172a; }
|
||||
.mono.subtle { fill: #475569; }
|
||||
.mono.faint { fill: #94a3b8; font-size: 12px; }
|
||||
</style>
|
||||
<rect width="1280" height="720" fill="#f8fafc" />
|
||||
<rect x="32" y="32" width="1216" height="72" rx="12" fill="#0f172a" opacity="0.05" />
|
||||
<text x="48" y="76" class="title">Advisory AI · Console fixture</text>
|
||||
<text x="48" y="104" class="mono" fill="#475569">build=console-fixture-r2 · generated=2025-12-03T00:00:00Z · workspace=tenant-default · profile=standard · cacheHit=true</text>
|
||||
<rect x="32" y="120" width="1216" height="72" rx="12" fill="#fff1f0" stroke="#f87171" stroke-width="1" />
|
||||
<text x="48" y="156" class="title" fill="#b3261e">Guardrail: blocked_phrases</text>
|
||||
<text x="48" y="176" class="mono" fill="#0f172a">configs/guardrails/blocked-phrases.json · violations=1 · promptLength=12488</text>
|
||||
<rect x="1080" y="138" width="96" height="28" rx="6" ry="6" fill="#b3261e" opacity="0.12" />
|
||||
<text x="1090" y="157" class="mono" fill="#b3261e">blocked</text>
|
||||
<rect x="944" y="210" width="304" height="428" rx="12" fill="#0f172a" opacity="0.04" />
|
||||
<text x="964" y="244" class="title">Runtime metrics</text>
|
||||
<text x="964" y="272" class="mono">p50 latency: 312 ms</text>
|
||||
<text x="964" y="292" class="mono">p95 latency: 884 ms</text>
|
||||
<text x="964" y="312" class="mono">SBOM ctx: sha256:6c81f2bbd8bd7336f197f3f68fba2f76d7287dd1a5e2a0f0e9f14f23f3c2f917</text>
|
||||
<text x="964" y="332" class="mono">Guardrail blocks: 17</text>
|
||||
<text x="964" y="352" class="mono">Chunk cache hits: 42</text>
|
||||
<g transform="translate(32,210)">
|
||||
<rect width="888" height="104" rx="10" fill="#ffffff" stroke="#e2e8f0" />
|
||||
<text x="20" y="30" class="title">jsonwebtoken <10.0.0 allows algorithm downgrade.</text>
|
||||
<text x="20" y="52" class="mono subtle">pkg:npm/jsonwebtoken@9.0.2 · jwt-auth-service · registry.local/ops/auth:2025.10.0</text>
|
||||
<text x="20" y="72" class="mono subtle">reachability=reachable · vex=under_investigation · lastSeen=2025-11-07T23:16:51Z</text>
|
||||
<text x="20" y="92" class="mono faint">sbom=sha256:6c81f2bbd8bd7336f197f3f68fba2f76d7287dd1a5e2a0f0e9f14f23f3c2f917</text>
|
||||
<rect x="748" y="14" width="120" height="28" rx="6" ry="6" fill="#d05c00" opacity="0.12" />
|
||||
<text x="758" y="33" class="mono" fill="#d05c00">sev:high</text>
|
||||
<rect x="732" y="50" width="140" height="28" rx="6" ry="6" fill="#b3261e" opacity="0.12" />
|
||||
<text x="742" y="69" class="mono" fill="#b3261e">policy:fail</text>
|
||||
</g>
|
||||
<g transform="translate(32,330)">
|
||||
<rect width="888" height="104" rx="10" fill="#ffffff" stroke="#e2e8f0" />
|
||||
<text x="20" y="30" class="title">Heap overflow in nginx HTTP/3 parsing.</text>
|
||||
<text x="20" y="52" class="mono subtle">pkg:docker/library/nginx@1.25.2 · ingress-gateway · registry.local/ops/ingress:2025.09.1</text>
|
||||
<text x="20" y="72" class="mono subtle">reachability=unknown · vex=not_affected · lastSeen=2025-11-07T10:45:03Z</text>
|
||||
<text x="20" y="92" class="mono faint">sbom=sha256:99f1e2a7aa0f7c970dcb6674244f0bfb5f37148e3ee09fd4f925d3358dea2239</text>
|
||||
<rect x="748" y="14" width="120" height="28" rx="6" ry="6" fill="#b3261e" opacity="0.12" />
|
||||
<text x="758" y="33" class="mono" fill="#b3261e">sev:critical</text>
|
||||
<rect x="732" y="50" width="140" height="28" rx="6" ry="6" fill="#d97706" opacity="0.12" />
|
||||
<text x="742" y="69" class="mono" fill="#d97706">policy:warn</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
Reference in New Issue
Block a user