DORA Info Sharing Event Contract v1
Version: dora-info-sharing-event-v1
Owner: Notify platform
Implementation: src/Notify/__Libraries/StellaOps.Notify.Connectors.DoraInfoSharing/
CLI: src/Cli/StellaOps.Cli/Commands/DoraInfoSharingCommandGroup.cs
Decision: docs/europe/decisions-log.md (DORA-Q5)
Part of the Stella Ops Contracts index. Audience: implementers and reviewers working on the Notify DORA info-sharing connector, its CLI, and downstream TAXII subscriber delivery.
Purpose
This contract defines Stella Ops’ DORA Article 45 outbound information-sharing batch. The canonical v1 format is a STIX 2.1-aligned JSON bundle delivered via a TAXII 2.1 collection manifest. MISP interoperability is future bridge work, not the v1 canonical path.
Export Center Assurance Profile
ExportCenter advertises the dora.info-sharing assurance profile for discovery and readiness. Signed export readiness remains fail-closed on dora-info-sharing-source-missing, dora-info-sharing-subscriber-approval-missing, dora-info-sharing-channel-disabled, and dora-info-sharing-schema-mapping-missing until the request supplies the source events, subscriber approval, channel enablement, and schema mapping required by the Notify DORA information-sharing connector.
POST /v1/exports/assurance/profiles/dora.info-sharing/runs is registered on the shared Assurance produce surface. While readiness is blocked, it returns HTTP 409 assurance_export_readiness_blocked. A readiness-satisfying request supplies { "doraInfoSharing": { "request": { ... }, "subscriberApprovalRef": "..." } }, where request is a JSON-friendly AssuranceProduceDoraInfoSharingExportRequest carrying tenant, collection, generated timestamp, channel, redaction profile, source events, and optional subscriber id. ExportCenter maps that DTO into the real Notify DoraInfoSharingExportRequest, invokes the Notify STIX/TAXII and DSSE services, and stores a deterministic wrapper bundle with media type application/vnd.stellaops.dora-info-sharing.http-bundle.v1+json. Signing material is sealed operator configuration under Export:Assurance:DoraInfoSharing (SigningKeyFile / SigningKey and SigningKeyId) and is never accepted from the request body.
Schema Pinning
All pinned values are declared as compile-time constants in DoraInfoSharingConstants and must not drift between the library, CLI, and this contract.
- STIX object model: pinned to STIX
2.1for v1 (DoraInfoSharingConstants.StixSpecVersion). - TAXII collection manifest: pinned to TAXII
2.1for v1 (DoraInfoSharingConstants.TaxiiVersion). - DSSE payload type:
application/vnd.stellaops.dora-info-sharing.stix-batch.v1+json(DoraInfoSharingConstants.DssePayloadType). - EU signing payload registry id:
dora-info-sharing-event-v1(docs/contracts/eu-signing-payload-registry-v1.md). The registry binds this contract to signing key purposetenant-regulatory-sharingand usesx_stella_dora_info_sharing.contract_versionas the version discriminator. - STIX media type:
application/stix+json;version=2.1(DoraInfoSharingConstants.StixMediaType). - TAXII subscriber delivery media type:
application/vnd.stellaops.dora-info-sharing.taxii-delivery.v1+json(DoraInfoSharingConstants.TaxiiDeliveryMediaType). - Channel purpose discriminator:
dora-info-sharing(DoraInfoSharingConstants.Purpose, mapped toNotifyChannelPurpose.DoraInfoSharing). - The connector must not fetch live OASIS, authority, or SaaS schemas at test or runtime to validate v1. Version bumps require a new contract version.
Batch Shape
The exported payload is canonical JSON. The bundle is serialised with CanonJson.Canonicalize (RFC 8785-style JCS canonical JSON); the x_stella_* extension properties below are emitted verbatim by DoraInfoSharingStixBatchBuilder.
{
"type": "bundle",
"id": "bundle--<deterministic-uuid>",
"objects": [
{
"type": "indicator|incident|threat-actor",
"spec_version": "2.1",
"id": "<type>--<deterministic-uuid>",
"created": "2026-04-30T08:00:00.000Z",
"modified": "2026-04-30T08:30:00.000Z",
"name": "string",
"x_stella_authorised_pii": { "contact_email": "ops@example.test" },
"x_stella_minimisation": {
"profile_id": "dora-info-sharing-strict-v1",
"mode": "strict|explicit-authorisation",
"redacted_fields": ["description", "pii.contact_email"],
"authorised_pii_fields": ["contact_email"],
"authorisation_ref_hash": "sha256:<hex>"
}
}
],
"x_stella_dora_info_sharing": {
"contract_version": "dora-info-sharing-event-v1",
"stix_spec_version": "2.1",
"taxii_version": "2.1",
"collection_id": "string",
"generated_at": "2026-04-30T09:00:00.000Z",
"tenant_id_hash": "sha256:<hex>",
"channel_id": "string",
"channel_purpose": "dora-info-sharing",
"object_count": 1,
"source_event_refs": ["sha256:<hex>"],
"subscriber_id_hash": "sha256:<hex>",
"redaction_profile": {
"profile_id": "dora-info-sharing-strict-v1",
"mode": "strict"
}
}
}
Field notes (grounded in DoraInfoSharingStixBatchBuilder):
- Object timestamps use the millisecond-precision UTC format
yyyy-MM-ddTHH:mm:ss.fffZ. x_stella_authorised_piiis emitted only when explicit-authorisation mode released one or more allowlisted PII fields for that object.- On
x_stella_minimisation,authorised_pii_fieldsis emitted only when the profile declares authorised PII fields, andauthorisation_ref_hashis the SHA-256 of the profileauthorisationRef(the raw reference is never embedded). x_stella_dora_info_sharing.subscriber_id_hashis emitted only when the export request carries asubscriberId.tenant_id_hash,source_event_refs, andsubscriber_id_hashare allsha256:-prefixed hex digests.- Bundle and object ids are SHA-256 name-based (v5-style) UUIDs derived from tenant, collection, profile, kind, and source-event inputs (
DoraInfoSharingIds), so identical inputs reproduce identical ids.
Supported Object Kinds
The object kind enum (DoraInfoSharingObjectKind) has exactly three members: Indicator, Incident, ThreatActor.
indicator: requires a STIXpattern(build fails ifindicatorPatternis absent) and emitspattern_type: "stix"plusvalid_from(set to the sourcecreatedinstant).incident: emits Stella extension propertyx_stella_incident_kind: "dora-ict-incident".threat-actor: emits STIXthreat_actor_types(defaults to["unknown"]when none are supplied); optionalaliasesare emitted when present and Stella target sectors are carried inx_stella_target_sectors.
Common optional STIX fields emitted on any kind when present on the source event: description (subject to redaction), labels, confidence (0–100), and external_references (each with source_name plus external_id and/or url).
Data Minimisation
Every export requires a DoraInfoSharingRedactionProfile.
- Strict mode is the default. It removes free-text descriptions and all fields declared in the source event
piimap. - Explicit authorisation mode requires an
authorisationRefand an allowlist of PII field names. Only those allowlisted PII fields can be emitted underx_stella_authorised_pii; non-allowlisted PII remains redacted. - If free-text descriptions are explicitly authorised, values from non-allowlisted PII fields are still scrubbed from the description (replaced with
[redacted]) before canonicalization. - The full authorisation reference is not embedded in the STIX payload. The payload includes only
authorisation_ref_hash(SHA-256 of theauthorisationRef). - PII field names are normalised (hyphens to underscores, lower-cased) on both the source
piimap and the authorised-field allowlist before matching, so a released field appears underx_stella_authorised_piiwith its normalised key. - Redaction evidence is carried on every object in
x_stella_minimisation. Theredacted_fieldslist usespii.<field>for suppressed PII fields anddescription.pii.<field>when a PII value was scrubbed out of an authorised description; thedescriptiontoken marks a fully removed free-text description. - Profile invariants enforced by
DoraInfoSharingRedactionProfile: strict mode may not carry any authorisation settings; explicit-authorisation mode requires anauthorisationRefand at least one authorised PII field orallowFreeTextDescription.
Signing
The canonical STIX bundle bytes are wrapped in a DSSE envelope. The signing input is the shared DSSE pre-authentication encoding over the pinned payload type and the canonical payload bytes. Offline verification must:
- Decode the DSSE
payload. - Recompute the DSSE pre-authentication encoding.
- Verify at least one signature against the configured local trust material.
- Recompute the payload SHA-256 and compare it to the delivery ledger entry.
TAXII Manifest
The connector also emits a deterministic TAXII collection manifest:
{
"type": "taxii-collection-manifest",
"taxii_version": "2.1",
"collection_id": "collection-tenant-a-dora",
"title": "DORA Article 45 outbound stream for collection-tenant-a-dora",
"can_read": true,
"can_write": false,
"media_types": ["application/stix+json;version=2.1"],
"latest_batch": {
"bundle_id": "bundle--<deterministic-uuid>",
"payload_sha256": "sha256:<hex>",
"object_count": 3,
"added_after": "2026-04-30T09:00:00.000Z"
},
"x_stella_delivery": {
"purpose": "dora-info-sharing",
"channel_id": "string",
"channel_type": "Custom",
"endpoint": "https://subscriber.example/taxii2/collections/.../objects/",
"tenant_id_hash": "sha256:<hex>",
"subscriber_id_hash": "sha256:<hex>"
}
}
title and the x_stella_delivery extension block are emitted by DoraTaxiiCollectionManifestBuilder. x_stella_delivery.endpoint resolves from the channel config (Endpoint falling back to Target), channel_type is the NotifyChannelType name, and subscriber_id_hash is present only when the export request carries a subscriberId. The TAXII verify path (CLI and library) asserts x_stella_delivery.purpose == "dora-info-sharing".
The v1 library builds the manifest and signed batch. CLI export, verify, and feed-setup commands are implemented (see CLI section below). Live server-side TAXII collection hosting (an inbound TAXII 2.1 HTTP server) is not part of v1; outbound subscriber push delivery is implemented by DoraInfoSharingSubscriberDeliveryService.
Subscriber Delivery (Outbound TAXII Push)
DoraInfoSharingSubscriberDeliveryService performs the live outbound push to a peer/authority TAXII subscriber. It exports the signed batch, re-verifies the DSSE envelope before transmission, and only then POSTs the delivery body.
- The delivery body is a JSON envelope (
schemaVersion: "dora-info-sharing-taxii-delivery-v1") carryingpurpose,taxiiVersion,tenantId,channelId,collectionId, optionalsubscriberIdHash,generatedAt,stixPayloadSha256,dsseEnvelopeSha256,taxiiManifestSha256, and the embeddedtaxiiManifest,stixBatch, anddsseEnvelopedocuments. - The POST uses
Content-Type: application/vnd.stellaops.dora-info-sharing.taxii-delivery.v1+json,Accept: application/taxii+json, and the headersX-StellaOps-DORA-Purpose,X-StellaOps-TAXII-Version,X-StellaOps-Collection-Id,X-StellaOps-STIX-SHA256,X-StellaOps-DSSE-SHA256, andX-StellaOps-Body-SHA256. - Pre-flight failures are recorded without a network call:
signature-verification-failed,missing-subscriber-endpoint, andchannel-disabled. Transport failures surface astransport-failed:<reason>ortransport-timeout:<reason>. - A
DoraInfoSharingSubscriberReceipt(schemaVersion: "dora-info-sharing-subscriber-receipt-v1") is produced for every attempt with statusaccepted(HTTP 2xx),rejected(non-2xx), orfailed(pre-flight/transport error). - When an
IDoraInfoSharingDeliveryLedgeris supplied, aNotifyDeliveryledger entry is recorded carrying metadata keys under thedora.infoSharing.*namespace (e.g.dora.infoSharing.contractVersion,dora.infoSharing.dsse.sha256,dora.infoSharing.stix.sha256,dora.infoSharing.taxii.manifestSha256,dora.infoSharing.endpointHash,dora.infoSharing.receiptId,dora.infoSharing.receiptStatus).
CLI
The connector is driven offline through three stella commands (DoraInfoSharingCommandGroup). All signing uses a local HMAC-SHA256 key supplied via --signing-key-file or the STELLAOPS_DORA_INFO_SHARING_HMAC_KEY environment variable.
stella notify setup-dora-feed— emits a disabled (dora-info-sharing-feed-setup-v1) Notify channel setup document (enabled: false,activation: "operator-review-required"). Required:--tenant,--url,--collection-id,--generated-at.stella export dora-info-sharing— reads adora-info-sharing-cli-input-v1JSON file (--input) and writes the offline handoff directory (--output):stix-batch.json,taxii-manifest.json,stix-batch.dsse.json, and adora-info-sharing.receipt.json(dora-info-sharing-handoff-receipt-v1).stella verify dora-info-sharing— verifies a handoff directory or receipt path: recomputes artifact SHA-256 digests, matches them to the receipt, asserts the TAXII manifest purpose, and verifies the DSSE signature with the local HMAC key. Exit codeVerificationFailedon mismatch.
Deterministic Fixture Location
Adjacent deterministic coverage lives in:
src/Notify/__Tests/StellaOps.Notify.Connectors.DoraInfoSharing.Tests/
The tests assert redaction, canonical payload stability, TAXII manifest output, and DSSE offline verification using frozen inputs.
Replay And Offline Expectations
- Same inputs, same generated timestamp, same redaction profile, and same signer material must produce the same payload hash and envelope hash.
- Tests must run without internet access and without a live TAXII endpoint.
- Delivery ledger entries (recorded by
DoraInfoSharingSubscriberDeliveryServiceviaIDoraInfoSharingDeliveryLedger) store the STIX payload hash, DSSE envelope hash, submission body hash, endpoint hash, receipt id/status, channel id, and collection id under thedora.infoSharing.*metadata namespace. The raw signer key material is never persisted (HMAC keys live only in the local key file orSTELLAOPS_DORA_INFO_SHARING_HMAC_KEY).
