Assurance Setup Prerequisites v1
This contract is the readiness vocabulary for Stella Ops Assurance packs — it names the setup prerequisites (sealed-environment config, tenant/operator settings, and live source data) that a tenant must satisfy before a regulator- facing export or handoff can be treated as production-ready, and separates them so setup can explain what is missing without ever storing secret material. It is for operators completing pack setup, Web/CLI authors building readiness screens, and reviewers tracing a blocked readiness result back to its cause. As the note below explains, the prerequisite-id taxonomy here is a design vocabulary; the two shipped runtimes it abstracts are ExportCenter (assurance-evidence-export-v1) and Notify (assurance-reporting-timeline-v1).
Contract ID: CONTRACT-ASSURANCE-SETUP-PREREQUISITES-V1-005 Status: Draft (forward design spec) Owner: Authority, Web, CLI Schema version: assurance-setup-prerequisites-v1
Implementation note (verified against source 2026-05-30). The
assurance-setup-prerequisites-v1schema name in this document is a forward design vocabulary; it is not emitted by any service today. Two concrete readiness surfaces implement these ideas in shipped code and use their own schema versions:
- Signed-export readiness — ExportCenter, schema
assurance-evidence-export-v1, exposed atGET /v1/exports/assurance/profiles/{profileId}/readiness(AssuranceExportEndpoints,AssuranceExportProfileRegistry). Requires theexport.viewerscope (StellaOpsScopes.ExportViewer).- Operator-handoff / reporting-timeline readiness — Notify, schema
assurance-reporting-readiness-v1, exposed atGET /api/v1/assurance/reporting-timeline-profiles/{timelineProfileId}/readiness(AssuranceReportingProfileEndpoints,AssuranceReportingProfileRegistry). Requires thenotify.viewerscope (StellaOpsScopes.NotifyViewer).The “Response Shape” section below documents both shipped shapes verbatim. The prerequisite-id, status-code, and
scope/secretHandlingtaxonomy in the earlier sections remains a design abstraction that is not serialized by either runtime; the per-examplestatusCodes[]lists are aspirational unless explicitly cross-referenced to a shipped reason code below.
Purpose
assurance-setup-prerequisites-v1 describes readiness checks for optional Assurance packs. It separates sealed/environment prerequisites from tenant/operator settings so setup can explain what is missing without storing secret material or deployment posture in tenant settings. packId and frameworkId cross-reference the assurance-pack-v1catalogue.
Prerequisite Fields
| Field | Type | Required | Notes |
|---|---|---|---|
schemaVersion | string | yes | MUST be assurance-setup-prerequisites-v1. |
prerequisiteId | string | yes | Stable readiness id. |
packId | string | yes | Pack id from assurance-pack-v1. |
frameworkId | string | yes | Framework id. |
scope | string | yes | sealed-environment, tenant-operator, or source-data. |
requiredFor[] | string array | yes | Lifecycle states or export profiles that require it. |
ownerModule | string | yes | Module that owns the setting or readiness check. |
statusCodes[] | string array | yes | Stable missing/configured/invalid reason codes. |
secretHandling | string | yes | no-secret, secret-ref-only, or sealed-only. |
operatorMessage | string | yes | Human-readable setup message. |
Scope Rules
| Scope | Meaning | Storage rule |
|---|---|---|
sealed-environment | Deployment or sealed runtime configuration. | Do not store in tenant/operator settings. Surface only status/reason codes. |
tenant-operator | Customer/operator choice such as enablement, approver, retention, channel destination, or public recipient key. | Store through Authority operator settings. |
source-data | Required live evidence source such as Policy snapshot or EvidenceLocker bundle ref. | Owned by the source module. |
Example: NIS2 SoA Live Export
{
"schemaVersion": "assurance-setup-prerequisites-v1",
"prerequisiteId": "nis2.soa.live-export",
"packId": "nis2",
"frameworkId": "nis2",
"scope": "sealed-environment",
"requiredFor": ["export-ready", "nis2.statement-of-applicability"],
"ownerModule": "ExportCenter",
"statusCodes": [
"authority-profile-url-missing",
"storage-root-missing",
"signing-key-missing",
"signing-provider-missing",
"tenant-export-trust-roots-missing",
"configured"
],
"secretHandling": "sealed-only",
"operatorMessage": "Configure Authority profile access, ExportCenter storage, signing provider, and tenant export trust roots before starting signed NIS2 SoA export runs."
}
The statusCodes above match the reason codes emitted by AssuranceExportProfileRegistry.AddNis2SoaReadinessReasons for profile nis2.statement-of-applicability (all category signed-export): the implementation does not emit a source-control-register-missing code, so it has been removed.
Required readiness checks (per AddNis2SoaReadinessReasons):
authority-profile-url-missing—Nis2SoaExportOptions.AuthorityBaseUrlis unset or not an absolute URI.storage-root-missing—Nis2SoaExportOptions.StorageRootis unset.signing-key-missing—Nis2SoaExportOptions.SigningKeyIdis unset.signing-provider-missing— noICryptoProviderRegistryis registered in the runtime.tenant-export-trust-roots-missing—TrustRootsis empty or any entry is missingTrustRootId/KeyId/PublicKeyPem/Fingerprint, hasNotAfterUtc <= NotBeforeUtc, or has no signer profile.
The Policy control-register snapshot is a source-data input that the shipped registry surfaces as the deterministicInputs entry policy.control-register.snapshot; it is not currently emitted as a blocking readiness reason code.
The source-dashboard-required / configured codes and ownerModule: Platform match the shipped nis2.effectiveness-report branch in AssuranceExportProfileRegistry.GetReadiness. Note the reason is non-blocking in code (Blocking: false): the profile reports signedExportReady = true because sealed export settings are validated by the shared signed-export checks, and the dashboard source report is a runtime input supplied at run start.
Example: NIS2 Effectiveness Monthly Export
{
"schemaVersion": "assurance-setup-prerequisites-v1",
"prerequisiteId": "nis2.effectiveness.monthly-export",
"packId": "nis2",
"frameworkId": "nis2",
"scope": "source-data",
"requiredFor": ["export-ready", "nis2.effectiveness-report"],
"ownerModule": "Platform",
"statusCodes": [
"source-dashboard-required",
"configured"
],
"secretHandling": "no-secret",
"operatorMessage": "Provide the monthly NIS2 effectiveness dashboard source report when starting the effectiveness export."
}
Example: DORA Major Incident Handoff
{
"schemaVersion": "assurance-setup-prerequisites-v1",
"prerequisiteId": "dora.major-incident.handoff",
"packId": "dora",
"frameworkId": "dora",
"scope": "tenant-operator",
"requiredFor": ["handoff-ready", "dora.major-incident-report", "dora.article19.incident"],
"ownerModule": "Notify",
"statusCodes": [
"csirt-destination-missing",
"pgp-recipient-key-missing",
"webhook-signing-key-missing",
"operator-approval-missing",
"publication-handoff-not-configured",
"auto-submit-disabled",
"configured"
],
"secretHandling": "secret-ref-only",
"operatorMessage": "Configure the tenant DORA handoff destination, recipient key, webhook signing key, and operator approval before treating DORA major-incident handoffs as production-ready."
}
Corrected against source. The DORA major-incident handoff readiness is implemented in two places, neither of which emits the
tenant-compliance-profile-missing,lei-missing-or-invalid,dora-financial-entity-flag-missing, orschema-taxonomy-package-missingcodes that earlier revisions of this document listed (no such codes exist in source):
- Notify operator-handoff — timeline profile
dora.article19.incident(AssuranceReportingProfileRegistry). ThestatusCodesabove are the real reason-code constants:csirt-destination-missing,pgp-recipient-key-missing,webhook-signing-key-missing,operator-approval-missing,publication-handoff-not-configured,auto-submit-disabled,configured.auto-submit-disabledis an auto-submit-only code that does not block operator handoff.- ExportCenter signed export — profile
dora.major-incident-report(AssuranceExportProfileRegistry.AddDoraMajorIncidentReportReadinessReasons), which emits the signed-export codes (storage-root-missing,signing-key-missing,signing-provider-missing,tenant-export-trust-roots-missing) plus the source-data codesdora-major-incident-report-source-missing,dora-major-incident-report-owner-approval-missing, anddora-major-incident-report-schema-mapping-missing(legal pindora-major-incident-report-eu-2025-302).
The local-contract encoder can be ready while official EBA XBRL validation is still blocked. The readiness response must distinguish local handoff readiness from the official schema-mapping pin (dora-major-incident-report-schema-mapping-missing in the signed-export surface).
Example: DORA RoI Local-Contract Export
{
"schemaVersion": "assurance-setup-prerequisites-v1",
"prerequisiteId": "dora.roi.local-contract-export",
"packId": "dora",
"frameworkId": "dora",
"scope": "source-data",
"requiredFor": ["export-ready", "dora.roi"],
"ownerModule": "Findings",
"statusCodes": [
"storage-root-missing",
"signing-key-missing",
"signing-provider-missing",
"tenant-export-trust-roots-missing",
"dora-roi-register-source-missing",
"dora-roi-owner-approval-missing",
"dora-roi-schema-mapping-missing",
"configured"
],
"secretHandling": "no-secret",
"operatorMessage": "Provide the DORA RoI register source rows, owner approval, and pinned schema mapping (and configure ExportCenter signed-export settings) before producing the annual RoI handoff."
}
Corrected against source. The shipped profile id is
dora.roi(AssuranceExportProfileRegistry.DoraRoiProfileId), andAddDoraRoiReadinessReasonsemits the codes above — the shared signed-export codes (storage-root-missing,signing-key-missing,signing-provider-missing,tenant-export-trust-roots-missing, categorysigned-export) plus three blockingsource-datacodes:dora-roi-register-source-missing(owner moduleFindings),dora-roi-owner-approval-missing(owner moduleAuthority), anddora-roi-schema-mapping-missing(owner moduleExportCenter). The earlier codes (tenant-compliance-profile-missing,lei-missing-or-invalid,asset-registry-snapshot-missing,integration-roi-metadata-incomplete,retention-policy-invalid,prior-year-hash-missing,official-roi-taxonomy-package-missing) do not exist in source. ThedeterministicInputsdeclared by the profile aredora.entity-register.snapshot,dora.ict-service-register.snapshot,dora.provider-contract-register.snapshot,authority.tenant-compliance-profile, andevidence-locker.bundle-ref.
dora-roi-schema-mapping-missing blocks official XSD validation and fileable-XBRL claims. It must not be collapsed into generic export failure when the local-contract ZIP can still be generated and verified.
Example: DORA Information-Sharing Channel
{
"schemaVersion": "assurance-setup-prerequisites-v1",
"prerequisiteId": "dora.info-sharing.channel",
"packId": "dora",
"frameworkId": "dora",
"scope": "tenant-operator",
"requiredFor": ["handoff-ready", "dora.info-sharing"],
"ownerModule": "Notify",
"statusCodes": [
"storage-root-missing",
"signing-key-missing",
"signing-provider-missing",
"tenant-export-trust-roots-missing",
"dora-info-sharing-source-missing",
"dora-info-sharing-subscriber-approval-missing",
"dora-info-sharing-channel-disabled",
"dora-info-sharing-schema-mapping-missing",
"configured"
],
"secretHandling": "secret-ref-only",
"operatorMessage": "Configure ExportCenter signed-export settings, supply the STIX/TAXII source bundle, obtain subscriber approval, and explicitly enable the per-tenant Article 45 TAXII channel before live sharing."
}
Corrected against source. The shipped profile id is
dora.info-sharingandAddDoraInfoSharingReadinessReasonsemits the codes above: the shared signed-export codes plusdora-info-sharing-source-missing(owner moduleNotify, categorysource-data),dora-info-sharing-subscriber-approval-missing(owner moduleAuthority, categorysource-data),dora-info-sharing-channel-disabled(owner moduleNotifier, categorylive-publication— the live TAXII channel is default-off and must be explicitly enabled per tenant), anddora-info-sharing-schema-mapping-missing(owner moduleExportCenter, contractdora-info-sharing-event-v1). The earlier codes (dora-purpose-channel-missing,subscriber-approval-missing,endpoint-allowlist-missing,verification-key-missing,redaction-profile-missing) are not present in source.
General webhook or custom Notify channels are not valid substitutes for this prerequisite: the live TAXII publication channel (dora-info-sharing-channel-disabled) is default-off and must be explicitly enabled in per-tenant configuration.
Example: DORA TLPT Evidence Pack
{
"schemaVersion": "assurance-setup-prerequisites-v1",
"prerequisiteId": "dora.tlpt.evidence-pack",
"packId": "dora",
"frameworkId": "dora",
"scope": "source-data",
"requiredFor": ["export-ready", "dora.tlpt-evidence-pack"],
"ownerModule": "EvidenceLocker",
"statusCodes": [
"storage-root-missing",
"signing-key-missing",
"signing-provider-missing",
"tenant-export-trust-roots-missing",
"dora-tlpt-evidence-pack-scope-missing",
"dora-tlpt-evidence-pack-white-team-signoff-missing",
"dora-tlpt-evidence-pack-schema-mapping-missing",
"configured"
],
"secretHandling": "secret-ref-only",
"operatorMessage": "Configure ExportCenter signed-export settings, then provide the live Graph asset-registry TLPT scope, white-team sign-off, and pinned TLPT schema mapping before treating TLPT evidence packs as production-ready."
}
Corrected against source. The shipped profile id is
dora.tlpt-evidence-pack(AssuranceExportProfileRegistry.DoraTlptEvidencePackProfileId), andAddDoraTlptEvidencePackReadinessReasonsemits the codes above — the shared signed-export codes (storage-root-missing,signing-key-missing,signing-provider-missing,tenant-export-trust-roots-missing, categorysigned-export) plus three blockingsource-datacodes:dora-tlpt-evidence-pack-scope-missing(owner moduleTlptScoper; scope rows derived from a live Graph Asset Registry snapshotasset-registry.v1),dora-tlpt-evidence-pack-white-team-signoff-missing(owner moduleEvidenceLocker), anddora-tlpt-evidence-pack-schema-mapping-missing(owner moduleExportCenter; contracttlpt-evidence-pack-v1). The earlier codes (tlpt-scope-missing,tlpt-baseline-missing,asset-registry-snapshot-missing,reachability-subgraph-missing,audit-action-emitter-missing) do not exist in source. The profiledeterministicInputsaretlpt-scoper.live-asset-registry-snapshot,tlpt-scoper.baseline-ref,evidence-locker.tlpt-controls-inventory, andevidence-locker.bundle-ref.
Example: CRA Product Security Publication
{
"schemaVersion": "assurance-setup-prerequisites-v1",
"prerequisiteId": "cra.product-security.publication",
"packId": "cra.product-security",
"frameworkId": "cra",
"scope": "sealed-environment",
"requiredFor": ["publication-ready"],
"ownerModule": "Router",
"statusCodes": [
"security-mailbox-unverified",
"intake-key-expired-or-missing",
"rotation-roles-missing",
"support-lifecycle-metadata-missing",
"configured"
],
"secretHandling": "no-secret",
"operatorMessage": "Verify product-security mailbox delivery/access and publish a non-expired encryption-capable intake key before live public CRA product-security publication."
}
This prerequisite is a live-publication gate. It does not block local signed CRA technical-file or conformity-dossier export.
Example: CRA Technical Documentation Signed Export
{
"schemaVersion": "assurance-setup-prerequisites-v1",
"prerequisiteId": "cra.technical-documentation.signed-export",
"packId": "cra.technical-documentation",
"frameworkId": "cra",
"scope": "sealed-environment",
"requiredFor": ["export-ready", "cra.technical-file", "cra.conformity-dossier"],
"ownerModule": "ExportCenter",
"statusCodes": [
"storage-root-missing",
"signing-key-missing",
"signing-provider-missing",
"tenant-export-trust-roots-missing",
"configured"
],
"secretHandling": "sealed-only",
"operatorMessage": "Configure ExportCenter storage, signing, and tenant export trust roots before treating CRA technical-documentation exports as production signed evidence."
}
Corrected against source. Both shipped CRA profiles —
cra.technical-file(CraTechnicalFileProfileId) andcra.conformity-dossier(CraConformityDossierProfileId) — compute signed-export readiness solely viaAddAssuranceSignedExportReadinessReasons, which emits only the four shared signed-export codes (storage-root-missing,signing-key-missing,signing-provider-missing,tenant-export-trust-roots-missing). They do not emit anevidence-bundle-ref-missingcode (no such code exists in source); the evidence-locker bundle ref is adeterministicInputs/readinessPrerequisitesentry, not a blocking reason. Both profiles additionally surface the CRA live-publication preflight codes (see “CRA Product Security Publication” example) viaAddCraPublicationReadinessReasons, reported as a separatelivePublicationReadyboolean.
The ExportCenter Assurance registry exposes these signed-export checks through GET /v1/exports/assurance/profiles/{profileId}/readiness. The response reports only booleans and stable reason codes, with secretValuesExposed=false; it must not echo storage paths, key material, provider secrets, or public/private key contents.
Response Shape
The abstract prerequisiteId/status/reasonCodes/secretHandling vocabulary used in the examples above is a design abstraction; it is not the wire shape of either shipped runtime. The two concrete readiness responses are documented verbatim below from source.
Signed-export readiness (ExportCenter)
Emitted by GET /v1/exports/assurance/profiles/{profileId}/readiness (AssuranceExportReadinessResponse):
{
"schemaVersion": "assurance-evidence-export-v1",
"profileId": "nis2.statement-of-applicability",
"tenantId": "tenant-a",
"frameworkId": "nis2",
"packId": "nis2",
"exportType": "statement-of-applicability",
"state": "blocked",
"signedExportReady": false,
"livePublicationReady": null,
"reasonCodes": ["signing-provider-missing"],
"reasons": [
{
"code": "signing-provider-missing",
"category": "signed-export",
"summary": "Export signing provider is not registered in this runtime.",
"ownerModule": "ExportCenter",
"blocking": true
}
],
"secretValuesExposed": false
}
stateis one ofexport-readyorblocked(`signedExportReady ? “export-ready”- “blocked”
).livePublicationReadyisnullfor profiles with no live- publication surface and a boolean for the CRA profiles. There is no service- emitteddisabled/unavailable/unknownstate; an unrecognisedprofileIdreturns HTTP 404 (assurance_export_profile_not_found), and an unknown profile matched at runtime yields theprofile-unavailablereason withsignedExportReady = false. Consumers must still treat any non-export-ready` state as fail-closed for production export.
Operator-handoff / reporting-timeline readiness (Notify)
Emitted by GET /api/v1/assurance/reporting-timeline-profiles/{timelineProfileId}/readiness (AssuranceReportingProfileReadiness):
{
"schemaVersion": "assurance-reporting-readiness-v1",
"timelineProfileId": "dora.article19.incident",
"frameworkId": "dora",
"packId": "dora",
"reportType": "major-ict-incident",
"claimBoundary": "operator-support",
"tenantId": "tenant-a",
"status": "blocked",
"operatorHandoffReady": false,
"autoSubmitReady": false,
"reasonCodes": ["operator-approval-missing", "publication-handoff-not-configured"],
"operatorHandoffReasonCodes": ["operator-approval-missing", "publication-handoff-not-configured"],
"autoSubmitReasonCodes": ["auto-submit-disabled", "operator-approval-missing", "publication-handoff-not-configured"],
"secretValuesExposed": false,
"updatedAt": "2026-05-01T00:00:00Z"
}
status is one of configured or blocked (operatorHandoffReady ? "configured" : "blocked"). Operator-handoff readiness and auto-submit readiness are reported separately; auto-submit-disabled is an auto-submit-only code that never blocks operator handoff. Both runtimes set secretValuesExposed = false and never echo secret material.
Security Rules
- Secret values MUST NOT appear in setup responses, logs, or CLI output.
- Tenant/operator settings may store public recipient keys and public contact metadata, but not private keys or provider secrets.
- Sealed/environment status may be reported as booleans or reason codes only.
- Public publication prerequisites must be distinguished from local export prerequisites.
