docs consolidation and others

This commit is contained in:
master
2026-01-06 19:02:21 +02:00
parent d7bdca6d97
commit 4789027317
849 changed files with 16551 additions and 66770 deletions

View File

@@ -0,0 +1,91 @@
# Event Envelope Schemas
Platform services publish strongly typed events; the JSON Schemas in this directory define those envelopes. File names follow `<event-name>@<version>.json` so producers and consumers can negotiate contracts explicitly.
## Catalog
**Orchestrator envelopes (ORCH-SVC-38-101)**
- `scanner.event.report.ready@1.json` — orchestrator event emitted when a signed report is persisted. Supersedes the legacy `scanner.report.ready@1` schema and adds versioning, idempotency keys, and trace context. Consumers: Orchestrator bus, Notifications Studio, UI timeline.
- `scanner.event.scan.completed@1.json` — orchestrator event emitted when a scan run finishes. Supersedes the legacy `scanner.scan.completed@1` schema. Consumers: Orchestrator bus, Notifications Studio, Scheduler replay tooling.
**Legacy envelopes (Redis-backed)**
- `scanner.report.ready@1.json` — legacy Redis stream event emitted once a signed report is persisted (kept for transitional compatibility).
- `scanner.scan.completed@1.json` — legacy Redis stream event emitted alongside the signed report for automation.
- `scheduler.rescan.delta@1.json` — emitted by Scheduler when BOM-Index diffs require fresh scans. Consumers: Notify, Policy Engine.
- `scheduler.graph.job.completed@1.json` — emitted when a Cartographer graph build/overlay job finishes (`status = completed|failed|cancelled`). Consumers: Scheduler WebService (lag metrics/API), Cartographer cache warmers, UI overlay freshness indicators.
- `attestor.logged@1.json` — emitted by Attestor after storing the Rekor inclusion proof. Consumers: UI attestation panel, Governance exports.
Additive payload changes (new optional fields) can stay within the same version. Any breaking change (removing a field, tightening validation, altering semantics) must increment the `@<version>` suffix and update downstream consumers. For full orchestrator guidance see [`orchestrator-scanner-events.md`](orchestrator-scanner-events.md).
## Envelope structure
### Orchestrator envelope (version&nbsp;1)
| Field | Type | Notes |
|-------|------|-------|
| `eventId` | `uuid` | Globally unique per occurrence. |
| `kind` | `string` | e.g., `scanner.event.report.ready`. |
| `version` | `integer` | Schema version (`1` for the initial release). |
| `tenant` | `string` | Multitenant isolation key; mirror the value recorded in queue/PostgreSQL metadata. |
| `occurredAt` | `date-time` | RFC3339 UTC timestamp describing when the state transition happened. |
| `recordedAt` | `date-time` | RFC3339 UTC timestamp for durable persistence (optional but recommended). |
| `source` | `string` | Producer identifier (`scanner.webservice`). |
| `idempotencyKey` | `string` | Deterministic dedupe key (`scanner.event.*:<tenant>:<report|scan>`). |
| `correlationId` | `string` | Ties the event to the originating scan/API request. |
| `traceId` / `spanId` | `string` | W3C trace context propagated into downstream telemetry. |
| `scope` | `object` | Optional block with at least `repo` and `digest`. |
| `payload` | `object` | Event-specific body; schemas embed the canonical report and DSSE envelope. |
| `attributes` | `object` | Optional metadata bag (`string` keys/values) for downstream correlation. |
For Scanner orchestrator events, `links` include console and API deep links (`report.ui`, `report.api`, etc.) plus optional attestation references when a DSSE envelope is present. See [`orchestrator-scanner-events.md`](orchestrator-scanner-events.md) for details.
### Legacy Redis envelope
| Field | Type | Notes |
|-------|------|-------|
| `eventId` | `uuid` | Must be globally unique per occurrence; producers log duplicates as fatal. |
| `kind` | `string` | Fixed per schema (e.g., `scanner.report.ready`). Downstream services reject unknown kinds or versions. |
| `tenant` | `string` | Multitenant isolation key; mirror the value recorded in queue/PostgreSQL metadata. |
| `ts` | `date-time` | RFC3339 UTC timestamp. Use monotonic clocks or atomic offsets so ordering survives retries. |
| `scope` | `object` | Optional block used when the event concerns a specific image or repository. See schema for required fields (e.g., `repo`, `digest`). |
| `payload` | `object` | Event-specific body. Schemas allow additional properties so producers can add optional hints (e.g., `reportId`, `quietedFindingCount`) without breaking consumers. See `docs/runtime/SCANNER_RUNTIME_READINESS.md` for the runtime consumer checklist covering these hints. |
| `attributes` | `object` | Optional metadata bag (`string` keys/values) for downstream correlation (e.g., pipeline identifiers). Omit when unused to keep payloads concise. |
When adding new optional fields, document the behaviour in the schemas `description` block and update the consumer checklist in the next sprint sync.
## Canonical samples & validation
Reference payloads live under `docs/events/samples/`, mirroring the schema version (`<event-name>@<version>.sample.json`). They illustrate common field combinations, including the optional attributes that downstream teams rely on for UI affordances and audit trails. Scanner samples reuse the exact DSSE envelope checked into `samples/api/reports/report-sample.dsse.json`, and unit tests (`ReportSamplesTests`, `PlatformEventSchemaValidationTests`) guard that payloads stay canonical and continue to satisfy the published schemas.
Run the following loop offline to validate both schemas and samples:
```bash
# Validate schemas (same check as CI)
for schema in docs/events/*.json; do
npx ajv compile -c ajv-formats -s "$schema"
done
# Validate canonical samples against their schemas
for sample in docs/events/samples/*.sample.json; do
schema="docs/events/$(basename "${sample%.sample.json}").json"
npx ajv validate -c ajv-formats -s "$schema" -d "$sample"
done
```
Consumers can copy the samples into integration tests to guarantee backwards compatibility. When emitting new event versions, include a matching sample and update this README so air-gapped operators stay in sync.
## CI validation
The Docs CI workflow (`.gitea/workflows/docs.yml`) installs `ajv-cli` and compiles every schema on pull requests. Run the same check locally before opening a PR:
```bash
for schema in docs/events/*.json; do
npx ajv compile -c ajv-formats -s "$schema"
done
```
Tip: run `npm install --no-save ajv ajv-cli ajv-formats` once per clone so `npx` can resolve the tooling offline.
If a schema references additional files, include `-r` flags so CI and local runs stay consistent.
## Working with schemas
- Producers should validate outbound payloads using the matching schema during unit tests.
- Consumers should pin to a specific version and log when encountering unknown versions to catch missing migrations early.
- Store real payload samples under `docs/events/samples/` (mirrors the schema version) and mirror them into `samples/events/` when you need fixtures in integration repositories.
Contact the Platform Events group in Docs Guild if you need help shaping a new event or version strategy.

View File

@@ -0,0 +1,58 @@
{
"$id": "https://stella-ops.org/schemas/events/advisoryai.evidence.bundle@0.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AdvisoryAI evidence bundle (draft v0)",
"type": "object",
"additionalProperties": false,
"required": ["bundleId", "advisoryId", "tenant", "generatedAt", "observations"],
"properties": {
"bundleId": {"type": "string", "description": "Deterministic bundle identifier (UUID or ULID)."},
"advisoryId": {"type": "string", "description": "Upstream advisory identifier (vendor or CVE-style)."},
"tenant": {"type": "string", "description": "Owning tenant."},
"generatedAt": {"type": "string", "format": "date-time", "description": "UTC timestamp when bundle was assembled."},
"schemaVersion": {"type": "integer", "default": 0},
"observations": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["observationId", "source"],
"properties": {
"observationId": {"type": "string"},
"source": {"type": "string", "description": "Publisher or feed name."},
"purl": {"type": "string", "description": "Optional package URL."},
"cve": {"type": "string"},
"severity": {"type": "string", "description": "Publisher-reported severity label."},
"cvss": {
"type": "object",
"additionalProperties": false,
"properties": {
"vector": {"type": "string"},
"score": {"type": "number"}
}
},
"summary": {"type": "string"},
"evidence": {
"type": "object",
"description": "Raw upstream statement or excerpt.",
"additionalProperties": true
}
}
}
},
"signatures": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["signature", "keyId"],
"properties": {
"signature": {"type": "string", "description": "Base64 signature over canonical JSON."},
"keyId": {"type": "string"},
"algorithm": {"type": "string"}
}
}
}
}
}

View File

@@ -0,0 +1,211 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stellaops.org/schemas/events/advisoryai.evidence.bundle@1.schema.json",
"title": "AdvisoryAI Evidence Bundle Schema v1",
"description": "Schema for AdvisoryAI evidence bundles containing advisory observations with CVSS vectors and optional signatures. Used by ExportCenter and Timeline services for evidence aggregation.",
"type": "object",
"required": ["bundleId", "advisoryId", "tenant", "generatedAt", "schemaVersion"],
"$defs": {
"cvssVector": {
"type": "object",
"title": "CVSS Vector",
"description": "Common Vulnerability Scoring System vector and score",
"properties": {
"vector": {
"type": ["string", "null"],
"description": "CVSS vector string (v2, v3.0, v3.1, or v4.0)",
"examples": [
"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"
]
},
"score": {
"type": ["number", "null"],
"minimum": 0,
"maximum": 10,
"description": "CVSS base score (0.0 to 10.0)"
}
},
"additionalProperties": false
},
"signatureInfo": {
"type": "object",
"title": "Signature Information",
"description": "Cryptographic signature for bundle authentication",
"required": ["signature", "keyId"],
"properties": {
"signature": {
"type": "string",
"description": "Base64-encoded cryptographic signature"
},
"keyId": {
"type": "string",
"description": "Identifier of the signing key",
"examples": ["sha256:abc123...", "stellaops-prod-2025"]
},
"algorithm": {
"type": ["string", "null"],
"description": "Signature algorithm used",
"examples": ["ECDSA-P256-SHA256", "RSA-PSS-SHA256", "Ed25519"]
}
},
"additionalProperties": false
},
"advisoryObservation": {
"type": "object",
"title": "Advisory Observation",
"description": "An individual advisory observation within the bundle",
"required": ["observationId", "source"],
"properties": {
"observationId": {
"type": "string",
"description": "Unique identifier for this observation",
"minLength": 1
},
"source": {
"type": "string",
"description": "Source of the observation (e.g., scanner, user, vex-lens)",
"examples": ["scanner", "manual", "vex-lens", "advisoryai", "concelier"]
},
"purl": {
"type": ["string", "null"],
"description": "Package URL identifying the affected component",
"pattern": "^pkg:[a-z]+/",
"examples": ["pkg:npm/lodash@4.17.21", "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1"]
},
"cve": {
"type": ["string", "null"],
"description": "CVE identifier",
"pattern": "^CVE-[0-9]{4}-[0-9]+$",
"examples": ["CVE-2021-44228", "CVE-2024-12345"]
},
"severity": {
"type": ["string", "null"],
"description": "Severity level",
"enum": ["critical", "high", "medium", "low", "info", "unknown", null]
},
"cvss": {
"oneOf": [
{ "$ref": "#/$defs/cvssVector" },
{ "type": "null" }
],
"description": "CVSS vector and score"
},
"summary": {
"type": ["string", "null"],
"description": "Brief summary of the observation"
},
"evidence": {
"type": ["object", "null"],
"additionalProperties": true,
"description": "Arbitrary evidence data attached to the observation",
"examples": [
{
"reachability": "reachable",
"callPaths": ["main() -> vulnerable_func()"],
"exploitMaturity": "poc"
}
]
}
},
"additionalProperties": false
}
},
"properties": {
"bundleId": {
"type": "string",
"description": "Unique identifier for this evidence bundle",
"minLength": 1,
"examples": ["bundle-550e8400-e29b-41d4-a716-446655440000"]
},
"advisoryId": {
"type": "string",
"description": "Identifier of the related advisory or assessment",
"minLength": 1,
"examples": ["advisory-2025-001", "assessment-abc123"]
},
"tenant": {
"type": "string",
"description": "Tenant identifier (may be UUID or name)",
"minLength": 1,
"examples": ["00000000-0000-0000-0000-000000000001", "acme-corp"]
},
"generatedAt": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp when the bundle was generated"
},
"schemaVersion": {
"type": "integer",
"minimum": 0,
"description": "Schema version number for this bundle format",
"default": 1
},
"observations": {
"type": "array",
"items": {
"$ref": "#/$defs/advisoryObservation"
},
"default": [],
"description": "List of advisory observations in this bundle"
},
"signatures": {
"type": ["array", "null"],
"items": {
"$ref": "#/$defs/signatureInfo"
},
"description": "Optional cryptographic signatures for bundle verification"
}
},
"additionalProperties": false,
"examples": [
{
"bundleId": "bundle-550e8400-e29b-41d4-a716-446655440000",
"advisoryId": "assessment-log4shell-2024",
"tenant": "00000000-0000-0000-0000-000000000001",
"generatedAt": "2025-12-07T10:30:00Z",
"schemaVersion": 1,
"observations": [
{
"observationId": "obs-001",
"source": "scanner",
"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1",
"cve": "CVE-2021-44228",
"severity": "critical",
"cvss": {
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
"score": 10.0
},
"summary": "Log4Shell RCE vulnerability detected in log4j-core",
"evidence": {
"reachability": "reachable",
"callPaths": [
"com.example.App.main() -> org.apache.logging.log4j.Logger.error()"
],
"exploitMaturity": "weaponized",
"kevListed": true
}
},
{
"observationId": "obs-002",
"source": "vex-lens",
"purl": "pkg:maven/org.apache.logging.log4j/log4j-api@2.14.1",
"cve": "CVE-2021-45105",
"severity": "high",
"cvss": {
"vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H",
"score": 5.9
},
"summary": "Log4j2 infinite recursion DoS vulnerability"
}
],
"signatures": [
{
"signature": "MEUCIQDx...",
"keyId": "sha256:abc123def456...",
"algorithm": "ECDSA-P256-SHA256"
}
]
}
]
}

View File

@@ -0,0 +1,43 @@
{
"$id": "https://stella-ops.org/schemas/events/attestor.logged@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["eventId", "kind", "tenant", "ts", "payload"],
"properties": {
"eventId": {"type": "string", "format": "uuid"},
"kind": {"const": "attestor.logged"},
"tenant": {"type": "string"},
"ts": {"type": "string", "format": "date-time"},
"payload": {
"type": "object",
"required": ["artifactSha256", "rekor", "subject"],
"properties": {
"artifactSha256": {"type": "string"},
"rekor": {
"type": "object",
"required": ["uuid", "url"],
"properties": {
"uuid": {"type": "string"},
"url": {"type": "string", "format": "uri"},
"index": {"type": "integer", "minimum": 0}
}
},
"subject": {
"type": "object",
"required": ["type", "name"],
"properties": {
"type": {"enum": ["sbom", "report", "vex-export"]},
"name": {"type": "string"}
}
}
},
"additionalProperties": true
},
"attributes": {
"type": "object",
"description": "Optional event attributes for downstream correlation.",
"additionalProperties": true
}
},
"additionalProperties": false
}

View File

@@ -0,0 +1,124 @@
# 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:**
- `report.ui``/ui/reports/{reportId}` on the current host.
- `report.api``{apiBasePath}/{reportsSegment}/{reportId}` (defaults to `/api/v1/reports/{reportId}`).
- `policy.ui``/ui/policy/revisions/{revisionId}` when a revision is present.
- `policy.api``{apiBasePath}/{policySegment}/revisions/{revisionId}` when a revision is present.
- `attestation.ui``/ui/attestations/{reportId}` when a DSSE envelope is included.
- `attestation.api``{apiBasePath}/{reportsSegment}/{reportId}/attestation` when a DSSE envelope is included.
- UI routes honour the configurable `scanner:console` options (`basePath`, `reportsSegment`, `policySegment`, `attestationsSegment`) so operators can move links under `/console` without code changes.
- `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 (`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` (done) track the production of these envelopes. Dispatcher link customisation landed and samples updated; full `dotnet test` suite now succeeds after Surface cache ctor drift was patched and DSSE fixtures re-synced (2025-11-06).
- **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/modules/devops/runbooks/launch-cutover.md` to confirm downstream validation before the production cutover. Record gaps or newly required fields in `docs/modules/devops/runbooks/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

@@ -0,0 +1,32 @@
{
"bundleId": "19bd7cf7-c7a6-4c1c-9b9c-6f2f794e9b1a",
"advisoryId": "CVE-2025-12345",
"tenant": "demo-tenant",
"generatedAt": "2025-11-18T12:00:00Z",
"schemaVersion": 0,
"observations": [
{
"observationId": "obs-001",
"source": "vendor.psirt",
"purl": "pkg:maven/org.example/app@1.2.3",
"cve": "CVE-2025-12345",
"severity": "critical",
"cvss": {
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"score": 9.8
},
"summary": "Remote code execution via deserialization of untrusted data.",
"evidence": {
"statement": "Vendor confirms unauthenticated RCE in versions <1.2.4",
"references": ["https://example.com/advisory"]
}
}
],
"signatures": [
{
"signature": "MEQCID...==",
"keyId": "authority-root-1",
"algorithm": "ecdsa-p256-sha256"
}
]
}

View File

@@ -0,0 +1,21 @@
{
"eventId": "1fdcaa1a-7a27-4154-8bac-cf813d8f4f6f",
"kind": "attestor.logged",
"tenant": "tenant-acme-solar",
"ts": "2025-10-18T15:45:27+00:00",
"payload": {
"artifactSha256": "sha256:8927d9151ad3f44e61a9c647511f9a31af2b4d245e7e031fe5cb4a0e8211c5d9",
"dsseEnvelopeDigest": "sha256:51c1dd189d5f16cfe87e82841d67b4fbc27d6fa9f5a09af0cd7e18945fb4c2a9",
"rekor": {
"index": 563421,
"url": "https://rekor.example/api/v1/log/entries/d6d0f897e7244edc9cb0bb2c68b05c96",
"uuid": "d6d0f897e7244edc9cb0bb2c68b05c96"
},
"signer": "cosign-stellaops",
"subject": {
"name": "scanner/report/sha256-0f0a8de5c1f93d6716b7249f6f4ea3a8",
"type": "report"
}
},
"attributes": {}
}

View File

@@ -0,0 +1,141 @@
{
"eventId": "6d2d1b77-f3c3-4f70-8a9d-6f2d0c8801ab",
"kind": "scanner.event.report.ready",
"version": 1,
"tenant": "tenant-alpha",
"occurredAt": "2025-10-19T12:34:56+00:00",
"recordedAt": "2025-10-19T12:34:57+00:00",
"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"
},
"payload": {
"reportId": "report-abc",
"scanId": "report-abc",
"imageDigest": "sha256:feedface",
"generatedAt": "2025-10-19T12:34:56+00:00",
"verdict": "fail",
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"delta": {
"newCritical": 1,
"kev": [
"CVE-2024-9999"
]
},
"quietedFindingCount": 0,
"policy": {
"revisionId": "rev-42",
"digest": "digest-123"
},
"links": {
"report": {
"ui": "https://scanner.example/ui/reports/report-abc",
"api": "https://scanner.example/api/v1/reports/report-abc"
},
"policy": {
"ui": "https://scanner.example/ui/policy/revisions/rev-42",
"api": "https://scanner.example/api/v1/policy/revisions/rev-42"
},
"attestation": {
"ui": "https://scanner.example/ui/attestations/report-abc",
"api": "https://scanner.example/api/v1/reports/report-abc/attestation"
}
},
"dsse": {
"payloadType": "application/vnd.stellaops.report+json",
"payload": "eyJyZXBvcnRJZCI6InJlcG9ydC1hYmMiLCJpbWFnZURpZ2VzdCI6InNoYTI1NjpmZWVkZmFjZSIsImdlbmVyYXRlZEF0IjoiMjAyNS0xMC0xOVQxMjozNDo1NiswMDowMCIsInZlcmRpY3QiOiJibG9ja2VkIiwicG9saWN5Ijp7InJldmlzaW9uSWQiOiJyZXYtNDIiLCJkaWdlc3QiOiJkaWdlc3QtMTIzIn0sInN1bW1hcnkiOnsidG90YWwiOjEsImJsb2NrZWQiOjEsIndhcm5lZCI6MCwiaWdub3JlZCI6MCwicXVpZXRlZCI6MH0sInZlcmRpY3RzIjpbeyJmaW5kaW5nSWQiOiJmaW5kaW5nLTEiLCJyZWFjaGFiaWxpdHkiOiJydW50aW1lIiwic2NvcmUiOjQ3LjUsInNvdXJjZVRydXN0IjoiTlZEIiwic3RhdHVzIjoiQmxvY2tlZCJ9XSwiaXNzdWVzIjpbXSwic3VyZmFjZSI6eyJ0ZW5hbnQiOiJ0ZW5hbnQtYWxwaGEiLCJnZW5lcmF0ZWRBdCI6IjIwMjUtMTAtMTlUMTI6MzQ6NTYrMDA6MDAiLCJtYW5pZmVzdERpZ2VzdCI6InNoYTI1Njo0ZmVlODdkMTg2MjkxZGRmYmJjYzJjNTZjOGVkMGU4Mjg1MjBiOGY1MmUxY2RlMGUxM2JiYTA4MmYxMDkxOGQ3IiwibWFuaWZlc3RVcmkiOiJjYXM6Ly9zY2FubmVyLWFydGlmYWN0cy9zY2FubmVyL3N1cmZhY2UvbWFuaWZlc3RzL3RlbmFudC1hbHBoYS9zaGEyNTYvNGYvZWUvNGZlZTg3ZDE4NjI5MWRkZmJiY2MyYzU2YzhlZDBlODI4NTIwYjhmNTJlMWNkZTBlMTNiYmEwODJmMTA5MThkNy5qc29uIiwibWFuaWZlc3QiOnsic2NoZW1hIjoic3RlbGxhb3BzLnN1cmZhY2UubWFuaWZlc3RAMSIsInRlbmFudCI6InRlbmFudC1hbHBoYSIsImltYWdlRGlnZXN0Ijoic2hhMjU2OmZlZWRmYWNlIiwiZ2VuZXJhdGVkQXQiOiIyMDI1LTEwLTE5VDEyOjM0OjU2KzAwOjAwIiwiYXJ0aWZhY3RzIjpbeyJraW5kIjoiZW50cnktdHJhY2UiLCJ1cmkiOiJjYXM6Ly9zY2FubmVyLWFydGlmYWN0cy9zY2FubmVyL2VudHJ5LXRyYWNlL2YwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwL2VudHJ5LXRyYWNlLmpzb24iLCJkaWdlc3QiOiJzaGEyNTY6ZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMCIsIm1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL2pzb24iLCJmb3JtYXQiOiJqc29uIiwic2l6ZUJ5dGVzIjo0MDk2fSx7ImtpbmQiOiJzYm9tLWludmVudG9yeSIsInVyaSI6ImNhczovL3NjYW5uZXItYXJ0aWZhY3RzL3NjYW5uZXIvaW1hZ2VzL2ZlZWRmYWNlL3Nib20uY2R4Lmpzb24iLCJkaWdlc3QiOiJzaGEyNTY6MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSIsIm1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5jeWNsb25lZHgranNvbjt2ZXJzaW9uPTEuNjt2aWV3PWludmVudG9yeSIsImZvcm1hdCI6ImNkeC1qc29uIiwic2l6ZUJ5dGVzIjoyNDU3NiwidmlldyI6ImludmVudG9yeSJ9LHsia2luZCI6InNib20tdXNhZ2UiLCJ1cmkiOiJjYXM6Ly9zY2FubmVyLWFydGlmYWN0cy9zY2FubmVyL2ltYWdlcy9mZWVkZmFjZS9zYm9tLXVzYWdlLmNkeC5qc29uIiwiZGlnZXN0Ijoic2hhMjU2OjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIiLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuY3ljbG9uZWR4K2pzb247dmVyc2lvbj0xLjY7dmlldz11c2FnZSIsImZvcm1hdCI6ImNkeC1qc29uIiwic2l6ZUJ5dGVzIjoxNjM4NCwidmlldyI6InVzYWdlIn1dfX19",
"signatures": [
{
"keyId": "test-key",
"algorithm": "hs256",
"signature": "signature-value"
}
]
},
"report": {
"reportId": "report-abc",
"imageDigest": "sha256:feedface",
"generatedAt": "2025-10-19T12:34:56+00:00",
"verdict": "blocked",
"policy": {
"revisionId": "rev-42",
"digest": "digest-123"
},
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"verdicts": [
{
"findingId": "finding-1",
"reachability": "runtime",
"score": 47.5,
"sourceTrust": "NVD",
"status": "Blocked"
}
],
"issues": [],
"surface": {
"tenant": "tenant-alpha",
"generatedAt": "2025-10-19T12:34:56+00:00",
"manifestDigest": "sha256:4fee87d186291ddfbbcc2c56c8ed0e828520b8f52e1cde0e13bba082f10918d7",
"manifestUri": "cas://scanner-artifacts/scanner/surface/manifests/tenant-alpha/sha256/4f/ee/4fee87d186291ddfbbcc2c56c8ed0e828520b8f52e1cde0e13bba082f10918d7.json",
"manifest": {
"schema": "stellaops.surface.manifest@1",
"tenant": "tenant-alpha",
"imageDigest": "sha256:feedface",
"generatedAt": "2025-10-19T12:34:56+00:00",
"artifacts": [
{
"kind": "entry-trace",
"uri": "cas://scanner-artifacts/scanner/entry-trace/f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0/entry-trace.json",
"digest": "sha256:f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0",
"mediaType": "application/json",
"format": "json",
"sizeBytes": 4096
},
{
"kind": "sbom-inventory",
"uri": "cas://scanner-artifacts/scanner/images/feedface/sbom.cdx.json",
"digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111",
"mediaType": "application/vnd.cyclonedx+json;version=1.6;view=inventory",
"format": "cdx-json",
"sizeBytes": 24576,
"view": "inventory"
},
{
"kind": "sbom-usage",
"uri": "cas://scanner-artifacts/scanner/images/feedface/sbom-usage.cdx.json",
"digest": "sha256:2222222222222222222222222222222222222222222222222222222222222222",
"mediaType": "application/vnd.cyclonedx+json;version=1.6;view=usage",
"format": "cdx-json",
"sizeBytes": 16384,
"view": "usage"
}
]
}
}
}
},
"attributes": {
"policyDigest": "digest-123",
"policyRevisionId": "rev-42",
"reportId": "report-abc",
"verdict": "blocked"
}
}

View File

@@ -0,0 +1,147 @@
{
"eventId": "08a6de24-4a94-4d14-8432-9d14f36f6da3",
"kind": "scanner.event.scan.completed",
"version": 1,
"tenant": "tenant-alpha",
"occurredAt": "2025-10-19T12:34:56+00:00",
"recordedAt": "2025-10-19T12:34:57+00:00",
"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"
},
"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": {
"revisionId": "rev-42",
"digest": "digest-123"
},
"findings": [
{
"id": "finding-1",
"severity": "Critical",
"cve": "CVE-2024-9999",
"purl": "pkg:docker/acme/edge-api@sha256-feedface",
"reachability": "runtime"
}
],
"links": {
"report": {
"ui": "https://scanner.example/ui/reports/report-abc",
"api": "https://scanner.example/api/v1/reports/report-abc"
},
"policy": {
"ui": "https://scanner.example/ui/policy/revisions/rev-42",
"api": "https://scanner.example/api/v1/policy/revisions/rev-42"
},
"attestation": {
"ui": "https://scanner.example/ui/attestations/report-abc",
"api": "https://scanner.example/api/v1/reports/report-abc/attestation"
}
},
"dsse": {
"payloadType": "application/vnd.stellaops.report+json",
"payload": "eyJyZXBvcnRJZCI6InJlcG9ydC1hYmMiLCJpbWFnZURpZ2VzdCI6InNoYTI1NjpmZWVkZmFjZSIsImdlbmVyYXRlZEF0IjoiMjAyNS0xMC0xOVQxMjozNDo1NiswMDowMCIsInZlcmRpY3QiOiJibG9ja2VkIiwicG9saWN5Ijp7InJldmlzaW9uSWQiOiJyZXYtNDIiLCJkaWdlc3QiOiJkaWdlc3QtMTIzIn0sInN1bW1hcnkiOnsidG90YWwiOjEsImJsb2NrZWQiOjEsIndhcm5lZCI6MCwiaWdub3JlZCI6MCwicXVpZXRlZCI6MH0sInZlcmRpY3RzIjpbeyJmaW5kaW5nSWQiOiJmaW5kaW5nLTEiLCJyZWFjaGFiaWxpdHkiOiJydW50aW1lIiwic2NvcmUiOjQ3LjUsInNvdXJjZVRydXN0IjoiTlZEIiwic3RhdHVzIjoiQmxvY2tlZCJ9XSwiaXNzdWVzIjpbXSwic3VyZmFjZSI6eyJ0ZW5hbnQiOiJ0ZW5hbnQtYWxwaGEiLCJnZW5lcmF0ZWRBdCI6IjIwMjUtMTAtMTlUMTI6MzQ6NTYrMDA6MDAiLCJtYW5pZmVzdERpZ2VzdCI6InNoYTI1Njo0ZmVlODdkMTg2MjkxZGRmYmJjYzJjNTZjOGVkMGU4Mjg1MjBiOGY1MmUxY2RlMGUxM2JiYTA4MmYxMDkxOGQ3IiwibWFuaWZlc3RVcmkiOiJjYXM6Ly9zY2FubmVyLWFydGlmYWN0cy9zY2FubmVyL3N1cmZhY2UvbWFuaWZlc3RzL3RlbmFudC1hbHBoYS9zaGEyNTYvNGYvZWUvNGZlZTg3ZDE4NjI5MWRkZmJiY2MyYzU2YzhlZDBlODI4NTIwYjhmNTJlMWNkZTBlMTNiYmEwODJmMTA5MThkNy5qc29uIiwibWFuaWZlc3QiOnsic2NoZW1hIjoic3RlbGxhb3BzLnN1cmZhY2UubWFuaWZlc3RAMSIsInRlbmFudCI6InRlbmFudC1hbHBoYSIsImltYWdlRGlnZXN0Ijoic2hhMjU2OmZlZWRmYWNlIiwiZ2VuZXJhdGVkQXQiOiIyMDI1LTEwLTE5VDEyOjM0OjU2KzAwOjAwIiwiYXJ0aWZhY3RzIjpbeyJraW5kIjoiZW50cnktdHJhY2UiLCJ1cmkiOiJjYXM6Ly9zY2FubmVyLWFydGlmYWN0cy9zY2FubmVyL2VudHJ5LXRyYWNlL2YwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwL2VudHJ5LXRyYWNlLmpzb24iLCJkaWdlc3QiOiJzaGEyNTY6ZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMGYwZjBmMCIsIm1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL2pzb24iLCJmb3JtYXQiOiJqc29uIiwic2l6ZUJ5dGVzIjo0MDk2fSx7ImtpbmQiOiJzYm9tLWludmVudG9yeSIsInVyaSI6ImNhczovL3NjYW5uZXItYXJ0aWZhY3RzL3NjYW5uZXIvaW1hZ2VzL2ZlZWRmYWNlL3Nib20uY2R4Lmpzb24iLCJkaWdlc3QiOiJzaGEyNTY6MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSIsIm1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5jeWNsb25lZHgranNvbjt2ZXJzaW9uPTEuNjt2aWV3PWludmVudG9yeSIsImZvcm1hdCI6ImNkeC1qc29uIiwic2l6ZUJ5dGVzIjoyNDU3NiwidmlldyI6ImludmVudG9yeSJ9LHsia2luZCI6InNib20tdXNhZ2UiLCJ1cmkiOiJjYXM6Ly9zY2FubmVyLWFydGlmYWN0cy9zY2FubmVyL2ltYWdlcy9mZWVkZmFjZS9zYm9tLXVzYWdlLmNkeC5qc29uIiwiZGlnZXN0Ijoic2hhMjU2OjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIiLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuY3ljbG9uZWR4K2pzb247dmVyc2lvbj0xLjY7dmlldz11c2FnZSIsImZvcm1hdCI6ImNkeC1qc29uIiwic2l6ZUJ5dGVzIjoxNjM4NCwidmlldyI6InVzYWdlIn1dfX19",
"signatures": [
{
"keyId": "test-key",
"algorithm": "hs256",
"signature": "signature-value"
}
]
},
"report": {
"reportId": "report-abc",
"imageDigest": "sha256:feedface",
"generatedAt": "2025-10-19T12:34:56+00:00",
"verdict": "blocked",
"policy": {
"revisionId": "rev-42",
"digest": "digest-123"
},
"summary": {
"total": 1,
"blocked": 1,
"warned": 0,
"ignored": 0,
"quieted": 0
},
"verdicts": [
{
"findingId": "finding-1",
"reachability": "runtime",
"score": 47.5,
"sourceTrust": "NVD",
"status": "Blocked"
}
],
"issues": [],
"surface": {
"tenant": "tenant-alpha",
"generatedAt": "2025-10-19T12:34:56+00:00",
"manifestDigest": "sha256:4fee87d186291ddfbbcc2c56c8ed0e828520b8f52e1cde0e13bba082f10918d7",
"manifestUri": "cas://scanner-artifacts/scanner/surface/manifests/tenant-alpha/sha256/4f/ee/4fee87d186291ddfbbcc2c56c8ed0e828520b8f52e1cde0e13bba082f10918d7.json",
"manifest": {
"schema": "stellaops.surface.manifest@1",
"tenant": "tenant-alpha",
"imageDigest": "sha256:feedface",
"generatedAt": "2025-10-19T12:34:56+00:00",
"artifacts": [
{
"kind": "entry-trace",
"uri": "cas://scanner-artifacts/scanner/entry-trace/f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0/entry-trace.json",
"digest": "sha256:f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0",
"mediaType": "application/json",
"format": "json",
"sizeBytes": 4096
},
{
"kind": "sbom-inventory",
"uri": "cas://scanner-artifacts/scanner/images/feedface/sbom.cdx.json",
"digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111",
"mediaType": "application/vnd.cyclonedx+json;version=1.6;view=inventory",
"format": "cdx-json",
"sizeBytes": 24576,
"view": "inventory"
},
{
"kind": "sbom-usage",
"uri": "cas://scanner-artifacts/scanner/images/feedface/sbom-usage.cdx.json",
"digest": "sha256:2222222222222222222222222222222222222222222222222222222222222222",
"mediaType": "application/vnd.cyclonedx+json;version=1.6;view=usage",
"format": "cdx-json",
"sizeBytes": 16384,
"view": "usage"
}
]
}
}
}
},
"attributes": {
"policyDigest": "digest-123",
"policyRevisionId": "rev-42",
"reportId": "report-abc",
"verdict": "blocked"
}
}

View File

@@ -0,0 +1,70 @@
{
"eventId": "6d2d1b77-f3c3-4f70-8a9d-6f2d0c8801ab",
"kind": "scanner.report.ready",
"tenant": "tenant-alpha",
"ts": "2025-10-19T12:34:56+00:00",
"scope": {
"namespace": "acme/edge",
"repo": "api",
"digest": "sha256:feedface",
"labels": {},
"attributes": {}
},
"payload": {
"delta": {
"kev": ["CVE-2024-9999"],
"newCritical": 1
},
"dsse": {
"payload": "eyJyZXBvcnRJZCI6InJlcG9ydC1hYmMiLCJpbWFnZURpZ2VzdCI6InNoYTI1NjpmZWVkZmFjZSIsImdlbmVyYXRlZEF0IjoiMjAyNS0xMC0xOVQxMjozNDo1NiswMDowMCIsInZlcmRpY3QiOiJibG9ja2VkIiwicG9saWN5Ijp7InJldmlzaW9uSWQiOiJyZXYtNDIiLCJkaWdlc3QiOiJkaWdlc3QtMTIzIn0sInN1bW1hcnkiOnsidG90YWwiOjEsImJsb2NrZWQiOjEsIndhcm5lZCI6MCwiaWdub3JlZCI6MCwicXVpZXRlZCI6MH0sInZlcmRpY3RzIjpbeyJmaW5kaW5nSWQiOiJmaW5kaW5nLTEiLCJzdGF0dXMiOiJCbG9ja2VkIiwic2NvcmUiOjQ3LjUsInNvdXJjZVRydXN0IjoiTlZEIiwicmVhY2hhYmlsaXR5IjoicnVudGltZSJ9XSwiaXNzdWVzIjpbXX0=",
"payloadType": "application/vnd.stellaops.report\u002Bjson",
"signatures": [{
"algorithm": "hs256",
"keyId": "test-key",
"signature": "signature-value"
}]
},
"generatedAt": "2025-10-19T12:34:56+00:00",
"links": {
"ui": "https://scanner.example/ui/reports/report-abc"
},
"quietedFindingCount": 0,
"report": {
"generatedAt": "2025-10-19T12:34:56+00:00",
"imageDigest": "sha256:feedface",
"issues": [],
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"reportId": "report-abc",
"summary": {
"blocked": 1,
"ignored": 0,
"quieted": 0,
"total": 1,
"warned": 0
},
"verdict": "blocked",
"verdicts": [
{
"findingId": "finding-1",
"status": "Blocked",
"score": 47.5,
"sourceTrust": "NVD",
"reachability": "runtime"
}
]
},
"reportId": "report-abc",
"summary": {
"blocked": 1,
"ignored": 0,
"quieted": 0,
"total": 1,
"warned": 0
},
"verdict": "fail"
},
"attributes": {}
}

View File

@@ -0,0 +1,78 @@
{
"eventId": "08a6de24-4a94-4d14-8432-9d14f36f6da3",
"kind": "scanner.scan.completed",
"tenant": "tenant-alpha",
"ts": "2025-10-19T12:34:56+00:00",
"scope": {
"namespace": "acme/edge",
"repo": "api",
"digest": "sha256:feedface",
"labels": {},
"attributes": {}
},
"payload": {
"delta": {
"kev": ["CVE-2024-9999"],
"newCritical": 1
},
"digest": "sha256:feedface",
"dsse": {
"payload": "eyJyZXBvcnRJZCI6InJlcG9ydC1hYmMiLCJpbWFnZURpZ2VzdCI6InNoYTI1NjpmZWVkZmFjZSIsImdlbmVyYXRlZEF0IjoiMjAyNS0xMC0xOVQxMjozNDo1NiswMDowMCIsInZlcmRpY3QiOiJibG9ja2VkIiwicG9saWN5Ijp7InJldmlzaW9uSWQiOiJyZXYtNDIiLCJkaWdlc3QiOiJkaWdlc3QtMTIzIn0sInN1bW1hcnkiOnsidG90YWwiOjEsImJsb2NrZWQiOjEsIndhcm5lZCI6MCwiaWdub3JlZCI6MCwicXVpZXRlZCI6MH0sInZlcmRpY3RzIjpbeyJmaW5kaW5nSWQiOiJmaW5kaW5nLTEiLCJzdGF0dXMiOiJCbG9ja2VkIiwic2NvcmUiOjQ3LjUsInNvdXJjZVRydXN0IjoiTlZEIiwicmVhY2hhYmlsaXR5IjoicnVudGltZSJ9XSwiaXNzdWVzIjpbXX0=",
"payloadType": "application/vnd.stellaops.report\u002Bjson",
"signatures": [{
"algorithm": "hs256",
"keyId": "test-key",
"signature": "signature-value"
}]
},
"findings": [
{
"cve": "CVE-2024-9999",
"id": "finding-1",
"reachability": "runtime",
"severity": "Critical"
}
],
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"report": {
"generatedAt": "2025-10-19T12:34:56+00:00",
"imageDigest": "sha256:feedface",
"issues": [],
"policy": {
"digest": "digest-123",
"revisionId": "rev-42"
},
"reportId": "report-abc",
"summary": {
"blocked": 1,
"ignored": 0,
"quieted": 0,
"total": 1,
"warned": 0
},
"verdict": "blocked",
"verdicts": [
{
"findingId": "finding-1",
"status": "Blocked",
"score": 47.5,
"sourceTrust": "NVD",
"reachability": "runtime"
}
]
},
"reportId": "report-abc",
"summary": {
"blocked": 1,
"ignored": 0,
"quieted": 0,
"total": 1,
"warned": 0
},
"verdict": "fail"
},
"attributes": {}
}

View File

@@ -0,0 +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"
}
}

View File

@@ -0,0 +1,20 @@
{
"eventId": "51d0ef8d-3a17-4af3-b2d7-4ad3db3d9d2c",
"kind": "scheduler.rescan.delta",
"tenant": "tenant-acme-solar",
"ts": "2025-10-18T15:40:11+00:00",
"payload": {
"impactedDigests": [
"sha256:0f0a8de5c1f93d6716b7249f6f4ea3a8db451dc3f3c3ff823f53c9cbde5d5e8a",
"sha256:ab921f9679dd8d0832f3710a4df75dbadbd58c2d95f26a4d4efb2fa8c3d9b4ce"
],
"reason": "policy-change:scoring/v2",
"scheduleId": "rescan-weekly-critical",
"summary": {
"newCritical": 0,
"newHigh": 1,
"total": 4
}
},
"attributes": {}
}

View File

@@ -0,0 +1,173 @@
{
"$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": {
"report": {"$ref": "#/definitions/linkTarget"},
"policy": {"$ref": "#/definitions/linkTarget"},
"attestation": {"$ref": "#/definitions/linkTarget"}
}
},
"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."
}
}
}
}
"definitions": {
"linkTarget": {
"type": "object",
"additionalProperties": false,
"properties": {
"ui": {"type": "string", "format": "uri"},
"api": {"type": "string", "format": "uri"}
}
}
}
}

View File

@@ -0,0 +1,183 @@
{
"$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": {
"report": {"$ref": "#/definitions/linkTarget"},
"policy": {"$ref": "#/definitions/linkTarget"},
"attestation": {"$ref": "#/definitions/linkTarget"}
}
},
"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."
}
}
}
}
"definitions": {
"linkTarget": {
"type": "object",
"additionalProperties": false,
"properties": {
"ui": {"type": "string", "format": "uri"},
"api": {"type": "string", "format": "uri"}
}
}
}
}

View File

@@ -0,0 +1,89 @@
{
"$id": "https://stella-ops.org/schemas/events/scanner.report.ready@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["eventId", "kind", "tenant", "ts", "scope", "payload"],
"properties": {
"eventId": {"type": "string", "format": "uuid"},
"kind": {"const": "scanner.report.ready"},
"tenant": {"type": "string"},
"ts": {"type": "string", "format": "date-time"},
"scope": {
"type": "object",
"required": ["repo", "digest"],
"properties": {
"namespace": {"type": "string"},
"repo": {"type": "string"},
"digest": {"type": "string"}
}
},
"payload": {
"type": "object",
"required": ["verdict", "delta", "links"],
"properties": {
"reportId": {"type": "string"},
"generatedAt": {"type": "string", "format": "date-time"},
"verdict": {"enum": ["pass", "warn", "fail"]},
"summary": {
"type": "object",
"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}
},
"additionalProperties": false
},
"delta": {
"type": "object",
"properties": {
"newCritical": {"type": "integer", "minimum": 0},
"newHigh": {"type": "integer", "minimum": 0},
"kev": {"type": "array", "items": {"type": "string"}}
},
"additionalProperties": false
},
"links": {
"type": "object",
"properties": {
"ui": {"type": "string", "format": "uri"},
"rekor": {"type": "string", "format": "uri"}
},
"additionalProperties": false
},
"quietedFindingCount": {"type": "integer", "minimum": 0},
"report": {"type": "object"},
"dsse": {
"type": "object",
"required": ["payloadType", "payload", "signatures"],
"properties": {
"payloadType": {"type": "string"},
"payload": {"type": "string"},
"signatures": {
"type": "array",
"items": {
"type": "object",
"required": ["keyId", "algorithm", "signature"],
"properties": {
"keyId": {"type": "string"},
"algorithm": {"type": "string"},
"signature": {"type": "string"}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}
},
"additionalProperties": true
},
"attributes": {
"type": "object",
"description": "Optional event attributes for downstream correlation.",
"additionalProperties": true
}
},
"additionalProperties": false
}

View File

@@ -0,0 +1,102 @@
{
"$id": "https://stella-ops.org/schemas/events/scanner.scan.completed@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["eventId", "kind", "tenant", "ts", "scope", "payload"],
"properties": {
"eventId": {"type": "string", "format": "uuid"},
"kind": {"const": "scanner.scan.completed"},
"tenant": {"type": "string"},
"ts": {"type": "string", "format": "date-time"},
"scope": {
"type": "object",
"required": ["repo", "digest"],
"properties": {
"namespace": {"type": "string"},
"repo": {"type": "string"},
"digest": {"type": "string"}
}
},
"payload": {
"type": "object",
"required": ["reportId", "digest", "verdict", "summary"],
"properties": {
"reportId": {"type": "string"},
"digest": {"type": "string"},
"verdict": {"enum": ["pass", "warn", "fail"]},
"summary": {
"type": "object",
"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}
},
"additionalProperties": false
},
"delta": {
"type": "object",
"properties": {
"newCritical": {"type": "integer", "minimum": 0},
"newHigh": {"type": "integer", "minimum": 0},
"kev": {"type": "array", "items": {"type": "string"}}
},
"additionalProperties": false
},
"policy": {
"type": "object",
"properties": {
"revisionId": {"type": "string"},
"digest": {"type": "string"}
},
"additionalProperties": false
},
"findings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {"type": "string"},
"severity": {"type": "string"},
"cve": {"type": "string"},
"purl": {"type": "string"},
"reachability": {"type": "string"}
},
"additionalProperties": true
}
},
"report": {"type": "object"},
"dsse": {
"type": "object",
"required": ["payloadType", "payload", "signatures"],
"properties": {
"payloadType": {"type": "string"},
"payload": {"type": "string"},
"signatures": {
"type": "array",
"items": {
"type": "object",
"required": ["keyId", "algorithm", "signature"],
"properties": {
"keyId": {"type": "string"},
"algorithm": {"type": "string"},
"signature": {"type": "string"}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}
},
"additionalProperties": true
},
"attributes": {
"type": "object",
"description": "Optional event attributes for downstream correlation.",
"additionalProperties": true
}
},
"additionalProperties": false
}

View File

@@ -0,0 +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"}
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
{
"$id": "https://stella-ops.org/schemas/events/scheduler.rescan.delta@1.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["eventId", "kind", "tenant", "ts", "payload"],
"properties": {
"eventId": {"type": "string", "format": "uuid"},
"kind": {"const": "scheduler.rescan.delta"},
"tenant": {"type": "string"},
"ts": {"type": "string", "format": "date-time"},
"payload": {
"type": "object",
"required": ["scheduleId", "impactedDigests", "summary"],
"properties": {
"scheduleId": {"type": "string"},
"impactedDigests": {
"type": "array",
"items": {"type": "string"}
},
"summary": {
"type": "object",
"properties": {
"newCritical": {"type": "integer", "minimum": 0},
"newHigh": {"type": "integer", "minimum": 0},
"total": {"type": "integer", "minimum": 0}
}
}
},
"additionalProperties": true
},
"attributes": {
"type": "object",
"description": "Optional event attributes for downstream correlation.",
"additionalProperties": true
}
},
"additionalProperties": false
}