Files
git.stella-ops.org/docs/events/orchestrator-scanner-events.md
master 96d52884e8
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Add Policy DSL Validator, Schema Exporter, and Simulation Smoke tools
- Implemented PolicyDslValidator with command-line options for strict mode and JSON output.
- Created PolicySchemaExporter to generate JSON schemas for policy-related models.
- Developed PolicySimulationSmoke tool to validate policy simulations against expected outcomes.
- Added project files and necessary dependencies for each tool.
- Ensured proper error handling and usage instructions across tools.
2025-10-27 08:00:11 +02:00

8.2 KiB
Raw Blame History

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).
  • verdictpass, 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.reportpolicy.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 WebServiceSCANNER-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.