In the previous article, we saw how tpm-ca-certificates manages the generation and distribution of TPM bundles. Since the bundle is a “root of trust,” it’s crucial to guarantee its integrity and provenance. Thus, anyone in possession of the file can verify that it hasn’t been tampered with and that it comes from the official repository.

To achieve this, tpm-ca-certificates uses the benefits provided by transparency logs.

What are transparency logs?

Transparency logs are a powerful tool that stores events in a precise, immutable, and verifiable manner.

Note: image generated by ChatGPT

Several implementations exist, each adapted to specific needs:

  • CT (Certificate Transparency)
  • Rekor (Sigstore Transparency Log)
  • Go (Go Checksum Database)
  • etc.

Transparency logs are tamper-evident logs which means that we can use them to cryptographically prove that the data hasn’t been unexpectedly changed since its creation.

This is exactly what we need to guarantee each bundle’s integrity.

However, it’s also crucial to guarantee their provenance. To do so, we produce an attestation which includes metadata about the artifact’s origin and the process used to create it.

Metadata included in the provenance attestation
  • Where was it created (e.g., GitHub, GitLab, etc.)?
  • From which version or commit?
  • On what date?
  • By which pipeline (i.e., YAML)?
  • By which worker?
  • With which tools or dependencies?
  • etc.

For security reasons, we need to make the attestation tamper-proof. That’s why it is also recorded in the transparency log.

How does the verification process work in tpm-ca-certificates?

In this section we won’t go in too much detail but if you’re interested in the subject, I invite you to take a look at the spec.

The bundle release process produces the following artifacts and delegates the creation of provenance attestation to GitHub (i.e., attest-build-provenance):

ArtifactDescription
tpm-ca-certificates.pemThe TPM root trust bundle
tpm-intermediate-ca-certificates.pemThe TPM intermediate trust bundle
checksums.txtSHA-256 checksum (of both bundles)
checksums.txt.sigstore.jsonSigstore 1 signature bundle for checksum verification

Table: Release artifacts

As explained in the previous section, we store in the transparency logs (Rekor) a cryptographic proof of the integrity of:

  • the checksums.txt
  • the provenance attestation

During the verification phase, the process performs the following actions:

  1. we ensure checksums.txt.sigstore.json is included in the transparency logs
    • if yes, we extract the digest included in the log entry and compare it with the digest of checksums.txt. If both match, the integrity is verified.
  2. we ensure that the digests of tpm-ca-certificates.pem and tpm-intermediate-ca-certificatespem correspond to those recorded in checksums.txt
  3. we verify that the log entry’s metadata match our policy
  4. we download the provenance attestation bundle (via the GitHub API)
    • Rekor stores the attestation + signature in plain text as a single entry
    • by design in-toto attestation are meant to be public
  5. we ensure the bundle is included in the transparency logs
  6. we verify the content of the provenance attestation
  7. we verify that the log entry’s metadata match our policy
Policy check details
  1. Source repo MUST be equal to https://github.com/loicsikidi/tpm-ca-certificates
  2. Bundle’s commit MUST match the commit recorded in the provenance attestation
  3. Bundle’s date MUST match the date when the entry was created in the transparency log
  4. Build workflows MUST match .github/workflows/release-bundle.yaml@refs/tags/$BUNDLE_DATE
  5. OIDC Issuer MUST match https://token.actions.githubusercontent.com
    • authority which produces job’s identity (in our case, GitHub Actions)

Demo time!

The tpmtb CLI includes all the verifications mentioned previously.

Below is the output of the tpmtb bundle verify command when run from the repository’s root directory:

Passing case

Failing case (because the bundle was tampered)

Playbook to do it yourself
# install the CLI
go install github.com/loicsikidi/tpm-ca-certificates/cmd/tpmtb@latest

git clone https://github.com/loicsikidi/tpm-ca-certificates.git
cd tpm-ca-certificates

# should pass
tpmtb bundle verify MIRROR.tpm-ca-certificates.pem

# let's tamper the bundle
echo "tampered" >> MIRROR.tpm-ca-certificates.pem

# should fail
tpmtb bundle verify MIRROR.tpm-ca-certificates.pem
# pull the latest image
docker pull ghcr.io/loicsikidi/tpm-ca-certificates/tpmtb:latest

git clone https://github.com/loicsikidi/tpm-ca-certificates.git
cd tpm-ca-certificates

# should pass
docker run -it --rm -v $(pwd):/tmp -w /tmp ghcr.io/loicsikidi/tpm-ca-certificates/tpmtb:latest bundle verify MIRROR.tpm-ca-certificates.pem

# let's tamper the bundle
echo "tampered" >> MIRROR.tpm-ca-certificates.pem

# should fail
docker run -it --rm -v $(pwd):/tmp -w /tmp ghcr.io/loicsikidi/tpm-ca-certificates/tpmtb:latest bundle verify MIRROR.tpm-ca-certificates.pem
git clone https://github.com/loicsikidi/tpm-ca-certificates.git
cd tpm-ca-certificates

# build the binary
nix-build

# should pass
./result/bin/tpmtb bundle verify MIRROR.tpm-ca-certificates.pem

# let's tamper the bundle
echo "tampered" >> MIRROR.tpm-ca-certificates.pem

# should fail
./result/bin/tpmtb bundle verify MIRROR.tpm-ca-certificates.pem

Since we rely on a “standard” approach, it’s possible to achieve the same result using cosign and gh (GitHub CLI)!

# will download all artifacts
tpmtb bundle save --output-dir .

# Verify the checksums signature
# (requires cosign >= v2.4.3)
cosign verify-blob \
  --bundle checksums.txt.sigstore.json \
  --certificate-identity-regexp 'https://github.com/loicsikidi/tpm-ca-certificates/.github/workflows/release-bundle.yaml@refs/tags/2026-05-19' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  checksums.txt

# Verify the bundle matches the checksum
sha256sum -c checksums.txt

# Verify that the artifact matches the repo
gh attestation verify tpm-ca-certificates.pem --repo loicsikidi/tpm-ca-certificates
gh attestation verify tpm-intermediate-ca-certificates.pem --repo loicsikidi/tpm-ca-certificates

Do transparency logs support offline validation?

The question is legitimate because we might be in an environment without internet connectivity or with restricted access. Fortunately, it is possible to perform the operation with the Sigstore trusted root.

tpmtb natively integrates this logic to make the operation trivial:

mkdir -p ./cache
# save the bundle and ALL assets allowing to verify the latter offline
tpmtb bundle save --output-dir ./cache
tree ./cache
# output:
# ./cache
# ├── checksums.txt
# ├── checksums.txt.sigstore.json          # Rekor's log entry pointing to checksums.txt's digest
# ├── config.json                           
# ├── provenance.json                      # Rekor's log entry pointing to provenance attestation
# ├── tpm-ca-certificates.pem
# ├── tpm-intermediate-ca-certificates.pem
# └── trusted-root.json                    # Sigstore's trusted root

# You can enable airplane mode

# should pass without internet
tpmtb bundle verify --offline --cache-dir ./cache ./cache/MIRROR.tpm-ca-certificates.pem

Conclusion

In this post, we explored how tpm-ca-certificates uses the transparency log to guarantee the integrity and provenance of its artifacts. This approach has the advantage of offering solid cryptographic proof while relying on a public and free mechanism. The next article will highlight the importance of implementing strong supply chain guardrails!


  1. Sigstore is a project that provides a set of tools and services for signing, verifying, and protecting software supply chains. Rekor is under Sigstore umbrella. ↩︎