NIS2 Effectiveness Report Contract v1

Contract ID: CONTRACT-NIS2-EFFECTIVENESS-REPORT-V1-062 Status: Published (sprint 062 monthly export work) Owner: Export Center Guild Schema version: nis2-effectiveness-report-v1 Bundle schema version: nis2-effectiveness-report-bundle-v1 Input contract: nis2-effectiveness-dashboard-v1 DSSE payload type: application/vnd.stellaops.nis2.effectiveness-report.v1+json

Part of the Stella Ops Contracts index. Audience: Export Center and CLI implementers building the monthly NIS2 effectiveness export, and auditors/reviewers who verify the resulting offline bundle. The input dashboard is produced by the KPI Telemetry Schema read projection; the linked control register is the NIS2 Control Register.

Implementation references (ground truth):

Purpose

The NIS2 effectiveness report export pins the monthly 13-area effectiveness dashboard shape into a deterministic bundle for offline auditor review. The report is evidence-pointer-first: it preserves the dashboard metrics, linked controls, target/control snapshot references, hashes, and blockers that were present at export time.

This contract does not claim production qualified signing. The current CLI path uses a local HMAC DSSE-shaped envelope so the bundle can be reproduced and tamper-checked offline. Production CAdES/KMS signing remains a separate platform integration and must not be inferred from the DSSE signature alg = "HS256".

HMAC operations are not raw System.Security.Cryptography calls: they route through StellaOps.Cryptography.DefaultHmacAlgorithm.Instance.ComputeMac(..., HmacAlgorithmName.HmacSha256) (Sprint 20260430_000 HMAC-CLEANUP-EXPORT-NIS2) so that regional crypto plugins (FIPS/GOST/SM/eIDAS) can substitute the implementation. The DSSE signature alg is always recorded as HS256 regardless of the substituted provider.

Bundle Envelope

{
  "schemaVersion": "nis2-effectiveness-report-bundle-v1",
  "sourceReportSchemaVersion": "nis2-effectiveness-dashboard-v1",
  "sourceReport": {},
  "monthlyReport": {},
  "manifest": {},
  "signature": {}
}

Field notes (from Nis2EffectivenessReportBundle):

FieldTypeNotes
schemaVersionstringAlways nis2-effectiveness-report-bundle-v1.
sourceReportSchemaVersionstringAlways nis2-effectiveness-dashboard-v1.
sourceReportobjectThe normalized nis2-effectiveness-dashboard-v1 source report, embedded verbatim.
monthlyReportobjectThe nis2-effectiveness-report-v1 monthly report (see below).
manifestobject{ "generatedAt", "reportMonth", "entries": [] }. generatedAt and reportMonth mirror the report; entries[] is documented under Manifest Entries.
signatureobjectA single DSSE envelope (Nis2EffectivenessDsseEnvelope); not a detached signature object. See Signing and Verification for its shape.

The DSSE envelope embedded in signature is:

{
  "payloadType": "application/vnd.stellaops.nis2.effectiveness-report.v1+json",
  "payload": "<base64 of canonical monthlyReport bytes>",
  "signatures": [
    { "keyid": "<key id>", "alg": "HS256", "sig": "<base64 HMAC-SHA256>" }
  ]
}

Monthly Report

{
  "schemaVersion": "nis2-effectiveness-report-v1",
  "tenantId": "tenant-a",
  "reportMonth": "2026-04",
  "generatedAt": "2026-04-30T12:00:00Z",
  "period": {
    "start": "2026-04-01",
    "endExclusive": "2026-05-01"
  },
  "source": "live",
  "rollingWindow": "rolling-30d",
  "sourceReportHash": "sha256:...",
  "sourceReferences": {
    "sourceReportRef": "nis2-effectiveness-dashboard://tenant-a/2026-04#sha256:...",
    "targetDocumentHash": "sha256:...",
    "targetDocumentRef": "policy://target-documents/nis2/2026-04",
    "controlRegisterSnapshotHash": "sha256:...",
    "controlRegisterSnapshotRef": "policy://control-registers/nis2/2026-04",
    "policySnapshotRef": "policy://snapshots/nis2/2026-04"
  },
  "areaCount": 13,
  "areas": [],
  "blockers": [],
  "reportHash": "sha256:..."
}

Required Fields

FieldTypeRequiredNotes
schemaVersionstringyesMust be nis2-effectiveness-report-v1.
tenantIdstringyesTenant that owns the effectiveness report.
reportMonthstringyesCalendar month in yyyy-MM form.
generatedAttimestampyesCopied from the source dashboard report after UTC normalization.
period.startdateyesFirst day of reportMonth.
period.endExclusivedateyesFirst day of the following month.
sourcestringyesSource label from the dashboard report, for example live or contract-fixture.
rollingWindowstringyesSource dashboard rolling window.
sourceReportHashstringyesSHA-256 of the canonical normalized sourceReport.
sourceReferencesobjectyesImmutable refs and hashes for source dashboard, target overrides, control register snapshot, and Policy snapshot when available.
areaCountnumberyesMust equal 13.
areas[]arrayyesExactly 13 areas, numbered 1 through 13 exactly once.
blockers[]arrayyesExplicit gaps from the source report or export adapter. Empty only when all required upstream references are pinned.
reportHashstringyessha256:-prefixed SHA-256 over the canonical JSON of the report hash payload (Nis2EffectivenessReportHashPayload), which excludes reportHash itself.

Area Shape

Each areas[] item (Nis2EffectivenessReportArea) preserves the source dashboard values:

Note: the source dashboard area carries a per-area rollingWindow, but the report area drops it (ToReportArea does not copy it). The report-level rollingWindow is the authoritative window for the monthly report.

The adapter sorts areas by areaNumber, metrics by metricName then kpiKey, linked controls by controlId then label, and evidence refs lexicographically. Validation requires each area to carry at least one metric, and the source report to contain exactly 13 areas numbered 1 through 13 exactly once (ValidateSourceReport).

Blockers

The exporter records blockers instead of fabricating upstream evidence. Each blockers[] item (Nis2EffectivenessReportBlocker) has four fields: code, summary, detail, and source (provenance of the blocker). Blockers are sorted by code, then summary, then detail, then source.

CodesourceMeaning
source:<code>nis2-effectiveness-dashboard-v1Blocker propagated from the source dashboard report (the original code is prefixed with source:).
source-contract-fixtureexportcenterEmitted when the source report’s source field equals contract-fixture; the bundle is deterministic format evidence only, not live tenant telemetry.
target-document-hash-missingexportcenterNo target document hash was present in the source report or CLI option.
control-register-snapshot-hash-missingexportcenterNo Policy control-register snapshot hash was present in the source report or CLI option.
policy-snapshot-ref-missingexportcenterNo Policy snapshot ref was supplied for replay pinning.

Manifest Entries

manifest carries top-level generatedAt and reportMonth plus an entries[] array. Each entry (Nis2EffectivenessBundleEntry) is { "path", "mediaType", "sha256" }, where sha256 is the sha256:-prefixed SHA-256 of the canonical bytes of the referenced object. The manifest must contain exactly these three logical paths and media types:

PathMedia typesha256 is over
source/nis2-effectiveness-dashboard.jsonapplication/vnd.stellaops.nis2.effectiveness-dashboard.v1+jsoncanonical sourceReport bytes
reports/nis2-effectiveness-report.jsonapplication/vnd.stellaops.nis2.effectiveness-report.v1+jsoncanonical monthlyReport bytes
signatures/nis2-effectiveness-report.dsse.jsonapplication/vnd.dsse+jsoncanonical signature (DSSE envelope) bytes

The reports/... entry media type is the same value as the DSSE payloadType (Nis2EffectivenessConstants.PayloadType).

Determinism Rules

Signing and Verification

Verification error codes

Verify returns IsValid plus a list of machine-readable error codes. The codes include:

CodeCause
bundle_json_invalid:<exception> / bundle_json_emptyBundle bytes are not valid JSON / deserialized to null.
bundle_schema_version_mismatchschemaVersion is not nis2-effectiveness-report-bundle-v1.
source_report_schema_version_mismatch / source_report_schema_mismatchBundle-level or embedded source-report schema is not nis2-effectiveness-dashboard-v1.
source_report_missing / monthly_report_missing / manifest_missing / signature_missingA required top-level section is absent.
report_schema_version_mismatchmonthlyReport.schemaVersion is not nis2-effectiveness-report-v1.
report_area_count_mismatchareaCount != 13 or areas.length != 13.
source_report_hash_mismatchRecomputed source report hash differs from monthlyReport.sourceReportHash.
report_hash_mismatchRecomputed report hash differs from monthlyReport.reportHash.
manifest_entries_missing / manifest_entry_missing:<path> / manifest_entry_hash_mismatch:<path>Manifest entry absent or its sha256 does not match recomputed bytes.
dsse_payload_type_mismatchDSSE payloadType is not the expected payload type.
dsse_payload_invalid_base64 / dsse_payload_mismatchDSSE payload is not base64 / does not equal the canonical monthly report bytes.
dsse_signature_missing / dsse_signature_invalid_base64 / dsse_signature_mismatchNo signature matches the supplied key id+alg / sig is not base64 / HMAC does not match.

CLI Surface

The registered CLI preserves a deterministic local/offline path and can also delegate production to the shipped ExportCenter Assurance run endpoint. The local path resolves signing material from operator-controlled CLI inputs; --via-export-center posts the same source dashboard to ExportCenter, where signing material is resolved server-side, and downloads the produced bundle.

The Assurance profile registry advertises the registered compatibility command exactly as stella export nis2-effectiveness.

Assurance Profile Discovery And Run Execution (HTTP)

The nis2.effectiveness-report profile is discoverable and executable through the framework-aware Assurance export API (AssuranceExportEndpoints):

When operator-owned signing and storage configuration is ready, profile readiness reports the non-blocking source-dashboard-required reason because the monthly NIS2 effectiveness dashboard remains a produce-time input. Missing signing material fails closed instead of falling back to request-supplied secrets.