Transparency (DOCS-ATTEST-74-002)

Last updated: 2026-07-17

Purpose

StellaOps uses transparency logs (Sigstore Rekor v2 or equivalent) to provide tamper-evident, timestamped anchoring for DSSE bundles.

This document freezes the offline verification inputs used by Attestor in sealed/air-gapped operation and points to the canonical schema for rekor-receipt.json.

Local Transparency Primary (Air-Gap Default)

Attestor now treats a Stella-owned local transparency log as the default primary anchor:

The local log is intentionally self-contained. It does not require public Sigstore, GCP, Tessera, or any internet service to sign, anchor, verify, or replay Stella Ops evidence inside an air-gapped deployment.

Submission remains behind the Attestor attestor:* authorization policies. Those policies accept either a real Stella Ops bearer token with the matching scope or a request from a configured service-to-service bypass network. Local compose uses the bypass path for trusted in-network services such as Findings Ledger; public callers still receive the normal authorization challenge.

Existing rekorLogIndex and rekorEntryId fields remain as compatibility fields for Console/API callers. When the primary log URL is stellaops://attestor/local-transparency, those fields identify the local transparency entry rather than a public Rekor entry.

External Rekor or equivalent log publication is an optional sync concern. In sealed mode operators keep the local log authoritative; when internet access is available, Attestor can mirror local entries to an operator-approved external log and record the external receipt alongside the local receipt. That sync path must be non-GCP-bound by default and must not weaken local verification if the external endpoint is unavailable.

External Mirror Postures

External transparency mirroring is additive. It never replaces the Stella local receipt and it never makes public Rekor, private Rekor, Tessera, GCP, or any internet endpoint a prerequisite for local signing, anchoring, replay, or verification.

Attestor supports three operator postures:

PostureNetwork shapeOperator filesResult
Sealed modeNo external network path.None.Local receipts are authoritative; mirror status remains local_only.
Connected-window syncOperator opens a bounded network path from Attestor to an approved external log.Optional run report.Attestor mirrors selected local entries and stores per-target mirror receipts.
Manual exchangeSealed site never opens direct egress. A connected relay handles external publication.Schedule file out, import file back.Sealed site validates and imports mirror receipts after removable-media transfer.

Operator-facing terms:

Mirror status is tracked per target. local_only, mirror_pending, mirror_failed, and mirrored are reporting states only; they do not alter the validity of the local receipt.

External Mirror Persistence

External mirror state is stored separately from the local transparency log:

ITransparencyMirrorRepository owns this persistence boundary. It may read attestor.local_transparency_entries to enumerate pending local entries, but it must not mutate local receipt rows. A restored sealed deployment can therefore verify local receipts even when external mirror state is absent, failed, or waiting for a future import file.

IExternalTransparencyMirrorClient owns target submission and receipt validation. The Rekor-compatible adapter reconstructs the DSSE submission from the local entry descriptor, submits it to the configured target, and verifies the returned inclusion proof against the local bundle SHA-256 before producing a mirrored receipt record. Digest mismatches, missing proof/checkpoint material, authentication failures, disabled targets, and unavailable endpoints return mirror_failed retry metadata without attaching external UUID/proof fields.

Operator Control APIs

Operators manage external mirror targets through Attestor instead of editing PostgreSQL rows directly:

requiredCryptoProfileId records the regional crypto expectation for schedules, imports, and connected-run reporting. The actual installation certificate and private-key operations still come from Authority/Platform trust state and the configured crypto provider; Attestor does not mint or store those keys.

Connected-Window Sync

Connected-window sync is for environments where operators can temporarily open a controlled egress path to an approved external transparency service.

Required controls:

Runtime contract:

Compose sealed defaults:

ATTESTOR_ATTESTOR__TRANSPARENCY__EXTERNALSYNC__ENABLED: "${ATTESTOR_EXTERNAL_TRANSPARENCY_SYNC_ENABLED:-false}"
ATTESTOR_ATTESTOR__TRANSPARENCY__EXTERNALSYNC__WORKERENABLED: "${ATTESTOR_EXTERNAL_TRANSPARENCY_WORKER_ENABLED:-false}"
ATTESTOR_ATTESTOR__TRANSPARENCY__EXTERNALSYNC__TENANTID: "${ATTESTOR_EXTERNAL_TRANSPARENCY_TENANT_ID:-default}"
ATTESTOR_ATTESTOR__TRANSPARENCY__EXTERNALSYNC__DEFAULTMAXENTRIES: "${ATTESTOR_EXTERNAL_TRANSPARENCY_MAX_ENTRIES:-100}"
ATTESTOR_ATTESTOR__TRANSPARENCY__EXTERNALSYNC__MAXENTRIESHARDLIMIT: "${ATTESTOR_EXTERNAL_TRANSPARENCY_MAX_ENTRIES_HARD_LIMIT:-1000}"
ATTESTOR_ATTESTOR__TRANSPARENCY__EXTERNALSYNC__MAXRUNTIMESECONDS: "${ATTESTOR_EXTERNAL_TRANSPARENCY_MAX_RUNTIME_SECONDS:-300}"
ATTESTOR_ATTESTOR__TRANSPARENCY__EXTERNALSYNC__INTERVALSECONDS: "${ATTESTOR_EXTERNAL_TRANSPARENCY_INTERVAL_SECONDS:-3600}"
ATTESTOR_ATTESTOR__TRANSPARENCY__EXTERNALSYNC__STOPONFIRSTHARDERROR: "${ATTESTOR_EXTERNAL_TRANSPARENCY_STOP_ON_HARD_ERROR:-true}"

No compose default points at public Rekor, GCP, Tessera, or any internet service. Operators configure targets in Attestor persistence and may point them at a local Rekor-compatible relay, a regional transparency service, or another approved mirror adapter.

Manual Schedule/Import Exchange

Manual exchange is for sealed deployments that use removable media or a controlled transfer station instead of a live sync window. It must follow the same validate/import discipline used by vulnerability database air-gap refreshes:

  1. The sealed site creates a deterministic schedule file for selected local transparency entries.
  2. The schedule file is signed with the installation certificate identity preserved by Authority/Platform trust administration. The private key never appears in the file.
  3. The connected relay validates the schedule file, submits entries to the approved external target, and creates a deterministic import file.
  4. The sealed site validates the import file before applying it. Unknown local UUIDs, digest mismatches, tampered manifests, untrusted certificates, expired or revoked certificates, and regional-crypto profile mismatches fail closed.

Schedule and import files carry public certificate metadata only:

The signing algorithm must match the installation’s active regional crypto profile (world, fips, eidas, gost, sm, kcmvp, or a future approved profile). Attestor must resolve that binding through the Authority/Platform trust state and the crypto-provider registry; it must not mint its own exchange certificate or silently fall back to another algorithm.

Runtime contract:

Verification and query APIs expose mirror state additively:

Offline Inputs (Air-Gap / Sealed Mode)

Baseline directory layout is defined in docs/product/advisories/14-Dec-2025 - Offline and Air-Gap Technical Reference.md:

/evidence/
  keys/
    tlog-root/             # pinned transparency log public key(s)
  tlog/
    checkpoint.sig         # signed tree head / checkpoint (note format)
    rekor-tile-snapshot.json # optional full local tile snapshot for root consistency
    rekor-sparse-proof.json  # optional bounded sparse proof for large logs
    entries/               # *.jsonl entry pack (leaves + proofs)

Rekor Receipt (rekor-receipt.json)

The offline kit (or any offline DSSE evidence pack) may include a Rekor receipt alongside a DSSE statement.

Fields:

Checkpoint (checkpoint.sig)

/evidence/tlog/checkpoint.sig is the pinned signed tree head used for offline verification.

Contract:

Entry Pack (entries/*.jsonl)

/evidence/tlog/entries/*.jsonl is an optional-but-recommended offline mirror snapshot for bulk audit/replay.

Contract:

Tile Snapshot (rekor-tile-snapshot.json)

Attestor Core can verify a strict local tile/root consistency snapshot when an offline kit includes full tile hash material.

Required fields:

Verification rules:

The contract is intentionally fail-closed. Missing snapshot material, unsupported schemaVersion, non-contiguous levels/tiles, malformed hashes, root mismatch, checkpoint mismatch, leaf mismatch, or receipt-path mismatch returns an invalid tile consistency result. A Rekor UUID, log index, signed-note-shaped checkpoint, or receipt inclusion path alone does not produce tile/root consistency success.

Sparse Tile Proof (rekor-sparse-proof.json)

Attestor Core can verify a bounded sparse proof when an offline kit covers a large Rekor tree and cannot ship every local tile hash.

Required fields:

Verification rules:

The contract is intentionally bounded and fail-closed. It proves one receipt path against a signed checkpoint using locally supplied nodes; it does not claim that a complete tile mirror is present. Metadata-only sparse material, UUID/log-index-only material, checkpoint text without proof nodes, malformed hashes, coordinate mismatches, root mismatch, leaf mismatch, or receipt/proof divergence returns an invalid sparse proof result.

Offline Verification Rules (High Level)

  1. Load the pinned Rekor log public key from /evidence/keys/tlog-root/ (rotation is handled by shipping a new key file alongside the updated checkpoint snapshot).
  2. Verify the checkpoint signature (when configured) and extract tree size + root hash.
  3. For each rekor-receipt.json, verify:
    • inclusion proof path resolves to rootHash for the given leaf hash,
    • receipt checkpoint root matches the pinned checkpoint root (same tree head).
  4. Optionally, validate that each receipt’s UUID/digest appears in the entry pack and that the recomputed Merkle root matches the pinned checkpoint.
  5. When rekor-tile-snapshot.json is present and the caller requires tile/root consistency, validate the full local tile snapshot with RekorTileRootConsistencyVerifier. Do not downgrade missing or malformed tile material into success; report tile consistency as unavailable/invalid while preserving the existing signed-checkpoint inclusion result.
  6. When rekor-sparse-proof.json is present for a large tree, validate the bounded sparse proof with RekorSparseTileProofVerifier. Do not treat sparse metadata as proof unless the local nodes match the receipt path and signed checkpoint.

Configured Local Bundle Verification (2026-04-29)

Attestor Core exposes RekorLocalTransparencyBundleVerifier for services and offline tooling that need one configured local/offline proof-material path instead of separate receipt, checkpoint, key, tile, and sparse-proof arguments.

Input contract:

Default local resolution order:

Verification behavior:

The verifier remains local/offline only. It does not fetch live Rekor checkpoints, tiles, entries, keys, or issuer metadata.

Fixture Contract (2026-04-28)

Positive offline transparency fixtures must contain all of the following material:

Fixtures that only contain a Rekor UUID, log index, certificate text, JWS header, Fulcio issuer string, or unsigned checkpoint are negative/unavailable fixtures. They may be used to test diagnostics, but they must not produce Verified, valid, or equivalent transparency success.

Tile/root consistency positive fixtures must additionally contain rekor-tile-snapshot.json with complete level 0..root hash material. Fixtures without this file may still verify signed checkpoint inclusion, but they must not claim tile consistency.

Sparse proof positive fixtures must contain rekor-sparse-proof.json with the payload leaf hash and ordered proof nodes for the receipt path. Sparse fixtures without proofNodes, with only UUID/log index/checkpoint metadata, or with nodes that do not match the receipt hashes are negative/unavailable fixtures.

Scanner Consumer Contract (2026-04-28)

Scanner consumes Attestor Core’s offline Rekor receipt verifier through a narrow local adapter for signed SBOM archives and offline-kit imports. The adapter normalizes archive/snapshot material into the Attestor receipt contract and verifies:

Scanner does not use online Rekor for this path and does not treat UUIDs, log indexes, JWS headers, unsigned checkpoints, or Fulcio issuer strings as proof. The local bundle must include the Rekor public key, signed checkpoint, inclusion proof, and DSSE envelope bytes being verified.

Local JWS/Fulcio Verification Contract (2026-04-28)

VexLens can now verify the narrow offline JWS slice used by signed VEX inputs when all local proof material is present:

The verifier remains fail-closed for missing local roots, missing x5c, malformed certificate material, unsupported critical JWS headers, unsupported algorithms, missing/untrusted Fulcio issuer extensions, CA/non-signing leaf certificates, tampered signatures, and revocation checks that would require online lookup. JWS kid, issuer strings, Fulcio OIDC extension text, and certificate presence are diagnostic metadata only until signature verification, local chain validation, leaf-certificate checks, and issuer-policy checks succeed.

Local JWKS/kid JWS Verification Contract (2026-04-28)

VexLens can also verify compact JWS inputs without x5c when the offline kit provides local JWKS material through VexLens:Trust:SignatureTrustRootPaths or request-level TrustRootPaths.

Required local proof material:

The verifier remains fail-closed for missing kid, absent local JWKS material, unknown kid, unsupported or incompatible JWK key material, alg mismatches between the protected header and selected key, key fingerprints outside the configured trusted set, unsupported critical JWS headers, unsupported algorithms, and tampered signatures. A kid, JWKS file, or algorithm name alone is not proof; success requires local key resolution plus cryptographic signature verification.

Local Detached JWS Payload Binding Contract (2026-04-28)

VexLens supports the compact detached JWS shape used by offline signed VEX inputs when the caller supplies both pieces explicitly:

Rules:

Local JWS Revocation Bundle Contract (2026-04-28)

When a VexLens caller sets SignatureVerificationOptions.CheckRevocation=true, compact JWS verification now requires a local revocation bundle in the configured trust-root paths. The verifier searches only local files named revocations.json, revocation-bundle.json, or *.revocations.json; it does not fetch OCSP, CRL, Fulcio, Rekor, or issuer metadata over the network.

Bundle schema:

{
  "schemaVersion": "stellaops.vexlens.revocation.v1",
  "generatedAt": "2026-04-28T00:00:00Z",
  "revokedCertificates": [
    {
      "certificateSha256": "<sha256 of DER certificate bytes>",
      "certificateThumbprintSha1": "<optional compatibility thumbprint>",
      "issuer": "<optional issuer DN>",
      "serialNumber": "<optional serial>",
      "revokedAt": "2026-04-28T00:00:00Z",
      "reason": "keyCompromise"
    }
  ],
  "revokedKeys": [
    {
      "keySha256": "<sha256 of SubjectPublicKeyInfo>",
      "reason": "keyRetired"
    }
  ]
}

Rules:

Scanner Signed-SBOM Revocation Bundle Contract (2026-04-28)

Scanner signed-SBOM archives reuse the same local revocation bundle schema for Fulcio leaf certificate revocation checks. Callers that request revocation checking must supply the bundle locally with the signed-SBOM material; Scanner does not fetch OCSP, CRL, Fulcio, Rekor, or issuer metadata.

Rules:

Scanner signed-SBOM archives now validate local Fulcio chains before packaging keyless material, can enforce local revocation bundles when requested, enforce strict local full-snapshot Rekor tile/root consistency when CheckRekorTileConsistency=true or when rekor-tile-snapshot.json material is supplied, and enforce bounded sparse proof consistency when CheckRekorSparseConsistency=true or when rekor-sparse-proof.json material is supplied. Scanner producer handoff treats includeRekorProof=false as a request to omit proof files from the emitted archive only; any supplied Rekor/tile/sparse material or consistency flag still forces local verification before storage. The cross-module fixture in src/VexLens/__Tests/StellaOps.VexLens.Tests/Verification/CrossModuleTransparencyFixtureTests.cs combines Scanner-shaped DSSE/Fulcio/Rekor material with VexLens compact JWS/JWKS/revocation material and verifies the two proof shapes are not accepted interchangeably. Still unsupported in these slices: online Fulcio discovery, online Rekor tile fetching/consistency proofs, and persisted arbitrary tile-source lookup.