Export Center Profiles

Currency check 2026-10-07: owner paths/source placement verified against 3238bd511a37e199ae99d4f17be2f13eabec8dd7. The supported boundary is /api/evidence/v1/evidence/capsules/tlpt-packs (src/Evidence/StellaOps.Evidence.WebService/Program.cs). Re-verify the host mount and owning endpoint extension together. This is source verification; deployment and broader audit coverage are separate evidence. Other dated findings retain their stated dates. Re-verify: rg -n "MapGroup|Map.*Endpoints|AddHostedService" src/Evidence/StellaOps.Evidence.WebService/Program.cs, then inspect the endpoint extension or library pointer cited at the operation.

Status: routes and paths re-checked against commit 942a18727c (2026-09-26); the export plane is served by offlinekit-web under /api/offlinekit/v1/**. The profile catalogue, field tables and JSON examples below were not re-verified; the request model the API accepts is CreateExportProfileRequest in src/OfflineKit/__Libraries/StellaOps.ExportCenter.Application/Api/ExportApiModels.cs (name, description, kind = ExportProfileKind AdHoc/Scheduled/EventDriven/Continuous/Mirror, scope, format = ExportFormatOptions, signing, schedule), which differs from the design-era shape in Common configuration fields.

Export Center profiles define what data is collected, how it is encoded, and which distribution paths are enabled for a run. Profiles are tenant-scoped and deterministic: identical selectors and source data produce identical bundles. This guide summarises built-in profiles, configuration fields, schema conventions, and compatibility notes.

Profile catalogue

ProfileKind / VariantOutput artefactsPrimary use cases
json:rawjson / rawCanonical JSONL archives of advisories, VEX, SBOMsEvidence escrow, analytics pipelines
json:policyjson / policyjson:raw artefacts plus policy snapshot + evaluated findingsAudit, compliance attestations
trivy:db—RETIRED 2026-08-09 — see Trivy profiles (retired)—
trivy:java-db—RETIRED 2026-08-09 — see Trivy profiles (retired)—
mirror:fullmirror / fullComplete mirror bundle (raw, policy, indexes, provenance)Air-gap deployments, disaster recovery
mirror:deltamirror / deltaIncremental changes relative to a prior manifestEfficient mirror updates
cra:tech-filecra / tech-fileCRA Annex VII technical-file bundleManufacturer technical documentation
cra:conformity-dossiercra / conformity-dossierCRA conformity-assessment dossier with Module A, B+C, or H overlaysSelf-assessment, notified-body, or full-QMS evidence packs
standards:mappingstandards / mappingSigned standards-mapping bundle for a selected local target mappingNIS2/CRA evidence crosswalks, procurement, auditor handoff
nis2:statement-of-applicabilitynis2 / statement-of-applicabilityProduction signed NIS2 SoA bundle from Policy and Authority inputsNIS2 Article 21 SoA handoff and audit evidence
nis2:effectiveness-reportnis2 / effectiveness-reportSigned monthly NIS2 13-area effectiveness JSON bundleMonthly NIS2 Article 21 effectiveness review and auditor handoff

Profiles can be cloned and customised; configuration is immutable per revision to keep runs reproducible.

Provisioning & CRUD model

The lists below name each route’s policy. Ordinary export and Assurance groups also apply export.viewer to every route; mutations add export.operator or export.admin as shown. Inherited, route-specific and configured resource-server default scope requirements apply together; a mutation policy does not replace Viewer.

There are two distinct profile classes, and they are provisioned differently. Conflating them is the source of the “export profiles have no CRUD” confusion — one class is fully CRUD-able, the other is intentionally read-only.

  1. Tenant export profiles (ExportProfile entity) — full tenant CRUD, backed by Postgres and audited. These are the profiles operators create/clone/customise:

    • GET /api/offlinekit/v1/exports/profiles (scope ExportViewer) — list
    • GET /api/offlinekit/v1/exports/profiles/{profileId} (ExportViewer) — read one
    • POST /api/offlinekit/v1/exports/profiles (ExportOperator, audited create_profile) — create
    • PUT /api/offlinekit/v1/exports/profiles/{profileId} (ExportOperator, audited update_profile) — update
    • DELETE /api/offlinekit/v1/exports/profiles/{profileId} (ExportAdmin, audited delete_profile) — archive (soft-delete)
    • POST /api/offlinekit/v1/exports/profiles/{profileId}/runs (ExportOperator) — start a run

    The console currently wires only the read side (listProfiles); create/update/archive are available on the API and are the intended console follow-up. This is an FE-wiring gap, not a missing backend.

  2. Assurance / compliance export profiles (NIS2 / DORA / CRA — the AssuranceExportProfileRegistry) are provisioned via offlinekit-web configuration (AssuranceExportOptions, Nis2SoaExportOptions; sections Export:Assurance and Export:Nis2Soa) and are read-only by design. They are discovery/readiness descriptors bound to signed adapters/routes; there is deliberately no create/update/delete surface. Change them by editing the offlinekit-web configuration and redeploying (see the Assurance export profile catalogue and OfflineKit architecture §7). Their read surface is /api/offlinekit/v1/exports/assurance/profiles.

Assurance export profile catalogue

The Assurance HTTP catalogue was verified against c5cc6723ce (PCD-281, 2026-10-04). Recheck all seven entries’ methods and templates with pwsh -NoProfile -File tools/scripts/test-targeted-xunit.ps1 -Project src/OfflineKit/__Tests/StellaOps.OfflineKit.WebService.Tests/StellaOps.OfflineKit.WebService.Tests.csproj -Class "*ExportSurfacingClientRouteTableTests" -BuildProjectReferences -Restore.

The generic Assurance registry uses dot-form profile ids and is exposed at /api/offlinekit/v1/exports/assurance/profiles. These descriptors are discovery/readiness records; execution uses the named typed export endpoints or registered CLI commands. The compatibilityRoutes JSON field lists these current entry points. Its HTTP entries include their method and complete /api/offlinekit/v1/exports path.

Assurance profile idFrameworkPackExport typeAdapter idSchema idRoutes and commands
cra.conformity-dossiercracra.technical-documentationconformity-dossiercra:conformity-dossierconformity-dossier-v1stella export conformity-dossier
cra.technical-filecracra.technical-documentationtechnical-filecra:tech-filecra-tech-file-v1stella export cra-tech-file
dora.roidoradoraregister-of-informationexportcenter.dora.roidora-roi-v1stella export dora-roi, stella verify dora-roi
nis2.effectiveness-reportnis2nis2effectiveness-reportexportcenter.nis2.effectiveness-reportnis2-effectiveness-report-v1stella export nis2-effectiveness, POST /api/offlinekit/v1/exports/assurance/profiles/nis2.effectiveness-report/runs, GET /api/offlinekit/v1/exports/assurance/profiles/nis2.effectiveness-report/runs/{runId}, GET /api/offlinekit/v1/exports/assurance/runs/{runId}/bundle
nis2.statement-of-applicabilitynis2nis2statement-of-applicabilityexportcenter.nis2.soanis2-soa-v1GET /api/offlinekit/v1/exports/nis2/soa/profile, POST /api/offlinekit/v1/exports/nis2/soa/runs, GET /api/offlinekit/v1/exports/nis2/soa/runs/{runId}, GET /api/offlinekit/v1/exports/nis2/soa/runs/{runId}/bundle

Every built-in Assurance profile sets signingRequired=true and supportsOfflineVerification=true. Readiness fails closed and reports stable reason codes without exposing secret/config values.

DORA route-owned profile targets

DORA RoI is a built-in fail-closed Assurance readiness descriptor and an HTTP-expressible source-supplied produce path. Web/CLI can render stable blocked readiness reasons instead of probing a missing route; when a request supplies a complete dora-roi.v1 register and ownerApprovalRef, ExportCenter materializes the signed RoI ZIP, validates the vendored EBA taxonomy package, and signs with operator-owned Export:Assurance:DoraRoi key material. The descriptor does not fetch workflow data, does not claim regulator submission, and never accepts signing key material from the request body. The ZIP wrapper uses the same DoraRoiBundleAssembler manifest/signature shape as stella export dora-roi --offline, so deterministic HMAC HTTP output can byte-match the CLI; HTTP-only approval/source refs remain request/readiness metadata instead of artifact fields. In deployed images, Export:Assurance:DoraRoi:TaxonomyPackagePath may point at a mounted read-only copy of the pinned EBA outer ZIP; readiness uses that same configured path before clearing dora-roi-schema-mapping-missing.

Other DORA handoff routes remain documented target profiles so Web/CLI can use stable ids. TLPT is HTTP-expressible only by delegating to EvidenceLocker. Major incident and information sharing are HTTP-expressible when the request supplies the Notify-owned source payloads and JSON-friendly Notify channel DTOs; ExportCenter maps those DTOs into the existing Notify contracts and does not invent workflow state.

Assurance profile idFrameworkPackExport typeSource ownerSchema idRoutes and commands
dora.info-sharingdoradorainfo-sharingNotifydora-info-sharing-event-v1stella export dora-info-sharing, stella verify dora-info-sharing
dora.major-incident-reportdoradoramajor-incident-reportNotifydora-major-incident-report-v1stella export dora-incident-report, stella verify dora-incident-report
dora.tlpt-evidence-packdoradoratlpt-evidence-packTLPT Scoper/EvidenceLockertlpt-evidence-pack.v1stella tlpt pack, stella verify tlpt-pack

dora.major-incident-report HTTP produce accepts { "doraMajorIncidentReport": { "report": <DoraMajorIncidentReportInput>, "channel": <AssuranceProduceNotifyChannelInput>, "producedAt": "..." } }, uses the Notify DORA major-incident encoder/outbound handoff, and signs with operator-owned Export:Assurance:DoraMajorIncidentReport HMAC material. Its wrapper media type is application/vnd.stellaops.dora-major-incident-report.http-bundle.v1+json.

dora.info-sharing HTTP produce accepts { "doraInfoSharing": { "request": <AssuranceProduceDoraInfoSharingExportRequest>, "subscriberApprovalRef": "..." } }, maps the request DTO into Notify DoraInfoSharingExportRequest, emits the Notify STIX/TAXII/DSSE artifacts, and signs with operator-owned Export:Assurance:DoraInfoSharing HMAC material. Its wrapper media type is application/vnd.stellaops.dora-info-sharing.http-bundle.v1+json.

dora.tlpt-evidence-pack HTTP produce accepts { "tlptEvidencePack": <CreateTlptEvidencePackRequest> } and delegates to EvidenceLocker POST /api/evidence/v1/evidence/capsules/tlpt-packs. ExportCenter persists the sealed EvidenceLocker response JSON as the Assurance run artifact; it does not assemble, sign, or mutate TLPT evidence locally. The delegated call still requires EvidenceLocker authorization/tenant context in deployed environments.

Common configuration fields

FieldDescriptionApplies toNotes
nameHuman-readable identifier displayed in Console/CLIAllUnique per tenant.
kindLogical family (json, mirror)AllDetermines eligible adapters. The trivy family was retired 2026-08-09.
variantSpecific export flavour (see table above)AllControls adapter behaviour.
includeRecord types to include (advisories, vex, sboms, findings)JSON, mirrorDefaults depend on variant.
policySnapshotModerequired, optional, or noneJSON policy, mirrorrequired forces a policy snapshot id when creating runs.
distributionEnabled distribution drivers (http, oci, object)AllOffline installs typically disable oci.
compressionCompression settings (zstd, level)JSON, mirror—
encryptionMirror encryption options (enabled, recipientKeys, strict)MirrorWhen enabled, only /data subtree is encrypted; manifests remain plaintext.
retentionRetention policy (days or never)AllDrives pruning jobs for staged bundles.

Selectors (time windows, tenants, products, SBOM subjects, ecosystems) are supplied per run, not stored in the profile.

JSON profiles

json:raw

{
  "profile": { "kind": "json", "variant": "raw" },
  "outputs": [
    { "type": "advisories.jsonl.zst", "sha256": "...", "count": 15234 },
    { "type": "vex.jsonl.zst", "sha256": "...", "count": 3045 },
    { "type": "sboms.jsonl.zst", "sha256": "...", "count": 872 }
  ],
  "selectors": { "tenant": "acme", "products": ["registry.example/app"] }
}

json:policy

Trivy profiles (retired)

⛔ RETIRED 2026-08-09 — owner ruling: Stella Ops does not support trivy-db. The trivy:db and trivy:java-db profiles, the TrivyDbAdapter / TrivyJavaDbAdapter, and the signed stellaops.exportcenter.trivy-db / …trivy-java-db bundles are severed; their sources moved to src/__Obsoleted/. No adapter declares either format in its SupportedFormats any more, so nothing can produce them. (Do not describe this as failing closed at adapter resolution — verified 2026-08-14, GetAdapterForFormat has no production call site, only test ones.) The ExportFormat.TrivyDb/TrivyJavaDb enum members are retained only so historical persisted plans deserialize.

Replacement: our own digest-attested compact offline vulnerability database — stella vuln-db export --from-hub <url>.

The historical adapter design is kept as a ⛔ FROZEN record in docs-archive/modules/export-center/trivy-adapter.md. Do not re-add these profiles.

Mirror profiles

mirror:full

mirror:delta

CRA profiles

cra:tech-file

cra:conformity-dossier

Standards profiles

standards:mapping

NIS2 profiles

nis2:statement-of-applicability

nis2:effectiveness-report

Compatibility and guardrails

Example profile definition (CLI)

{
  "name": "daily-json-raw",
  "kind": "json",
  "variant": "raw",
  "include": ["advisories", "vex", "sboms"],
  "distribution": ["http", "object"],
  "compression": { "codec": "zstd", "level": 9 },
  "retention": { "mode": "days", "value": 14 }
}

Create through the API: POST /api/offlinekit/v1/exports/profiles (inherited export.viewer plus route export.operator). The CLI has no profile-create verb at this commit (stella export profiles offers list and show).

Verification workflow

Extending profiles

Imposed rule: Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.