CRA Technical File v1

Contract ID: CONTRACT-CRA-TECH-FILE-V1-027 Status: Draft Owner: ExportCenter Last Updated: 2026-04-30

Purpose

cra-tech-file-v1 defines the deterministic bundle index used by ExportCenter to assemble a CRA (EU Cyber Resilience Act) Annex VII technical documentation file for a Stella product release. The bundle is evidence-pointer-first: sections cite immutable evidence references, hashes, signed release manifests, portable Evidence Locker bundles, and control-register snapshots instead of copying mutable runtime state.

Audience: ExportCenter engineers and regulatory-export operators producing CRA technical files, plus auditors verifying one offline. This contract is the building block embedded by conformity-dossier-v1; read that contract for the full conformity-assessment dossier that wraps this file.

Schema Pinning

Bundle Layout

index.json
checksums.txt
sections/01-general-description.json
sections/02-design-development-manufacture.json
sections/03-risk-assessment.json
sections/04-eu-declaration-of-conformity.json
sections/05-harmonised-standards.json
sections/06-test-reports.json
sections/07-sbom.json
sections/08-attestations.json
sections/09-audit-log-slice.json
sections/10-control-register.json
sections/11-support-policy.json
signatures/index.dsse.json
signatures/index.cadenced.dsse.json

index.json is authoritative. signatures/index.dsse.json is present when the producer signs the bundle index, either through the local offline HMAC path or the production Signer/KMS path. signatures/index.cadenced.dsse.json is present only when production cadenced-envelope mode is requested. checksums.txt is a deterministic convenience file for offline operators and covers all bundle entries except itself.

Required index.json Fields

FieldTypeRequirement
schemaVersionstringMUST equal cra-tech-file-v1.
generatedAtRFC3339 timestampUTC timestamp chosen by the caller, not wall-clocked inside the adapter.
productobjectProduct reference (productRef, name, version, manufacturer, optional description).
releaseobjectRelease version plus optional releaseManifestRef, sbomRef, placedOnMarketAt, and supportUntil.
sourceRefsobjectOptional evidencePortableBundleRef, releaseManifestRef, and controlRegisterRef.
sectionsarrayThe fixed section list above, in numeric order.
blockersarrayMissing upstream dependencies that prevent a complete Annex VII file (dependency, reason, optional sprintRef), sorted by dependency.
signingobjectCurrent signing state for the bundle index. Signed bundles include status, payloadType, signerRef, algorithm, signaturePath, envelopeMode, cadesProfile, and cadesStatus; cadenced bundles also include cadencedSignaturePath. Unsigned local bundles MUST remain explicit with status = not-signed and carry a blockedBy reason.

Each sections[] entry MUST include:

FieldTypeRequirement
sectionIdstringOne of the fixed section ids in the bundle layout.
annexViiRefstringHuman-readable Annex VII mapping.
titlestringStable display title.
pathstringRelative bundle path.
orderinteger1-based numeric section order (matches the filename prefix).
mediaTypestringSection media type (always application/vnd.stellaops.cra.tech-file.section.v1+json).
sha256stringSHA-256 hash of the section file.
sizeBytesintegerByte length of the canonicalized section file; the verifier rejects the bundle on a size mismatch (section_size_mismatch).
statusstringcomplete, incomplete, or blocked. The eu-declaration-of-conformity section instead carries the DoC lifecycle status (template, operator-signed, or signature-invalid); the legacy stub value is retired.
evidenceRefsarrayImmutable refs backing the section.

EU Declaration Of Conformity (Annex V)

The eu-declaration-of-conformity section (Annex VII(4)) embeds a structured EU declaration of conformity (Annex V). Stella never authors or signs a legally-binding DoC on the operator’s behalf — it ships an operator-completable template pre-populated from known evidence and then embeds the operator’s own signed declaration. The unsigned state is always an explicit fail-closed value; it is never a false signed/valid.

The section’s euDeclarationOfConformity object (schemaVersion = cra-eu-declaration-of-conformity-v1) carries:

FieldTypeRequirement
schemaVersionstringMUST equal cra-eu-declaration-of-conformity-v1.
statusstringtemplate (operator-completable, fail-closed — the default when no signed DoC is supplied), operator-signed (operator’s detached signature verified and content bound by hash), or signature-invalid (a supplied DoC whose signature failed verification — fail-closed).
productName, productRef, productVersion, productDigeststringProduct identity pre-populated from release evidence.
manufacturerNamestringPre-populated from the product manufacturer.
manufacturerAddress, signatoryName, signatoryRolestringLegal fields — OPERATOR-TO-COMPLETE placeholders in a template; populated by the operator on signing.
conformityAssessmentRoute, classificationRefstringConformity-assessment route (default self-assessment (Module A)) keyed off cra-product-classification.md.
appliedStandardsarrayApplied harmonised standards/specs (CraHarmonisedStandardRef).
sbomRef, supportUntilstring / datePre-populated from release evidence.
placeOfIssue, dateOfIssuestring / datePlace + date of issue (operator-completed).
operatorSignatureobjectPresent once an operator-signed DoC is embedded: contentFormat (json/pdf), contentSha256 (binds the operator’s DoC content), contentPath, algorithm, signerKeyId, signaturePath, verified, optional verificationError.
notesarrayHuman-readable lifecycle notes.

When the operator supplies a signed DoC, the producer validates the detached signature through StellaOps.Cryptography (ICryptoProviderRegistryICryptoSigner, so regional EIDAS/FIPS/GOST/SM/HSM plugins apply), binds the operator content by sha256, embeds eu-declaration-of-conformity/operator-doc.{json,pdf} and eu-declaration-of-conformity/operator-doc.sig into the bundle, and sets status = operator-signed (the section status becomes complete). An invalid/missing signature is rejected with a precise reason and nothing is embedded.

Evidence Reference Shape

{
  "sectionId": "sbom",
  "kind": "sbom",
  "ref": "evidence://bundle/release-2026.04/sbom",
  "sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
  "mediaType": "application/vnd.cyclonedx+json",
  "description": "Release SBOM"
}

ref MUST be immutable or content-addressed. If a source system only has mutable URLs, the adapter MUST record a blocking risk rather than presenting the section as complete.

Signing And Audit

index.json is the DSSE payload for both local offline signing and production EU regulatory signing. The file-backed CLI path signs canonical index.json with HMAC-SHA256, records signing.algorithm = HS256, and stores the envelope at signatures/index.dsse.json:

{
  "status": "signed",
  "payloadType": "application/vnd.stellaops.cra.tech-file.index.v1+json",
  "signerRef": "eu-local-cra-tech-file",
  "algorithm": "HS256",
  "signaturePath": "signatures/index.dsse.json",
  "envelopeMode": "dsse",
  "cadesProfile": "None",
  "cadesStatus": "not_requested"
}

When no local signing key is supplied, the ExportCenter adapter records:

{
  "status": "not-signed",
  "payloadType": "application/vnd.stellaops.cra.tech-file.index.v1+json",
  "blockedBy": "local signing key or production CRA technical-file signer is required",
  "envelopeMode": "none",
  "cadesProfile": "None",
  "cadesStatus": "not_requested"
}

Production signing MUST use the EU signing payload registry id cra-tech-file-v1, signer profile tenant-regulatory-export, and the Signer/KMS crypto-provider contract (CraTechFileCryptoProviderSigner resolving an ICryptoProviderRegistry signer). The recorded signerRef is the resolved signer key id and algorithm is whatever the resolved signer reports (ICraTechFileDsseSigner.AlgorithmId); the crypto-provider signer defaults to ES256 (CraTechFileCryptoProviderSigningOptions.AlgorithmId = SignatureAlgorithms.Es256). The default production envelope mode is DSSE only:

{
  "status": "signed",
  "payloadType": "application/vnd.stellaops.cra.tech-file.index.v1+json",
  "signerRef": "<resolved-signer-key-id>",
  "algorithm": "ES256",
  "signaturePath": "signatures/index.dsse.json",
  "envelopeMode": "dsse",
  "cadesProfile": "None",
  "cadesStatus": "not_requested"
}

If the resolved signer reports a different signing algorithm (for example a regional-crypto plugin), algorithm reflects that value rather than ES256. BuildProductionSignedAsync rejects the bundle when the signature’s key id does not match the requested signer identity.

When envelopeMode = cadenced, the bundle keeps the direct index DSSE envelope and adds signatures/index.cadenced.dsse.json, an outer DSSE envelope over the cadenced envelope bytes. cadesProfile MAY be None, BaselineB, BaselineT, BaselineLT, or BaselineLTA. CAdES provider-pack availability is reported in the cadenced envelope companion metadata; missing production QES/QSCD or timestamp/archive providers MUST be represented as blocked companion metadata rather than silently fabricating long-term evidence.

Every Build/BuildProductionSignedAsync result also carries an in-bundle CraTechFileAuditEvent (schema cra-tech-file-audit-event-v1, event type cra.tech_file.bundle.materialized) recording the product ref, release version, index hash, bundle hash, signing status, and signer ref. This materialization event is produced for both signed and unsigned bundles and is returned alongside the bundle, not embedded in index.json.

The final exporter MUST emit durable regulatory evidence after the archive hash is known. RecordRegulatoryEvidenceAsync records an EvidenceLocker regulatory ArtifactSigned audit event (regime Cra, artifact type CraTechnicalFile) and upserts a CRA technical-file artifact-ledger record with the bundle hash, index hash, signer key id, signer fingerprint when verified, signature path (the cadenced path when present, otherwise the DSSE path), and source evidence refs (including a synthetic exportcenter://cra-tech-file/index/<indexHash> ref). Email-shaped actor refs are hashed to an opaque actor:sha256:<hex> form. That event is outside index.json to avoid a self-referential bundle hash and requires a signer identity.

HTTP Produce Surface

In addition to the stella export cra-tech-file CLI path, ExportCenter exposes an authenticated HTTP produce endpoint that reuses the same CraTechFileAdapter (BuildProductionSignedAsync) so the materialized bundle is byte-deterministic and the inner DSSE-signed index.json is identical to the CLI for the same frozen inputs (only the ECDSA signature bytes vary run-to-run). Sprint reference: SPRINT_20260616_006_ExportCenter_cra_dora_bundle_http_parity.md.

MethodRouteScope (policy)Purpose
POST/v1/exports/assurance/profiles/cra.technical-file/runsexport.operatorProduce a signed bundle (run handle).
GET/v1/exports/assurance/profiles/cra.technical-file/runs/{runId}export.viewerRead the produce run.
GET/v1/exports/assurance/runs/{runId}/bundleexport.viewerDownload the produced bundle.

Offline And Replay Expectations

Known v1 Blockers