Skip to main content
The quickstart deploys a pre-built Docker image. If you have another pre-built image, reference it directly in the image field of your tinfoil-config.yml. If instead you have source code you want to deploy, you’ll need to build an image for it first. How you do this depends on the visibility of the repository:
  • Public source code → use tinfoil-public-containers-template. When deploying public code you can do it all in one repo. The public-containers template contains one workflow that builds the image, substitutes the real digest into the config at the tagged release commit, and publishes the release. It consolidates the tinfoil-containers-hello-world repo and the tinfoil-containers-template repo.
  • Private source code → keep your code in its own private repo and use tinfoil-containers-hello-world as the build-and-publish pattern (Dockerfile + workflow that pushes to GHCR). Then reference the published image from a tinfoil-containers-template fork like the quickstart.
If the published image is private (not just the source), Tinfoil needs registry credentials to pull it at deploy time. See Private images. Public images work without any configuration.

Image digests in the release workflow

The image field must pin a SHA256 digest because this is what the attestation commits to and what clients verify. How the digest gets into your config depends on your setup:
  • Pre-built image (the quickstart template, or any external image you pull): put the real digest in your config directly.
  • Build your own image (the public-containers template): use a placeholder digest on main:
    tinfoil-config.yml
When you trigger a release, tinfoil-release.yml builds the image, substitutes the real digest into the config on the tagged release commit (not on main), then runs the measurement and publish workflow against that commit. main keeps the placeholder. For example, here’s the release for v0.0.118 of confidential-model-router:
GitHub release page showing the published measurements and attestation

The release contains measurements and the bundled binary

You can see that it contains a detached commit (d3aad2e) that doesn’t belong to any branch. If we click on it we can see the placeholder being replaced with the real digest:
GitHub commit page showing the release workflow replacing the placeholder digest with the real one
The measurement and publish workflow runs against that commit, producing a GitHub release with the enclave measurements.