Prerequisites
- An organization with Tinfoil Containers enabled in the dashboard, and an organization admin who can create instances and secrets.
- A GitHub account that can create a public repository and run its GitHub Actions workflows.
- The current Tinfoil CLI, including for the verified HTTP request if you create the instance in the dashboard.
- For CLI management, an organization admin key. Run
tinfoil loginand checktinfoil whoamibefore creating resources. See credential precedence if environment variables are set.
1. Create a repo from the template
Open tinfoil-containers-template and choose Use this template → Create a new repository. Make the new repository public. In the commands below, replacemyorg/my-app-config with its GitHub owner/repo name, not the template’s name.
The config and release evidence must be public so clients can independently verify the enclave. Your application image can remain private. Never put secret values in the public repository.
Keep both template workflows: .github/workflows/tinfoil-release.yml and .github/workflows/tinfoil-release-publish.yml. They create the tag, compute its enclave measurement, sign the attestation, and publish the release.
2. Review the config
The template contains a completetinfoil-config.yml, including a real image digest. The example below matches template commit 0eddc32. This minimal demo listens on port 8080, needs no outbound network access or writable storage, and declares one secret you will create before deploying:
tinfoil-config.yml
MESSAGE and whether GREETING_TOKEN is present, never its value. It does not require a custom domain, GPU, or disk.
Bringing an existing image
Instead of the demo, edit the config to match your application before publishing the first release:
The remaining steps use the hello-world demo. For your own image, create its declared secrets and use its expected endpoint and response. See the configuration reference for the schema, or building an image if you do not have one yet.
3. Release a version
First commit any config changes to the default branch. A config pull request must be merged, not merely opened or closed, before you release it.- Dashboard
- CLI
- Open Containers → Projects. Under Available configurations, choose Connect GitHub if needed and grant the Tinfoil GitHub App access to your config repository. Choose Refresh after connecting or adding a repository.
- Select your repository under Available configurations to open its config editor. If you change a field, choose Open Pull Request, then review and merge that PR on GitHub. Return to the editor and refresh its status.
- Choose Release, enter
v0.0.1, and choose Run build. If the template is unchanged, you can release it without making a cosmetic edit. - Follow the workflow link and wait for both phases described below to succeed.
tinfoil-release.yml, tag creation and dispatch) and Tinfoil Release - Publish (auto-triggered) (tinfoil-release-publish.yml, measurement, attestation, and publication) to complete successfully. Confirm that GitHub has a published release for v0.0.1. A tag alone, a successful dispatch, or a fixed waiting period is not sufficient. If a workflow fails, inspect its logs before proceeding.
4. Add the demo secret
CreateGREETING_TOKEN in the same Tinfoil organization as the instance. The demo only checks that it has a nonempty value; use a disposable demo value, not a real credential.
- Dashboard
- CLI
Open Containers → Secrets, choose Add Secret, enter
GREETING_TOKEN and a nonempty value, and save.5. Create the instance
- Dashboard
- CLI
- In the config editor’s Latest releases, find
v0.0.1and choose Create instance from this release. This carries the repository and tag into the create form. You can also choose New instance from the instances view and select them yourself. - Name it
hello-worldand confirm the selected repository andv0.0.1tag match the release you just published. - Check the image, resources, environment, and
GREETING_TOKENsecret. Leave debug mode off; the demo needs no custom domain or volume. - Review Mark v0.0.1 as the latest release once it’s running, then choose Create instance.
--mark-latest=false disables it). After a non-debug instance is running, Tinfoil can mark its tag as the repository’s latest GitHub release when the GitHub App is connected and the repository is active. This is a repository-wide change: consumers that follow GitHub’s latest release can be affected even though other instances are not updated. This tutorial pins requests to the exact tag.
6. Make a verified request
This step uses beta V3 attestation verification through the CLI. Replacehello-world.myorg.containers.tinfoil.dev with the actual domain from step 5, without https://. Replace the repository with your own and keep the @v0.0.1 pin:
MESSAGE before publishing, expect that value instead. A verification failure is not a reason to disable verification: check the domain, repository, tag, release publication, and that debug mode is off. For application clients, use a Tinfoil SDK.
A direct curl to the public domain only checks connectivity; it does not verify the enclave. Do not use it to send sensitive data.
7. Update only after the first request works
-
Edit
MESSAGEin the config toA new message!. Open a config PR and merge it into the default branch. -
Release
v0.0.2, using Release in the dashboard or: -
Wait for both workflow phases to succeed and for
v0.0.2to be published. -
Choose Update on
hello-worldand selectv0.0.2, or run: -
After the update completes, repeat the verified request from step 6 with
@v0.0.2. ExpectMESSAGE: A new message!andGREETING_TOKEN: present.
v0.0.2 at the production URL; or explicitly choose --hold=false for this update.
Cleanup
Choose Stop in the dashboard or runtinfoil container stop hello-world when you no longer need the demo running. Stopped instances keep their saved configuration, not their memory. Use Deploy to boot it again or Delete to remove it permanently; see Instance lifecycle.
