eIDAS Qualified-Provider Pack Ingestion

Audience: operators, compliance owners, and engineers wiring WS8 eIDAS QES validation. Status: production operator-QES ingestion was abandoned for the 2026-06-08 operator-signed-decisions program. Synthetic fixtures are allowed for deterministic tests only; this runbook is the future re-entry path if a real QTSP/provider pack and counsel decision are later supplied.

Decision

Stella Ops may use the existing in-repo synthetic eIDAS fixture pack to prove parser, loader, revocation, and CAdES wiring while the real qualified-provider pack is unavailable.

That fixture is not a QTSP pack, does not create a qualified-service claim, and must not be bundled into production deployments, Offline Kit releases, or provider-pack distributions. Production QES validation remains fail-closed until the operator supplies a real pack through the configured runtime paths and the legal gates in docs/legal/decisions/REG-20260502-eidas-qualified-provider-pack.md are satisfied.

Program closeout note (2026-06-10): the operator-signed governance decisions program abandoned the production eIDAS operator-QES tier instead of waiting indefinitely or fabricating trust material. The reasons are deliberate: no real QTSP/provider pack exists, no vendor-specific counsel decision exists, and the synthetic profile would be a false qualified-service claim if used as production evidence. Re-entry requires a new sprint and the full intake process below.

The synthetic fixture lives under:

src/Cryptography/__Tests/StellaOps.Cryptography.Tests/Eidas/Fixtures/sealed-pack/

The accepted test manifest is:

src/Cryptography/__Tests/StellaOps.Cryptography.Tests/Eidas/Fixtures/sealed-pack/accepted-baseline-t/qtsp-pack/manifest.json

Use it for test evidence such as:

Do not use it for:

Synthetic Fixture Guardrails

The fixture pack is first-party test material. Its packVersion values are test-qtsp-*, its issuer names are test-only, and its manifests point at deterministic test bytes. Any code path using this pack outside tests must keep the output labelled as test evidence and must not mark a release decision as eIDAS-qualified.

The eIDAS plugin intentionally does not register a default production IEidasFixturePack. A deployment has to wire an operator-supplied pack and set the loader configuration. If the loader is not configured, the runtime must continue to emit not-claimed:eidas-pack-not-loaded or throw EidasEvidenceNotProductionReadyException on production-claim algorithms.

Synthetic Signer-Certificate Profile Lane

While the real qualified-provider pack is unavailable, the test lane may create first-party synthetic signer certificates with a QCStatements extension (1.3.6.1.5.5.7.1.3) to prove parser and verifier behavior. These synthetic certificates may carry QcCompliance, QcSSCD/QSCD, QcType, and QcPDS values, and may be chained to a synthetic pinned root with synthetic CRL evidence.

This lane proves:

It does not prove a production eIDAS qualified-provider arrangement. Do not treat synthetic QCStatements, synthetic roots, or synthetic CRLs as Gate 4 pack material, and do not emit claimed-against:<real-pack-version> from this lane.

Real Pack Ingestion

A real eIDAS pack is operator-supplied trust material, not source code. Ingest it only after:

Recommended on-disk layout:

/etc/stella-ops/eidas/
  qtsp-pack/
    manifest.json
    lotl/
    tsl/
    certs/
    ocsp/
    crl/
    policies/
    fixtures/
  transaction-evidence/
    <release-id>/
      sbom.hash
      timestamp-token.tsr
      ocsp-response.der
      crl.pem
      archive-timestamp.tsr
      evidence-manifest.json
  qtsp-agreement.json

Runtime configuration:

Eidas:
  TrustedList:
    OfflineTrustMaterialPackPath: "/etc/stella-ops/eidas/qtsp-pack/manifest.json"
    QtspAgreementPath: "/etc/stella-ops/eidas/qtsp-agreement.json"
    AllowHistoricalPreTlv6Use: false
    IsHistoricalReplay: false
  TransactionEvidence:
    RootPath: "/etc/stella-ops/eidas/transaction-evidence"

Agreement file shape consumed by the current loader:

{
  "authorisedVendor": "qtsp-vendor-name-from-gate-4",
  "agreementEffectiveDate": "2026-06-01T00:00:00Z",
  "agreementExpiryDate": "2027-06-01T00:00:00Z",
  "redistributionMode": "OperatorSupplied"
}

Manifest fields consumed by Loader 1:

{
  "packVersion": "qtsp-vendor-jurisdiction-profile-2026.06",
  "validFromUtc": "2026-06-01T00:00:00Z",
  "validUntilUtc": "2027-06-01T00:00:00Z",
  "trustedListVersion": "TLv6",
  "tlv6Compatible": true,
  "qtspServiceIdentifier": "vendor-service-id",
  "serviceStatusUri": "http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted",
  "serviceTypeUri": "http://uri.etsi.org/TrstSvc/Svctype/TSA/QTST",
  "packSha256": "<sha256-rollup>",
  "files": [
    {
      "role": "lotl-snapshot",
      "path": "lotl/lotl.xml",
      "sha256": "<sha256>"
    },
    {
      "role": "tsl-member-state",
      "path": "tsl/member-state.xml",
      "sha256": "<sha256>"
    },
    {
      "role": "qtsp-cert",
      "path": "certs/qtsp-tsa-leaf.pem",
      "sha256": "<sha256>"
    },
    {
      "role": "ocsp-response",
      "path": "ocsp/tsa-chain.der",
      "sha256": "<sha256>"
    },
    {
      "role": "crl",
      "path": "crl/tsa-chain.crl",
      "sha256": "<sha256>"
    },
    {
      "role": "policy-document",
      "path": "policies/cp-cps.txt",
      "sha256": "<sha256>"
    }
  ]
}

The loader verifies every listed file, then verifies packSha256 as SHA-256 over the canonical sorted list:

<role>\0<sha256-lowercase>\n

sorted by role and then path. Do not place private keys, vendor credentials, customer production evidence, or confidential material in the repository.

Per-Transaction Evidence

RFC 3161 timestamp tokens, OCSP responses, CRL snapshots, and archive timestamps are per-transaction evidence. They belong under Eidas:TransactionEvidence:RootPath, not inside a static production pack, except when a vendor supplies accepted/rejected verdict fixtures for offline conformance tests.

Each release directory must contain evidence-manifest.json with:

{
  "releaseId": "release-2026-06-09-001",
  "messageImprintSha256": "<sha256-of-the-signed-data>",
  "evidenceTimestampUtc": "2026-06-09T12:00:00Z",
  "qtspServiceIdentifier": "vendor-service-id",
  "evidenceDigestBinding": "<sha256(messageImprintSha256_lower + ':' + qtspServiceIdentifier)>"
}

Loader 2 rejects missing evidence, QTSP mismatches, and digest bindings that do not match the actual message imprint.

Replacing The Synthetic Fixture

When the real pack arrives:

  1. Record the vendor, jurisdiction, profile, expiry, delivery channel, and operator obligations in REG-20260502-eidas-qualified-provider-pack.md.
  2. Recompute every file SHA-256 and the manifest roll-up from local bytes.
  3. Place the pack under /etc/stella-ops/eidas/qtsp-pack/, not under src/ or devops/.
  4. Place the agreement JSON at Eidas:TrustedList:QtspAgreementPath.
  5. Place per-release evidence under Eidas:TransactionEvidence:RootPath.
  6. Run the eIDAS loader, claim-state, CAdES, and QES signer-certificate tests against the delivered accepted/rejected verdict pairs.
  7. Only after pack load, per-transaction evidence, and counsel sign-off are complete may the eIDAS-QES enforcement flag be considered for a production decision surface.

Until all seven steps are complete, WS8 remains blocked for production QES and must keep emitting not-claimed:* or typed fail-closed exceptions.