Restructure solution layout by module
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

This commit is contained in:
root
2025-10-28 15:10:40 +02:00
parent 4e3e575db5
commit 68da90a11a
4103 changed files with 192899 additions and 187024 deletions

View File

@@ -1,121 +1,121 @@
# Scanner Orchestrator Events (ORCH-SVC-38-101)
Last updated: 2025-10-26
The Notifications Studio initiative (NOTIFY-SVC-38-001) and orchestrator backlog (ORCH-SVC-38-101) standardise how platform services emit lifecycle events. This document describes the Scanner WebService contract for the new **orchestrator envelopes** (`scanner.event.*`) and how they supersede the legacy Redis-backed `scanner.report.ready` / `scanner.scan.completed` events.
## 1. Envelope overview
Orchestrator events share a deterministic JSON envelope:
| Field | Type | Notes |
|-------|------|-------|
| `eventId` | `uuid` | Globally unique identifier generated per occurrence. |
| `kind` | `string` | Event identifier; Scanner emits `scanner.event.report.ready` and `scanner.event.scan.completed`. |
| `version` | `integer` | Schema version. Initial release uses `1`. |
| `tenant` | `string` | Tenant that owns the scan/report. Mirrors Authority claims. |
| `occurredAt` | `date-time` | UTC instant when the underlying state transition happened (e.g., report persisted). |
| `recordedAt` | `date-time` | UTC instant when the event was durably written. Optional but recommended. |
| `source` | `string` | Producer identifier (`scanner.webservice`). |
| `idempotencyKey` | `string` | Deterministic key for duplicate suppression (see §4). |
| `correlationId` | `string` | Maps back to the API request or scan identifier. |
| `traceId` / `spanId` | `string` | W3C trace context propagated into downstream telemetry. |
| `scope` | `object` | Describes the affected artefact. Requires `repo` and `digest`; optional `namespace`, `component`, `image`. |
| `attributes` | `object` | Flat string map for frequently queried metadata (e.g., policy revision). |
| `payload` | `object` | Event-specific body (see §2). |
Canonical schemas live under `docs/events/scanner.event.*@1.json`. Samples that round-trip through `NotifyCanonicalJsonSerializer` are stored in `docs/events/samples/`.
## 2. Event kinds and payloads
### 2.1 `scanner.event.report.ready`
Emitted once a signed report is persisted and attested. Payload highlights:
- `reportId` / `scanId` — identifiers for the persisted report and originating scan. Until Scan IDs are surfaced by the API, `scanId` mirrors `reportId` so downstream correlators can stabilise on a single key.
- **Attributes:** `reportId`, `policyRevisionId`, `policyDigest`, `verdict` — pre-sorted for deterministic routing.
- **Links:**
- `ui``/ui/reports/{reportId}` on the current host.
- `report``{apiBasePath}/{reportsSegment}/{reportId}` (defaults to `/api/v1/reports/{reportId}`).
- `policy``{apiBasePath}/{policySegment}/revisions/{revisionId}` when a revision is present.
- `attestation``/ui/attestations/{reportId}` when a DSSE envelope is included.
- `imageDigest` — OCI image digest associated with the analysis.
- `generatedAt` — report generation timestamp (ISO-8601 UTC).
- `verdict``pass`, `warn`, or `fail` after policy evaluation.
- `summary` — blocked/warned/ignored/quieted counters (all non-negative integers).
- `delta` — newly critical/high counts and optional `kev` array.
- `quietedFindingCount` — mirrors `summary.quieted`.
- `policy` — revision metadata (`digest`, `revisionId`) surfaced for routing.
- `links` — UI/report/policy URLs suitable for operators.
- `dsse` — embedded DSSE envelope (payload, type, signature list).
- `report` — canonical report document; identical to the DSSE payload.
Schema: `docs/events/scanner.event.report.ready@1.json`
Sample: `docs/events/samples/scanner.event.report.ready@1.sample.json`
### 2.2 `scanner.event.scan.completed`
Emitted after scan execution finishes (success or policy failure). Payload highlights:
- `reportId` / `scanId` / `imageDigest` — identifiers mirroring the report-ready event. As with the report-ready payload, `scanId` currently mirrors `reportId` as a temporary shim.
- **Attributes:** `reportId`, `policyRevisionId`, `policyDigest`, `verdict`.
- **Links:** same as above (`ui`, `report`, `policy`) with `attestation` populated when DSSE metadata exists.
- `verdict`, `summary`, `delta`, `policy` — same semantics as above.
- `findings` — array of surfaced findings with `id`, `severity`, optional `cve`, `purl`, and `reachability`.
- `links`, `dsse`, `report` — same structure as §2.1 (allows Notifier to reuse signatures).
Schema: `docs/events/scanner.event.scan.completed@1.json`
Sample: `docs/events/samples/scanner.event.scan.completed@1.sample.json`
### 2.3 Relationship to legacy events
| Legacy Redis event | Replacement orchestrator event | Notes |
|--------------------|-------------------------------|-------|
| `scanner.report.ready` | `scanner.event.report.ready` | Adds versioning, idempotency, trace context. Payload is a superset of the legacy fields. |
| `scanner.scan.completed` | `scanner.event.scan.completed` | Same data plus explicit scan identifiers and orchestrator metadata. |
Legacy schemas remain for backwards-compatibility during migration, but new integrations **must** target the orchestrator variants.
## 3. Deterministic serialization
- Producers must serialise events using `NotifyCanonicalJsonSerializer` to guarantee consistent key ordering and whitespace.
- Timestamps (`occurredAt`, `recordedAt`, `payload.generatedAt`) use `DateTimeOffset.UtcDateTime.ToString("O")`.
- Payload arrays (`delta.kev`, `findings`) should be pre-sorted (e.g., alphabetical CVE order) so hash-based consumers remain stable.
- Optional fields are omitted rather than emitted as `null`.
## 4. Idempotency and correlation
Idempotency keys dedupe repeated publishes and align with the orchestrators outbox pattern:
| Event kind | Idempotency key template |
|------------|-------------------------|
| `scanner.event.report.ready` | `scanner.event.report.ready:<tenant>:<reportId>` |
| `scanner.event.scan.completed` | `scanner.event.scan.completed:<tenant>:<scanId>` |
Keys are ASCII lowercase; components should be trimmed and validated before concatenation. Retries must reuse the same key.
`correlationId` should match the scan identifier that appears in REST responses (`scanId`). Re-using the same value across the pair of events allows Notifier and orchestrator analytics to stitch lifecycle data together.
## 5. Versioning and evolution
- Increment the `version` field and the `@<version>` suffix for **breaking** changes (field removals, type changes, semantic shifts).
- Additive optional fields may remain within version 1; update the JSON schema and samples accordingly.
- When introducing `@2`, keep the `@1` schema/docs in place until orchestrator subscribers confirm migration.
## 6. Consumer checklist
1. Validate incoming payloads against the schema for the targeted version.
2. Use `idempotencyKey` for dedupe, not `eventId`.
3. Map `traceId`/`spanId` into telemetry spans to preserve causality.
4. Prefer `payload.report``policy.revisionId` when populating templates; the top-level `attributes` are convenience duplicates for quick routing.
5. Reserve the legacy Redis events for transitional compatibility only; downstream systems should subscribe to the orchestrator bus exposed by ORCH-SVC-38-101.
## 7. Implementation status and next actions
- **Scanner WebService** — `SCANNER-EVENTS-16-301` (blocked) and `SCANNER-EVENTS-16-302` (doing) track the production of these envelopes. The remaining blocker is the .NET 10 preview OpenAPI/Auth dependency drift that currently breaks `dotnet test`. Once Gateway and Notifier owners land the replacement packages, rerun the full test suite and capture fresh fixtures under `docs/events/samples/`.
- **Gateway/Notifier consumers** — subscribe to the orchestrator stream documented in ORCH-SVC-38-101. When the Scanner tasks unblock, regenerate notifier contract tests against the sample events included here.
- **Docs cadence** — update this file and the matching JSON schemas whenever payload fields change. Use the rehearsal checklist in `docs/ops/launch-cutover.md` to confirm downstream validation before the production cutover. Record gaps or newly required fields in `docs/ops/launch-readiness.md` so they land in the launch checklist.
---
**Imposed rule reminder:** work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
# Scanner Orchestrator Events (ORCH-SVC-38-101)
Last updated: 2025-10-26
The Notifications Studio initiative (NOTIFY-SVC-38-001) and orchestrator backlog (ORCH-SVC-38-101) standardise how platform services emit lifecycle events. This document describes the Scanner WebService contract for the new **orchestrator envelopes** (`scanner.event.*`) and how they supersede the legacy Redis-backed `scanner.report.ready` / `scanner.scan.completed` events.
## 1. Envelope overview
Orchestrator events share a deterministic JSON envelope:
| Field | Type | Notes |
|-------|------|-------|
| `eventId` | `uuid` | Globally unique identifier generated per occurrence. |
| `kind` | `string` | Event identifier; Scanner emits `scanner.event.report.ready` and `scanner.event.scan.completed`. |
| `version` | `integer` | Schema version. Initial release uses `1`. |
| `tenant` | `string` | Tenant that owns the scan/report. Mirrors Authority claims. |
| `occurredAt` | `date-time` | UTC instant when the underlying state transition happened (e.g., report persisted). |
| `recordedAt` | `date-time` | UTC instant when the event was durably written. Optional but recommended. |
| `source` | `string` | Producer identifier (`scanner.webservice`). |
| `idempotencyKey` | `string` | Deterministic key for duplicate suppression (see §4). |
| `correlationId` | `string` | Maps back to the API request or scan identifier. |
| `traceId` / `spanId` | `string` | W3C trace context propagated into downstream telemetry. |
| `scope` | `object` | Describes the affected artefact. Requires `repo` and `digest`; optional `namespace`, `component`, `image`. |
| `attributes` | `object` | Flat string map for frequently queried metadata (e.g., policy revision). |
| `payload` | `object` | Event-specific body (see §2). |
Canonical schemas live under `docs/events/scanner.event.*@1.json`. Samples that round-trip through `NotifyCanonicalJsonSerializer` are stored in `docs/events/samples/`.
## 2. Event kinds and payloads
### 2.1 `scanner.event.report.ready`
Emitted once a signed report is persisted and attested. Payload highlights:
- `reportId` / `scanId` — identifiers for the persisted report and originating scan. Until Scan IDs are surfaced by the API, `scanId` mirrors `reportId` so downstream correlators can stabilise on a single key.
- **Attributes:** `reportId`, `policyRevisionId`, `policyDigest`, `verdict` — pre-sorted for deterministic routing.
- **Links:**
- `ui``/ui/reports/{reportId}` on the current host.
- `report``{apiBasePath}/{reportsSegment}/{reportId}` (defaults to `/api/v1/reports/{reportId}`).
- `policy``{apiBasePath}/{policySegment}/revisions/{revisionId}` when a revision is present.
- `attestation``/ui/attestations/{reportId}` when a DSSE envelope is included.
- `imageDigest` — OCI image digest associated with the analysis.
- `generatedAt` — report generation timestamp (ISO-8601 UTC).
- `verdict``pass`, `warn`, or `fail` after policy evaluation.
- `summary` — blocked/warned/ignored/quieted counters (all non-negative integers).
- `delta` — newly critical/high counts and optional `kev` array.
- `quietedFindingCount` — mirrors `summary.quieted`.
- `policy` — revision metadata (`digest`, `revisionId`) surfaced for routing.
- `links` — UI/report/policy URLs suitable for operators.
- `dsse` — embedded DSSE envelope (payload, type, signature list).
- `report` — canonical report document; identical to the DSSE payload.
Schema: `docs/events/scanner.event.report.ready@1.json`
Sample: `docs/events/samples/scanner.event.report.ready@1.sample.json`
### 2.2 `scanner.event.scan.completed`
Emitted after scan execution finishes (success or policy failure). Payload highlights:
- `reportId` / `scanId` / `imageDigest` — identifiers mirroring the report-ready event. As with the report-ready payload, `scanId` currently mirrors `reportId` as a temporary shim.
- **Attributes:** `reportId`, `policyRevisionId`, `policyDigest`, `verdict`.
- **Links:** same as above (`ui`, `report`, `policy`) with `attestation` populated when DSSE metadata exists.
- `verdict`, `summary`, `delta`, `policy` — same semantics as above.
- `findings` — array of surfaced findings with `id`, `severity`, optional `cve`, `purl`, and `reachability`.
- `links`, `dsse`, `report` — same structure as §2.1 (allows Notifier to reuse signatures).
Schema: `docs/events/scanner.event.scan.completed@1.json`
Sample: `docs/events/samples/scanner.event.scan.completed@1.sample.json`
### 2.3 Relationship to legacy events
| Legacy Redis event | Replacement orchestrator event | Notes |
|--------------------|-------------------------------|-------|
| `scanner.report.ready` | `scanner.event.report.ready` | Adds versioning, idempotency, trace context. Payload is a superset of the legacy fields. |
| `scanner.scan.completed` | `scanner.event.scan.completed` | Same data plus explicit scan identifiers and orchestrator metadata. |
Legacy schemas remain for backwards-compatibility during migration, but new integrations **must** target the orchestrator variants.
## 3. Deterministic serialization
- Producers must serialise events using `NotifyCanonicalJsonSerializer` to guarantee consistent key ordering and whitespace.
- Timestamps (`occurredAt`, `recordedAt`, `payload.generatedAt`) use `DateTimeOffset.UtcDateTime.ToString("O")`.
- Payload arrays (`delta.kev`, `findings`) should be pre-sorted (e.g., alphabetical CVE order) so hash-based consumers remain stable.
- Optional fields are omitted rather than emitted as `null`.
## 4. Idempotency and correlation
Idempotency keys dedupe repeated publishes and align with the orchestrators outbox pattern:
| Event kind | Idempotency key template |
|------------|-------------------------|
| `scanner.event.report.ready` | `scanner.event.report.ready:<tenant>:<reportId>` |
| `scanner.event.scan.completed` | `scanner.event.scan.completed:<tenant>:<scanId>` |
Keys are ASCII lowercase; components should be trimmed and validated before concatenation. Retries must reuse the same key.
`correlationId` should match the scan identifier that appears in REST responses (`scanId`). Re-using the same value across the pair of events allows Notifier and orchestrator analytics to stitch lifecycle data together.
## 5. Versioning and evolution
- Increment the `version` field and the `@<version>` suffix for **breaking** changes (field removals, type changes, semantic shifts).
- Additive optional fields may remain within version 1; update the JSON schema and samples accordingly.
- When introducing `@2`, keep the `@1` schema/docs in place until orchestrator subscribers confirm migration.
## 6. Consumer checklist
1. Validate incoming payloads against the schema for the targeted version.
2. Use `idempotencyKey` for dedupe, not `eventId`.
3. Map `traceId`/`spanId` into telemetry spans to preserve causality.
4. Prefer `payload.report``policy.revisionId` when populating templates; the top-level `attributes` are convenience duplicates for quick routing.
5. Reserve the legacy Redis events for transitional compatibility only; downstream systems should subscribe to the orchestrator bus exposed by ORCH-SVC-38-101.
## 7. Implementation status and next actions
- **Scanner WebService** — `SCANNER-EVENTS-16-301` (blocked) and `SCANNER-EVENTS-16-302` (doing) track the production of these envelopes. The remaining blocker is the .NET 10 preview OpenAPI/Auth dependency drift that currently breaks `dotnet test`. Once Gateway and Notifier owners land the replacement packages, rerun the full test suite and capture fresh fixtures under `docs/events/samples/`.
- **Gateway/Notifier consumers** — subscribe to the orchestrator stream documented in ORCH-SVC-38-101. When the Scanner tasks unblock, regenerate notifier contract tests against the sample events included here.
- **Docs cadence** — update this file and the matching JSON schemas whenever payload fields change. Use the rehearsal checklist in `docs/ops/launch-cutover.md` to confirm downstream validation before the production cutover. Record gaps or newly required fields in `docs/ops/launch-readiness.md` so they land in the launch checklist.
---
**Imposed rule reminder:** work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.

View File

@@ -1,93 +1,93 @@
{
"eventId": "6d2d1b77-f3c3-4f70-8a9d-6f2d0c8801ab",
"kind": "scanner.event.report.ready",
"version": 1,
"tenant": "tenant-alpha",
"occurredAt": "2025-10-19T12:34:56Z",
"recordedAt": "2025-10-19T12:34:57Z",
"source": "scanner.webservice",
"idempotencyKey": "scanner.event.report.ready:tenant-alpha:report-abc",
"correlationId": "report-abc",
"traceId": "0af7651916cd43dd8448eb211c80319c",
"spanId": "b7ad6b7169203331",
"scope": {
"namespace": "acme/edge",
"repo": "api",
"digest": "sha256:feedface"
},
"attributes": {
"reportId": "report-abc",
"policyRevisionId": "rev-42",
"policyDigest": "digest-123",
"verdict": "blocked"
},
"payload": {
"reportId": "report-abc",
"scanId": "report-abc",
"imageDigest": "sha256:feedface",
"generatedAt": "2025-10-19T12:34:56Z",
"verdict": "fail",
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"delta": {
"newCritical": 1,
"kev": [
"CVE-2024-9999"
]
},
"quietedFindingCount": 0,
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"links": {
"ui": "https://scanner.example/ui/reports/report-abc",
"report": "https://scanner.example/api/v1/reports/report-abc",
"policy": "https://scanner.example/api/v1/policy/revisions/rev-42",
"attestation": "https://scanner.example/ui/attestations/report-abc"
},
"dsse": {
"payloadType": "application/vnd.stellaops.report+json",
"payload": "eyJyZXBvcnRJZCI6InJlcG9ydC1hYmMiLCJpbWFnZURpZ2VzdCI6InNoYTI1NjpmZWVkZmFjZSIsImdlbmVyYXRlZEF0IjoiMjAyNS0xMC0xOVQxMjozNDo1NiswMDowMCIsInZlcmRpY3QiOiJibG9ja2VkIiwicG9saWN5Ijp7InJldmlzaW9uSWQiOiJyZXYtNDIiLCJkaWdlc3QiOiJkaWdlc3QtMTIzIn0sInN1bW1hcnkiOnsidG90YWwiOjEsImJsb2NrZWQiOjEsIndhcm5lZCI6MCwiaWdub3JlZCI6MCwicXVpZXRlZCI6MH0sInZlcmRpY3RzIjpbeyJmaW5kaW5nSWQiOiJmaW5kaW5nLTEiLCJzdGF0dXMiOiJCbG9ja2VkIiwic2NvcmUiOjQ3LjUsInNvdXJjZVRydXN0IjoiTlZEIiwicmVhY2hhYmlsaXR5IjoicnVudGltZSJ9XSwiaXNzdWVzIjpbXX0=",
"signatures": [
{
"keyId": "test-key",
"algorithm": "hs256",
"signature": "signature-value"
}
]
},
"report": {
"reportId": "report-abc",
"generatedAt": "2025-10-19T12:34:56Z",
"imageDigest": "sha256:feedface",
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"verdict": "blocked",
"verdicts": [
{
"findingId": "finding-1",
"status": "Blocked",
"score": 47.5,
"sourceTrust": "NVD",
"reachability": "runtime"
}
],
"issues": []
}
}
}
{
"eventId": "6d2d1b77-f3c3-4f70-8a9d-6f2d0c8801ab",
"kind": "scanner.event.report.ready",
"version": 1,
"tenant": "tenant-alpha",
"occurredAt": "2025-10-19T12:34:56Z",
"recordedAt": "2025-10-19T12:34:57Z",
"source": "scanner.webservice",
"idempotencyKey": "scanner.event.report.ready:tenant-alpha:report-abc",
"correlationId": "report-abc",
"traceId": "0af7651916cd43dd8448eb211c80319c",
"spanId": "b7ad6b7169203331",
"scope": {
"namespace": "acme/edge",
"repo": "api",
"digest": "sha256:feedface"
},
"attributes": {
"reportId": "report-abc",
"policyRevisionId": "rev-42",
"policyDigest": "digest-123",
"verdict": "blocked"
},
"payload": {
"reportId": "report-abc",
"scanId": "report-abc",
"imageDigest": "sha256:feedface",
"generatedAt": "2025-10-19T12:34:56Z",
"verdict": "fail",
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"delta": {
"newCritical": 1,
"kev": [
"CVE-2024-9999"
]
},
"quietedFindingCount": 0,
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"links": {
"ui": "https://scanner.example/ui/reports/report-abc",
"report": "https://scanner.example/api/v1/reports/report-abc",
"policy": "https://scanner.example/api/v1/policy/revisions/rev-42",
"attestation": "https://scanner.example/ui/attestations/report-abc"
},
"dsse": {
"payloadType": "application/vnd.stellaops.report+json",
"payload": "eyJyZXBvcnRJZCI6InJlcG9ydC1hYmMiLCJpbWFnZURpZ2VzdCI6InNoYTI1NjpmZWVkZmFjZSIsImdlbmVyYXRlZEF0IjoiMjAyNS0xMC0xOVQxMjozNDo1NiswMDowMCIsInZlcmRpY3QiOiJibG9ja2VkIiwicG9saWN5Ijp7InJldmlzaW9uSWQiOiJyZXYtNDIiLCJkaWdlc3QiOiJkaWdlc3QtMTIzIn0sInN1bW1hcnkiOnsidG90YWwiOjEsImJsb2NrZWQiOjEsIndhcm5lZCI6MCwiaWdub3JlZCI6MCwicXVpZXRlZCI6MH0sInZlcmRpY3RzIjpbeyJmaW5kaW5nSWQiOiJmaW5kaW5nLTEiLCJzdGF0dXMiOiJCbG9ja2VkIiwic2NvcmUiOjQ3LjUsInNvdXJjZVRydXN0IjoiTlZEIiwicmVhY2hhYmlsaXR5IjoicnVudGltZSJ9XSwiaXNzdWVzIjpbXX0=",
"signatures": [
{
"keyId": "test-key",
"algorithm": "hs256",
"signature": "signature-value"
}
]
},
"report": {
"reportId": "report-abc",
"generatedAt": "2025-10-19T12:34:56Z",
"imageDigest": "sha256:feedface",
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"verdict": "blocked",
"verdicts": [
{
"findingId": "finding-1",
"status": "Blocked",
"score": 47.5,
"sourceTrust": "NVD",
"reachability": "runtime"
}
],
"issues": []
}
}
}

View File

@@ -1,99 +1,99 @@
{
"eventId": "08a6de24-4a94-4d14-8432-9d14f36f6da3",
"kind": "scanner.event.scan.completed",
"version": 1,
"tenant": "tenant-alpha",
"occurredAt": "2025-10-19T12:34:56Z",
"recordedAt": "2025-10-19T12:34:57Z",
"source": "scanner.webservice",
"idempotencyKey": "scanner.event.scan.completed:tenant-alpha:report-abc",
"correlationId": "report-abc",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"scope": {
"namespace": "acme/edge",
"repo": "api",
"digest": "sha256:feedface"
},
"attributes": {
"reportId": "report-abc",
"policyRevisionId": "rev-42",
"policyDigest": "digest-123",
"verdict": "blocked"
},
"payload": {
"reportId": "report-abc",
"scanId": "report-abc",
"imageDigest": "sha256:feedface",
"verdict": "fail",
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"delta": {
"newCritical": 1,
"kev": [
"CVE-2024-9999"
]
},
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"findings": [
{
"id": "finding-1",
"severity": "Critical",
"cve": "CVE-2024-9999",
"purl": "pkg:docker/acme/edge-api@sha256-feedface",
"reachability": "runtime"
}
],
"links": {
"ui": "https://scanner.example/ui/reports/report-abc",
"report": "https://scanner.example/api/v1/reports/report-abc",
"policy": "https://scanner.example/api/v1/policy/revisions/rev-42",
"attestation": "https://scanner.example/ui/attestations/report-abc"
},
"dsse": {
"payloadType": "application/vnd.stellaops.report+json",
"payload": "eyJyZXBvcnRJZCI6InJlcG9ydC1hYmMiLCJpbWFnZURpZ2VzdCI6InNoYTI1NjpmZWVkZmFjZSIsImdlbmVyYXRlZEF0IjoiMjAyNS0xMC0xOVQxMjozNDo1NiswMDowMCIsInZlcmRpY3QiOiJibG9ja2VkIiwicG9saWN5Ijp7InJldmlzaW9uSWQiOiJyZXYtNDIiLCJkaWdlc3QiOiJkaWdlc3QtMTIzIn0sInN1bW1hcnkiOnsidG90YWwiOjEsImJsb2NrZWQiOjEsIndhcm5lZCI6MCwiaWdub3JlZCI6MCwicXVpZXRlZCI6MH0sInZlcmRpY3RzIjpbeyJmaW5kaW5nSWQiOiJmaW5kaW5nLTEiLCJzdGF0dXMiOiJCbG9ja2VkIiwic2NvcmUiOjQ3LjUsInNvdXJjZVRydXN0IjoiTlZEIiwicmVhY2hhYmlsaXR5IjoicnVudGltZSJ9XSwiaXNzdWVzIjpbXX0=",
"signatures": [
{
"keyId": "test-key",
"algorithm": "hs256",
"signature": "signature-value"
}
]
},
"report": {
"reportId": "report-abc",
"generatedAt": "2025-10-19T12:34:56Z",
"imageDigest": "sha256:feedface",
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"verdict": "blocked",
"verdicts": [
{
"findingId": "finding-1",
"status": "Blocked",
"score": 47.5,
"sourceTrust": "NVD",
"reachability": "runtime"
}
],
"issues": []
}
}
}
{
"eventId": "08a6de24-4a94-4d14-8432-9d14f36f6da3",
"kind": "scanner.event.scan.completed",
"version": 1,
"tenant": "tenant-alpha",
"occurredAt": "2025-10-19T12:34:56Z",
"recordedAt": "2025-10-19T12:34:57Z",
"source": "scanner.webservice",
"idempotencyKey": "scanner.event.scan.completed:tenant-alpha:report-abc",
"correlationId": "report-abc",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"scope": {
"namespace": "acme/edge",
"repo": "api",
"digest": "sha256:feedface"
},
"attributes": {
"reportId": "report-abc",
"policyRevisionId": "rev-42",
"policyDigest": "digest-123",
"verdict": "blocked"
},
"payload": {
"reportId": "report-abc",
"scanId": "report-abc",
"imageDigest": "sha256:feedface",
"verdict": "fail",
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"delta": {
"newCritical": 1,
"kev": [
"CVE-2024-9999"
]
},
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"findings": [
{
"id": "finding-1",
"severity": "Critical",
"cve": "CVE-2024-9999",
"purl": "pkg:docker/acme/edge-api@sha256-feedface",
"reachability": "runtime"
}
],
"links": {
"ui": "https://scanner.example/ui/reports/report-abc",
"report": "https://scanner.example/api/v1/reports/report-abc",
"policy": "https://scanner.example/api/v1/policy/revisions/rev-42",
"attestation": "https://scanner.example/ui/attestations/report-abc"
},
"dsse": {
"payloadType": "application/vnd.stellaops.report+json",
"payload": "eyJyZXBvcnRJZCI6InJlcG9ydC1hYmMiLCJpbWFnZURpZ2VzdCI6InNoYTI1NjpmZWVkZmFjZSIsImdlbmVyYXRlZEF0IjoiMjAyNS0xMC0xOVQxMjozNDo1NiswMDowMCIsInZlcmRpY3QiOiJibG9ja2VkIiwicG9saWN5Ijp7InJldmlzaW9uSWQiOiJyZXYtNDIiLCJkaWdlc3QiOiJkaWdlc3QtMTIzIn0sInN1bW1hcnkiOnsidG90YWwiOjEsImJsb2NrZWQiOjEsIndhcm5lZCI6MCwiaWdub3JlZCI6MCwicXVpZXRlZCI6MH0sInZlcmRpY3RzIjpbeyJmaW5kaW5nSWQiOiJmaW5kaW5nLTEiLCJzdGF0dXMiOiJCbG9ja2VkIiwic2NvcmUiOjQ3LjUsInNvdXJjZVRydXN0IjoiTlZEIiwicmVhY2hhYmlsaXR5IjoicnVudGltZSJ9XSwiaXNzdWVzIjpbXX0=",
"signatures": [
{
"keyId": "test-key",
"algorithm": "hs256",
"signature": "signature-value"
}
]
},
"report": {
"reportId": "report-abc",
"generatedAt": "2025-10-19T12:34:56Z",
"imageDigest": "sha256:feedface",
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"verdict": "blocked",
"verdicts": [
{
"findingId": "finding-1",
"status": "Blocked",
"score": 47.5,
"sourceTrust": "NVD",
"reachability": "runtime"
}
],
"issues": []
}
}
}

View File

@@ -1,36 +1,36 @@
{
"eventId": "4d33c19c-1c8a-44d1-9954-1d5e98b2af71",
"kind": "scheduler.graph.job.completed",
"tenant": "tenant-alpha",
"ts": "2025-10-26T12:00:45Z",
"payload": {
"jobType": "build",
"status": "completed",
"occurredAt": "2025-10-26T12:00:45Z",
"job": {
"schemaVersion": "scheduler.graph-build-job@1",
"id": "gbj_20251026a",
"tenantId": "tenant-alpha",
"sbomId": "sbom_20251026",
"sbomVersionId": "sbom_ver_20251026",
"sbomDigest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"graphSnapshotId": "graph_snap_20251026",
"status": "completed",
"trigger": "sbom-version",
"attempts": 1,
"cartographerJobId": "carto_job_42",
"correlationId": "evt_svc_987",
"createdAt": "2025-10-26T12:00:00+00:00",
"startedAt": "2025-10-26T12:00:05+00:00",
"completedAt": "2025-10-26T12:00:45+00:00",
"metadata": {
"sbomEventId": "sbom_evt_20251026"
}
},
"resultUri": "oras://cartographer/offline/tenant-alpha/graph_snap_20251026"
},
"attributes": {
"cartographerCluster": "offline-kit",
"plannerShard": "graph-builders-01"
}
}
{
"eventId": "4d33c19c-1c8a-44d1-9954-1d5e98b2af71",
"kind": "scheduler.graph.job.completed",
"tenant": "tenant-alpha",
"ts": "2025-10-26T12:00:45Z",
"payload": {
"jobType": "build",
"status": "completed",
"occurredAt": "2025-10-26T12:00:45Z",
"job": {
"schemaVersion": "scheduler.graph-build-job@1",
"id": "gbj_20251026a",
"tenantId": "tenant-alpha",
"sbomId": "sbom_20251026",
"sbomVersionId": "sbom_ver_20251026",
"sbomDigest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"graphSnapshotId": "graph_snap_20251026",
"status": "completed",
"trigger": "sbom-version",
"attempts": 1,
"cartographerJobId": "carto_job_42",
"correlationId": "evt_svc_987",
"createdAt": "2025-10-26T12:00:00+00:00",
"startedAt": "2025-10-26T12:00:05+00:00",
"completedAt": "2025-10-26T12:00:45+00:00",
"metadata": {
"sbomEventId": "sbom_evt_20251026"
}
},
"resultUri": "oras://cartographer/offline/tenant-alpha/graph_snap_20251026"
},
"attributes": {
"cartographerCluster": "offline-kit",
"plannerShard": "graph-builders-01"
}
}

View File

@@ -1,164 +1,164 @@
{
"$id": "https://stella-ops.org/schemas/events/scanner.event.report.ready@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Scanner orchestrator event report ready (v1)",
"type": "object",
"additionalProperties": false,
"required": [
"eventId",
"kind",
"version",
"tenant",
"occurredAt",
"source",
"idempotencyKey",
"payload"
],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Globally unique identifier for this occurrence."
},
"kind": {
"const": "scanner.event.report.ready",
"description": "Event kind identifier consumed by orchestrator subscribers."
},
"version": {
"const": 1,
"description": "Schema version for orchestrator envelopes."
},
"tenant": {
"type": "string",
"description": "Tenant that owns the scan/report."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp (UTC) when the report transitioned to ready."
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp (UTC) when the event was persisted. Optional."
},
"source": {
"type": "string",
"description": "Producer identifier, e.g. `scanner.webservice`."
},
"idempotencyKey": {
"type": "string",
"minLength": 8,
"description": "Deterministic key used to deduplicate events downstream."
},
"correlationId": {
"type": "string",
"description": "Correlation identifier that ties this event to a request or workflow."
},
"traceId": {
"type": "string",
"description": "W3C trace ID (32 hex chars) for distributed tracing."
},
"spanId": {
"type": "string",
"description": "Optional span identifier associated with traceId."
},
"scope": {
"type": "object",
"additionalProperties": false,
"required": ["repo", "digest"],
"properties": {
"namespace": {"type": "string"},
"repo": {"type": "string"},
"digest": {"type": "string"},
"component": {"type": "string"},
"image": {"type": "string"}
}
},
"attributes": {
"type": "object",
"description": "String attributes for downstream correlation (policy revision, scan id, etc.).",
"additionalProperties": {"type": "string"}
},
"payload": {
"type": "object",
"additionalProperties": true,
"required": ["reportId", "verdict", "summary", "links", "report"],
"properties": {
"reportId": {"type": "string"},
"scanId": {"type": "string"},
"imageDigest": {"type": "string"},
"generatedAt": {"type": "string", "format": "date-time"},
"verdict": {"enum": ["pass", "warn", "fail"]},
"summary": {
"type": "object",
"additionalProperties": false,
"required": ["total", "blocked", "warned", "ignored", "quieted"],
"properties": {
"total": {"type": "integer", "minimum": 0},
"blocked": {"type": "integer", "minimum": 0},
"warned": {"type": "integer", "minimum": 0},
"ignored": {"type": "integer", "minimum": 0},
"quieted": {"type": "integer", "minimum": 0}
}
},
"delta": {
"type": "object",
"additionalProperties": false,
"properties": {
"newCritical": {"type": "integer", "minimum": 0},
"newHigh": {"type": "integer", "minimum": 0},
"kev": {
"type": "array",
"items": {"type": "string"}
}
}
},
"quietedFindingCount": {
"type": "integer",
"minimum": 0
},
"policy": {
"type": "object",
"description": "Policy revision metadata surfaced alongside the report."
},
"links": {
"type": "object",
"additionalProperties": false,
"properties": {
"ui": {"type": "string", "format": "uri"},
"report": {"type": "string", "format": "uri"},
"policy": {"type": "string", "format": "uri"},
"attestation": {"type": "string", "format": "uri"}
}
},
"dsse": {
"type": "object",
"additionalProperties": false,
"required": ["payloadType", "payload", "signatures"],
"properties": {
"payloadType": {"type": "string"},
"payload": {"type": "string"},
"signatures": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["keyId", "algorithm", "signature"],
"properties": {
"keyId": {"type": "string"},
"algorithm": {"type": "string"},
"signature": {"type": "string"}
}
}
}
}
},
"report": {
"type": "object",
"description": "Canonical scanner report document that aligns with the DSSE payload."
}
}
}
}
}
{
"$id": "https://stella-ops.org/schemas/events/scanner.event.report.ready@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Scanner orchestrator event report ready (v1)",
"type": "object",
"additionalProperties": false,
"required": [
"eventId",
"kind",
"version",
"tenant",
"occurredAt",
"source",
"idempotencyKey",
"payload"
],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Globally unique identifier for this occurrence."
},
"kind": {
"const": "scanner.event.report.ready",
"description": "Event kind identifier consumed by orchestrator subscribers."
},
"version": {
"const": 1,
"description": "Schema version for orchestrator envelopes."
},
"tenant": {
"type": "string",
"description": "Tenant that owns the scan/report."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp (UTC) when the report transitioned to ready."
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp (UTC) when the event was persisted. Optional."
},
"source": {
"type": "string",
"description": "Producer identifier, e.g. `scanner.webservice`."
},
"idempotencyKey": {
"type": "string",
"minLength": 8,
"description": "Deterministic key used to deduplicate events downstream."
},
"correlationId": {
"type": "string",
"description": "Correlation identifier that ties this event to a request or workflow."
},
"traceId": {
"type": "string",
"description": "W3C trace ID (32 hex chars) for distributed tracing."
},
"spanId": {
"type": "string",
"description": "Optional span identifier associated with traceId."
},
"scope": {
"type": "object",
"additionalProperties": false,
"required": ["repo", "digest"],
"properties": {
"namespace": {"type": "string"},
"repo": {"type": "string"},
"digest": {"type": "string"},
"component": {"type": "string"},
"image": {"type": "string"}
}
},
"attributes": {
"type": "object",
"description": "String attributes for downstream correlation (policy revision, scan id, etc.).",
"additionalProperties": {"type": "string"}
},
"payload": {
"type": "object",
"additionalProperties": true,
"required": ["reportId", "verdict", "summary", "links", "report"],
"properties": {
"reportId": {"type": "string"},
"scanId": {"type": "string"},
"imageDigest": {"type": "string"},
"generatedAt": {"type": "string", "format": "date-time"},
"verdict": {"enum": ["pass", "warn", "fail"]},
"summary": {
"type": "object",
"additionalProperties": false,
"required": ["total", "blocked", "warned", "ignored", "quieted"],
"properties": {
"total": {"type": "integer", "minimum": 0},
"blocked": {"type": "integer", "minimum": 0},
"warned": {"type": "integer", "minimum": 0},
"ignored": {"type": "integer", "minimum": 0},
"quieted": {"type": "integer", "minimum": 0}
}
},
"delta": {
"type": "object",
"additionalProperties": false,
"properties": {
"newCritical": {"type": "integer", "minimum": 0},
"newHigh": {"type": "integer", "minimum": 0},
"kev": {
"type": "array",
"items": {"type": "string"}
}
}
},
"quietedFindingCount": {
"type": "integer",
"minimum": 0
},
"policy": {
"type": "object",
"description": "Policy revision metadata surfaced alongside the report."
},
"links": {
"type": "object",
"additionalProperties": false,
"properties": {
"ui": {"type": "string", "format": "uri"},
"report": {"type": "string", "format": "uri"},
"policy": {"type": "string", "format": "uri"},
"attestation": {"type": "string", "format": "uri"}
}
},
"dsse": {
"type": "object",
"additionalProperties": false,
"required": ["payloadType", "payload", "signatures"],
"properties": {
"payloadType": {"type": "string"},
"payload": {"type": "string"},
"signatures": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["keyId", "algorithm", "signature"],
"properties": {
"keyId": {"type": "string"},
"algorithm": {"type": "string"},
"signature": {"type": "string"}
}
}
}
}
},
"report": {
"type": "object",
"description": "Canonical scanner report document that aligns with the DSSE payload."
}
}
}
}
}

View File

@@ -1,174 +1,174 @@
{
"$id": "https://stella-ops.org/schemas/events/scanner.event.scan.completed@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Scanner orchestrator event scan completed (v1)",
"type": "object",
"additionalProperties": false,
"required": [
"eventId",
"kind",
"version",
"tenant",
"occurredAt",
"source",
"idempotencyKey",
"payload"
],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Globally unique identifier for this occurrence."
},
"kind": {
"const": "scanner.event.scan.completed",
"description": "Event kind identifier consumed by orchestrator subscribers."
},
"version": {
"const": 1,
"description": "Schema version for orchestrator envelopes."
},
"tenant": {
"type": "string",
"description": "Tenant that owns the scan."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp (UTC) when the scan completed."
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp (UTC) when the event was persisted. Optional."
},
"source": {
"type": "string",
"description": "Producer identifier, e.g. `scanner.webservice`."
},
"idempotencyKey": {
"type": "string",
"minLength": 8,
"description": "Deterministic key used to deduplicate events downstream."
},
"correlationId": {
"type": "string",
"description": "Correlation identifier tying this event to a request or workflow."
},
"traceId": {
"type": "string",
"description": "W3C trace ID (32 hex chars) for distributed tracing."
},
"spanId": {
"type": "string",
"description": "Optional span identifier associated with traceId."
},
"scope": {
"type": "object",
"additionalProperties": false,
"required": ["repo", "digest"],
"properties": {
"namespace": {"type": "string"},
"repo": {"type": "string"},
"digest": {"type": "string"},
"component": {"type": "string"},
"image": {"type": "string"}
}
},
"attributes": {
"type": "object",
"description": "String attributes for downstream correlation (policy revision, scan id, etc.).",
"additionalProperties": {"type": "string"}
},
"payload": {
"type": "object",
"additionalProperties": true,
"required": ["reportId", "scanId", "imageDigest", "verdict", "summary", "report"],
"properties": {
"reportId": {"type": "string"},
"scanId": {"type": "string"},
"imageDigest": {"type": "string"},
"verdict": {"enum": ["pass", "warn", "fail"]},
"summary": {
"type": "object",
"additionalProperties": false,
"required": ["total", "blocked", "warned", "ignored", "quieted"],
"properties": {
"total": {"type": "integer", "minimum": 0},
"blocked": {"type": "integer", "minimum": 0},
"warned": {"type": "integer", "minimum": 0},
"ignored": {"type": "integer", "minimum": 0},
"quieted": {"type": "integer", "minimum": 0}
}
},
"delta": {
"type": "object",
"additionalProperties": false,
"properties": {
"newCritical": {"type": "integer", "minimum": 0},
"newHigh": {"type": "integer", "minimum": 0},
"kev": {
"type": "array",
"items": {"type": "string"}
}
}
},
"policy": {
"type": "object",
"description": "Policy revision metadata surfaced alongside the report."
},
"findings": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["id"],
"properties": {
"id": {"type": "string"},
"severity": {"type": "string"},
"cve": {"type": "string"},
"purl": {"type": "string"},
"reachability": {"type": "string"}
}
}
},
"links": {
"type": "object",
"additionalProperties": false,
"properties": {
"ui": {"type": "string", "format": "uri"},
"report": {"type": "string", "format": "uri"},
"policy": {"type": "string", "format": "uri"},
"attestation": {"type": "string", "format": "uri"}
}
},
"dsse": {
"type": "object",
"additionalProperties": false,
"required": ["payloadType", "payload", "signatures"],
"properties": {
"payloadType": {"type": "string"},
"payload": {"type": "string"},
"signatures": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["keyId", "algorithm", "signature"],
"properties": {
"keyId": {"type": "string"},
"algorithm": {"type": "string"},
"signature": {"type": "string"}
}
}
}
}
},
"report": {
"type": "object",
"description": "Canonical scanner report document that aligns with the DSSE payload."
}
}
}
}
}
{
"$id": "https://stella-ops.org/schemas/events/scanner.event.scan.completed@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Scanner orchestrator event scan completed (v1)",
"type": "object",
"additionalProperties": false,
"required": [
"eventId",
"kind",
"version",
"tenant",
"occurredAt",
"source",
"idempotencyKey",
"payload"
],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Globally unique identifier for this occurrence."
},
"kind": {
"const": "scanner.event.scan.completed",
"description": "Event kind identifier consumed by orchestrator subscribers."
},
"version": {
"const": 1,
"description": "Schema version for orchestrator envelopes."
},
"tenant": {
"type": "string",
"description": "Tenant that owns the scan."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp (UTC) when the scan completed."
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp (UTC) when the event was persisted. Optional."
},
"source": {
"type": "string",
"description": "Producer identifier, e.g. `scanner.webservice`."
},
"idempotencyKey": {
"type": "string",
"minLength": 8,
"description": "Deterministic key used to deduplicate events downstream."
},
"correlationId": {
"type": "string",
"description": "Correlation identifier tying this event to a request or workflow."
},
"traceId": {
"type": "string",
"description": "W3C trace ID (32 hex chars) for distributed tracing."
},
"spanId": {
"type": "string",
"description": "Optional span identifier associated with traceId."
},
"scope": {
"type": "object",
"additionalProperties": false,
"required": ["repo", "digest"],
"properties": {
"namespace": {"type": "string"},
"repo": {"type": "string"},
"digest": {"type": "string"},
"component": {"type": "string"},
"image": {"type": "string"}
}
},
"attributes": {
"type": "object",
"description": "String attributes for downstream correlation (policy revision, scan id, etc.).",
"additionalProperties": {"type": "string"}
},
"payload": {
"type": "object",
"additionalProperties": true,
"required": ["reportId", "scanId", "imageDigest", "verdict", "summary", "report"],
"properties": {
"reportId": {"type": "string"},
"scanId": {"type": "string"},
"imageDigest": {"type": "string"},
"verdict": {"enum": ["pass", "warn", "fail"]},
"summary": {
"type": "object",
"additionalProperties": false,
"required": ["total", "blocked", "warned", "ignored", "quieted"],
"properties": {
"total": {"type": "integer", "minimum": 0},
"blocked": {"type": "integer", "minimum": 0},
"warned": {"type": "integer", "minimum": 0},
"ignored": {"type": "integer", "minimum": 0},
"quieted": {"type": "integer", "minimum": 0}
}
},
"delta": {
"type": "object",
"additionalProperties": false,
"properties": {
"newCritical": {"type": "integer", "minimum": 0},
"newHigh": {"type": "integer", "minimum": 0},
"kev": {
"type": "array",
"items": {"type": "string"}
}
}
},
"policy": {
"type": "object",
"description": "Policy revision metadata surfaced alongside the report."
},
"findings": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["id"],
"properties": {
"id": {"type": "string"},
"severity": {"type": "string"},
"cve": {"type": "string"},
"purl": {"type": "string"},
"reachability": {"type": "string"}
}
}
},
"links": {
"type": "object",
"additionalProperties": false,
"properties": {
"ui": {"type": "string", "format": "uri"},
"report": {"type": "string", "format": "uri"},
"policy": {"type": "string", "format": "uri"},
"attestation": {"type": "string", "format": "uri"}
}
},
"dsse": {
"type": "object",
"additionalProperties": false,
"required": ["payloadType", "payload", "signatures"],
"properties": {
"payloadType": {"type": "string"},
"payload": {"type": "string"},
"signatures": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["keyId", "algorithm", "signature"],
"properties": {
"keyId": {"type": "string"},
"algorithm": {"type": "string"},
"signature": {"type": "string"}
}
}
}
}
},
"report": {
"type": "object",
"description": "Canonical scanner report document that aligns with the DSSE payload."
}
}
}
}
}

View File

@@ -1,196 +1,196 @@
{
"$id": "https://stella-ops.org/schemas/events/scheduler.graph.job.completed@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Scheduler Graph Job Completed Event",
"description": "Legacy scheduler event emitted when a graph build or overlay job reaches a terminal state. Consumers validate downstream caches and surface overlay freshness.",
"type": "object",
"additionalProperties": false,
"required": ["eventId", "kind", "tenant", "ts", "payload"],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Globally unique identifier per event."
},
"kind": {
"const": "scheduler.graph.job.completed"
},
"tenant": {
"type": "string",
"description": "Tenant identifier scoped to the originating job."
},
"ts": {
"type": "string",
"format": "date-time",
"description": "UTC timestamp when the job reached a terminal state."
},
"payload": {
"type": "object",
"additionalProperties": false,
"required": ["jobType", "job", "status", "occurredAt"],
"properties": {
"jobType": {
"type": "string",
"enum": ["build", "overlay"],
"description": "Job flavour, matches the CLR type of the serialized job payload."
},
"status": {
"type": "string",
"enum": ["completed", "failed", "cancelled"],
"description": "Terminal status recorded for the job."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"description": "UTC timestamp of the terminal transition, mirrors job.CompletedAt."
},
"job": {
"oneOf": [
{"$ref": "#/definitions/graphBuildJob"},
{"$ref": "#/definitions/graphOverlayJob"}
],
"description": "Canonical serialized representation of the finished job."
},
"resultUri": {
"type": "string",
"description": "Optional URI pointing to Cartographer snapshot or overlay bundle (if available)."
}
}
},
"attributes": {
"type": "object",
"description": "Optional correlation bag for downstream consumers.",
"additionalProperties": {
"type": "string"
}
}
},
"definitions": {
"graphBuildJob": {
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"id",
"tenantId",
"sbomId",
"sbomVersionId",
"sbomDigest",
"status",
"trigger",
"attempts",
"createdAt"
],
"properties": {
"schemaVersion": {
"const": "scheduler.graph-build-job@1"
},
"id": {"type": "string"},
"tenantId": {"type": "string"},
"sbomId": {"type": "string"},
"sbomVersionId": {"type": "string"},
"sbomDigest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"graphSnapshotId": {"type": "string"},
"status": {
"type": "string",
"enum": ["pending", "queued", "running", "completed", "failed", "cancelled"]
},
"trigger": {
"type": "string",
"enum": ["sbom-version", "backfill", "manual"]
},
"attempts": {
"type": "integer",
"minimum": 0
},
"cartographerJobId": {"type": "string"},
"correlationId": {"type": "string"},
"createdAt": {
"type": "string",
"format": "date-time"
},
"startedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"error": {"type": "string"},
"metadata": {
"type": "object",
"additionalProperties": {"type": "string"}
}
}
},
"graphOverlayJob": {
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"id",
"tenantId",
"graphSnapshotId",
"overlayKind",
"overlayKey",
"status",
"trigger",
"attempts",
"createdAt"
],
"properties": {
"schemaVersion": {
"const": "scheduler.graph-overlay-job@1"
},
"id": {"type": "string"},
"tenantId": {"type": "string"},
"graphSnapshotId": {"type": "string"},
"buildJobId": {"type": "string"},
"overlayKind": {
"type": "string",
"enum": ["policy", "advisory", "vex"]
},
"overlayKey": {"type": "string"},
"subjects": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true
},
"status": {
"type": "string",
"enum": ["pending", "queued", "running", "completed", "failed", "cancelled"]
},
"trigger": {
"type": "string",
"enum": ["policy", "advisory", "vex", "sbom-version", "manual"]
},
"attempts": {
"type": "integer",
"minimum": 0
},
"correlationId": {"type": "string"},
"createdAt": {
"type": "string",
"format": "date-time"
},
"startedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"error": {"type": "string"},
"metadata": {
"type": "object",
"additionalProperties": {"type": "string"}
}
}
}
}
}
{
"$id": "https://stella-ops.org/schemas/events/scheduler.graph.job.completed@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Scheduler Graph Job Completed Event",
"description": "Legacy scheduler event emitted when a graph build or overlay job reaches a terminal state. Consumers validate downstream caches and surface overlay freshness.",
"type": "object",
"additionalProperties": false,
"required": ["eventId", "kind", "tenant", "ts", "payload"],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Globally unique identifier per event."
},
"kind": {
"const": "scheduler.graph.job.completed"
},
"tenant": {
"type": "string",
"description": "Tenant identifier scoped to the originating job."
},
"ts": {
"type": "string",
"format": "date-time",
"description": "UTC timestamp when the job reached a terminal state."
},
"payload": {
"type": "object",
"additionalProperties": false,
"required": ["jobType", "job", "status", "occurredAt"],
"properties": {
"jobType": {
"type": "string",
"enum": ["build", "overlay"],
"description": "Job flavour, matches the CLR type of the serialized job payload."
},
"status": {
"type": "string",
"enum": ["completed", "failed", "cancelled"],
"description": "Terminal status recorded for the job."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"description": "UTC timestamp of the terminal transition, mirrors job.CompletedAt."
},
"job": {
"oneOf": [
{"$ref": "#/definitions/graphBuildJob"},
{"$ref": "#/definitions/graphOverlayJob"}
],
"description": "Canonical serialized representation of the finished job."
},
"resultUri": {
"type": "string",
"description": "Optional URI pointing to Cartographer snapshot or overlay bundle (if available)."
}
}
},
"attributes": {
"type": "object",
"description": "Optional correlation bag for downstream consumers.",
"additionalProperties": {
"type": "string"
}
}
},
"definitions": {
"graphBuildJob": {
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"id",
"tenantId",
"sbomId",
"sbomVersionId",
"sbomDigest",
"status",
"trigger",
"attempts",
"createdAt"
],
"properties": {
"schemaVersion": {
"const": "scheduler.graph-build-job@1"
},
"id": {"type": "string"},
"tenantId": {"type": "string"},
"sbomId": {"type": "string"},
"sbomVersionId": {"type": "string"},
"sbomDigest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"graphSnapshotId": {"type": "string"},
"status": {
"type": "string",
"enum": ["pending", "queued", "running", "completed", "failed", "cancelled"]
},
"trigger": {
"type": "string",
"enum": ["sbom-version", "backfill", "manual"]
},
"attempts": {
"type": "integer",
"minimum": 0
},
"cartographerJobId": {"type": "string"},
"correlationId": {"type": "string"},
"createdAt": {
"type": "string",
"format": "date-time"
},
"startedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"error": {"type": "string"},
"metadata": {
"type": "object",
"additionalProperties": {"type": "string"}
}
}
},
"graphOverlayJob": {
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"id",
"tenantId",
"graphSnapshotId",
"overlayKind",
"overlayKey",
"status",
"trigger",
"attempts",
"createdAt"
],
"properties": {
"schemaVersion": {
"const": "scheduler.graph-overlay-job@1"
},
"id": {"type": "string"},
"tenantId": {"type": "string"},
"graphSnapshotId": {"type": "string"},
"buildJobId": {"type": "string"},
"overlayKind": {
"type": "string",
"enum": ["policy", "advisory", "vex"]
},
"overlayKey": {"type": "string"},
"subjects": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true
},
"status": {
"type": "string",
"enum": ["pending", "queued", "running", "completed", "failed", "cancelled"]
},
"trigger": {
"type": "string",
"enum": ["policy", "advisory", "vex", "sbom-version", "manual"]
},
"attempts": {
"type": "integer",
"minimum": 0
},
"correlationId": {"type": "string"},
"createdAt": {
"type": "string",
"format": "date-time"
},
"startedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"error": {"type": "string"},
"metadata": {
"type": "object",
"additionalProperties": {"type": "string"}
}
}
}
}
}