eIDAS QTSP/QSCD Bridge Contract

This contract defines the operator-controlled HTTP bridge used by src/__Libraries/StellaOps.Cryptography.Plugin.EIDAS/ when eIDAS signing is delegated to a qualified trust service provider or QSCD.

Placement

Endpoints

GET /health

Returns bridge readiness without creating signing authority.

Required response fields:

{
  "status": "ready",
  "production": true,
  "provider": "vendor-name",
  "qscd": true,
  "trustedListFixture": "fixture://eidas/tsl/eu-qualified-tsa-2026-04",
  "algorithms": ["ECDSA-P256", "RSA-PSS-2048"]
}

Release evidence requires production=true, qscd=true, and a non-empty trustedListFixture.

GET /api/v1/keys/{keyId}

Returns public key metadata for JWK export and verification setup.

Required response fields:

{
  "keyId": "eu-prod-signing-01",
  "algorithm": "ECDSA-P256",
  "certificatePem": "-----BEGIN CERTIFICATE-----...",
  "certificateChainPem": ["-----BEGIN CERTIFICATE-----..."],
  "qualifiedCertificate": true,
  "qscd": true,
  "trustedListReference": "fixture://eidas/tsl/eu-qualified-ca-2026-04"
}

The active plugin may export a JWK only from configured certificate material. Missing or unverifiable public key material is a configuration failure.

POST /api/v1/sign

Consumes a digest request and returns a detached signature plus evidence metadata.

Required request fields:

{
  "keyId": "eu-prod-signing-01",
  "algorithm": "ECDSA-P256",
  "digestAlgorithm": "SHA256",
  "dataHash": "base64-digest",
  "signatureLevel": "QES",
  "signatureFormat": "CAdES"
}

Required response fields for BaselineB:

{
  "signature": "base64-signature",
  "certificate": "base64-leaf-certificate"
}

Additional required fields for BaselineT:

{
  "timestampToken": "base64-rfc3161-token",
  "trustListReference": "fixture://eidas/tsl/eu-qualified-tsa-2026-04"
}

Additional required fields for BaselineLT:

{
  "ocspResponses": ["base64-ocsp-response"],
  "crls": ["base64-crl"]
}

At least one OCSP response or CRL is required. The response must bind to the signing certificate chain in sealed fixtures.

Additional required field for BaselineLTA:

{
  "archiveTimestamp": "base64-rfc3161-archive-token"
}

Until Stella Ops embeds and validates this evidence locally, requested profiles above BaselineB fail closed with stable error keys.

Offline Sealed Fixture Manifest

LT/LTA tests and air-gapped validation harnesses must use local sealed fixtures only. Configure fixtures inline through Eidas:TrustedList:SealedFixtures or with Eidas:TrustedList:FixtureManifestPath.

Manifest shape:

{
  "fixtures": [
    {
      "reference": "fixture://eidas/tsl/eu-qualified-tsa-2026-04",
      "trusted": true,
      "evidence": [
        {
          "kind": "timestamp",
          "sha256": "lowercase-sha256-of-decoded-rfc3161-token"
        },
        {
          "kind": "ocsp",
          "sha256": "lowercase-sha256-of-decoded-ocsp-response"
        },
        {
          "kind": "crl",
          "sha256": "lowercase-sha256-of-decoded-crl"
        },
        {
          "kind": "archiveTimestamp",
          "sha256": "lowercase-sha256-of-decoded-rfc3161-archive-token"
        }
      ]
    }
  ]
}

Rules:

Offline Sealed Fixture Pack Preflight

Vendor-qualified fixture ingestion uses a stricter pack manifest before any bytes are allowed into LT/LTA validation work. Configure it with Eidas:TrustedList:FixturePackManifestPath. The expected operator path is:

<offline-kit-or-internal-share>/eidas/<pack-id>/eidas-fixture-pack.manifest.json

The manifest must be JSON with this schema version:

{
  "schemaVersion": "stellaops.eidas.fixture-pack.v1",
  "packId": "vendor-qualified-eu-lt-2026-04",
  "jurisdiction": "EU",
  "evidenceProfile": "BaselineLT",
  "trustedListReference": "fixture://eidas/fixture-packs/vendor-qualified-eu-lt-2026-04",
  "expiresAt": "2026-10-31T00:00:00Z",
  "artifacts": [
    {
      "id": "timestamp-token",
      "role": "timestamp-token",
      "path": "timestamp-token.tsr",
      "sha256": "lowercase-sha256-of-file-bytes",
      "notBefore": "2026-04-01T00:00:00Z",
      "expiresAt": "2026-10-31T00:00:00Z"
    }
  ],
  "expectedVerdicts": [
    {
      "id": "accepted-lt",
      "evidenceProfile": "BaselineLT",
      "expectedResult": "accepted",
      "evidenceArtifactIds": ["timestamp-token"]
    },
    {
      "id": "rejected-tampered-token",
      "evidenceProfile": "BaselineLT",
      "expectedResult": "rejected",
      "evidenceArtifactIds": ["timestamp-token"]
    }
  ]
}

Allowed artifact roles are payload, signature, timestamp-token, ocsp-response, crl, archive-timestamp-token, signing-certificate-chain, tsa-certificate-chain, tsl-snapshot, and lotl-snapshot.

Required roles:

Evidence profileRequired fixture roles
BaselineTtimestamp-token, signing-certificate-chain, tsa-certificate-chain, tsl-snapshot, lotl-snapshot
BaselineLTBaselineT roles plus at least one ocsp-response or crl
BaselineLTABaselineLT roles plus archive-timestamp-token

Preflight validation checks the schema version, manifest and artifact expiry, fixture:// trusted-list reference, jurisdiction/profile metadata, lowercase SHA-256 file hashes, path containment inside the fixture pack directory, required roles, and both accepted and rejected expected verdict metadata. It does not parse RFC 3161, OCSP, CRL, certificates, TSL, or LOTL cryptographically.

Passing EidasSealedFixturePackValidator means validationScope=fixture-pack-preflight and productionCryptographicValidation=false. It only proves that the offline pack is complete enough for the next implementation step to run deterministic cryptographic validators.

Provider-Pack Meaning And Intake

For this contract, an eIDAS provider pack means either:

The pack is not a simulator. It must contain the evidence needed to prove the selected CAdES baseline profile without fetching mutable live services:

Intake plan:

  1. Compliance or vendor integration selects the pack owner and records whether the material can be committed, stored in an internal sealed asset store, or supplied only during customer deployment.
  2. Legal/license review records redistribution limits before bytes are copied into any Stella Ops repository, offline kit, or CI asset location.
  3. The pack is copied only into an approved offline location and assigned a stable packId, local path, SHA-256 manifest hash, jurisdiction, profile, and expiry.
  4. EidasSealedFixturePackValidator runs first. Passing preflight is required before implementation work, but it is not a production validation verdict.
  5. Cryptographic validators for RFC 3161, OCSP/CRL, certificate chains, archive timestamp, and TSL/LOTL trust path are implemented against the sealed pack.
  6. CAdES-T/LT/LTA embedding is enabled only after produced signatures verify offline against the same sealed pack.

Live LOTL/TSL fetches are not acceptable release evidence because the result is not deterministic, cannot be replayed in an air-gapped install, may change between release and audit, and bypasses the legal/license review that governs trust-list redistribution. The universal crypto simulator is also not acceptable because it cannot prove qualified certificate status, QSCD use, TSA trust, revocation status, archive timestamp validity, or EU trust-list lineage.

Selecting A QTSP/QSCD Provider

For Stella Ops, a QTSP/QSCD provider is not just a vendor name. It is the qualified trust-service provider, qualified service type, signing/sealing device boundary, API/bridge contract, and sealed evidence pack that together allow Stella Ops to claim a specific eIDAS evidence profile.

Selection checklist:

  1. Confirm the provider is listed as qualified for the needed service in the EU Trusted List Browser or the relevant national trusted list.
  2. Confirm the service type matches the product claim: qualified certificate for electronic signature or seal, qualified timestamp, qualified validation, or preservation/archive service as applicable.
  3. Confirm QSCD coverage for the signing or sealing key. For remote signing, require evidence that the QTSP manages the remote qualified signature/seal creation device under the applicable eIDAS remote-QSCD rules.
  4. Confirm the provider can supply the CAdES evidence needed by the requested profile: BaselineB certificate chain, BaselineT timestamp token, BaselineLT OCSP/CRL evidence, and BaselineLTA archive timestamp.
  5. Confirm the provider or integrator can expose a deterministic bridge that matches this contract and can run without live network fetches during Stella Ops release validation.
  6. Confirm legal/license terms for storing or redistributing the sealed evidence pack, including TSL/LOTL snapshots, certificate chains, OCSP/CRL material, timestamp tokens, archive timestamps, expected verdict fixtures, and audit reports.
  7. Confirm operational fit: jurisdiction, SLA, support for test and production tenants, key ceremony, incident support, revocation handling, expiry rotation, and customer deployment model.
  8. Record the chosen provider pack in the release evidence pack with packId, source, local immutable path, manifest SHA-256, expiry, evidence profile, and legal/license disposition.

Minimum recommendation: pick the smallest provider scope that satisfies the claim. If Stella Ops only needs local detached CMS/CAdES-B harness tests, a configured certificate private key can support test evidence but not QES/QSCD claims. If Stella Ops needs BaselineT/LT/LTA or QES/seal claims, select a QTSP/QSCD-backed pack and keep the feature blocked until the pack passes offline preflight and cryptographic validation.

Authoritative selection sources:

Release Evidence Eligibility

Evidence profileCurrent active-provider status
BaselineBLocal harness-capable when backed by configured PKCS#12/PFX certificate private-key material; production QES eligibility still requires qualified certificate/QSCD or production QTSP/QSCD bridge evidence.
BaselineTProvider-pack required. Timestamp evidence is fixture-gated and then fails closed at the embedding boundary unless a selected QTSP/QSCD/TSA pack supplies real embedding and validation.
BaselineLTProvider-pack required. Timestamp and OCSP/CRL evidence are fixture-gated and then fail closed at the embedding boundary unless a selected pack supplies revocation embedding and validation.
BaselineLTAProvider-pack required. Timestamp, OCSP/CRL, and archive timestamp evidence are fixture-gated and then fail closed at the embedding boundary unless a selected pack supplies archive evidence embedding and validation.

The Signer local CAdES companion provider may produce detached CMS/CAdES-B-like bytes with configured PKCS#12/PFX certificate private-key material for offline harness verification. This proves local CMS signature validity against bundled certificate material only. It is not QES/QSCD evidence, does not validate qualified status, and does not embed trusted-list, timestamp, revocation, or archive evidence. CAdES-T, CAdES-LT, CAdES-LTA, and upgrade operations are explicitly unavailable in the default provider unless deployment/provider packs supply vendor-qualified RFC 3161 timestamp tokens, OCSP/CRL evidence, archive timestamp tokens, signing/TSA certificate chains, and sealed TSL/LOTL snapshots. The builder must fail closed rather than adding empty or shape-only unsigned attributes.

Signer Cadenced DSSE Companion Boundary

The Signer cadenced wrapper used by CRA technical-file and conformity-dossier exports signs an outer DSSE envelope over the normal inner DSSE envelope and a deterministic cadesCompanion status object. The default Signer runtime does not fabricate CMS/CAdES bytes from DSSE signatures or crypto-registry JWK metadata. For local offline harnesses, BaselineB may emit detached CMS bytes when Signer:Dsse:CadesBaselineBPfxPath points at configured PKCS#12/PFX certificate private-key material; the response includes the CMS bytes, CMS SHA-256 digest, provider name, and PEM certificate chain. Without that material, or for profiles above BaselineB, a requested CAdES companion records blocked with cadenced.cades.provider_pack_required until a deployment/provider pack exposes a Signer-facing CAdES companion provider backed by qualified certificate private-key material or a production QTSP/QSCD bridge result.

For BaselineT, BaselineLT, and BaselineLTA, the provider pack must also embed and locally validate the timestamp, revocation, archive timestamp, signing and TSA certificate chains, and sealed TSL/LOTL fixtures described above. Passing fixture-pack preflight alone is not enough to make the cadenced CAdES companion release-evidence eligible. The provider-pack implementation remains tracked by docs/implplan/SPRINT_20260427_018_Cryptography_eidas_production_evidence.md.

POST /api/v1/verify

Verifies a detached signature. The response must separate cryptographic signature validity from evidence completeness.

Required request fields:

{
  "keyId": "eu-prod-signing-01",
  "algorithm": "ECDSA-P256",
  "digestAlgorithm": "SHA256",
  "dataHash": "base64-digest",
  "signature": "base64-signature"
}

Required response fields:

{
  "valid": true,
  "evidenceComplete": true,
  "evidenceProfile": "BaselineLT",
  "trustedListReference": "fixture://eidas/tsl/eu-qualified-tsa-2026-04",
  "error": null
}

valid=true alone is not enough for LT/LTA release evidence.

Fail-Closed Rules