Skip to main content
Deploy the prebuilt hello-world image, or bring an image you already have. Both paths use a public config repository, a measured release, and an independently managed instance. Instances that use the same config repository belong to one container project. This tutorial reaches a verified HTTP response before changing the running version. Choose the dashboard or CLI instructions at each step; they operate on the same resources.

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 login and check tinfoil whoami before 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, replace myorg/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 complete tinfoil-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
Use the complete values in your generated repository; do not substitute a placeholder digest or CVM version. The demo reports 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.
  1. 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.
  2. 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.
  3. Choose Release, enter v0.0.1, and choose Run build. If the template is unchanged, you can release it without making a cosmetic edit.
  4. Follow the workflow link and wait for both phases described below to succeed.
Queued is not deployable. Wait for Tinfoil Release (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

Create GREETING_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.
Open Containers → Secrets, choose Add Secret, enter GREETING_TOKEN and a nonempty value, and save.

5. Create the instance

  1. In the config editor’s Latest releases, find v0.0.1 and 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.
  2. Name it hello-world and confirm the selected repository and v0.0.1 tag match the release you just published.
  3. Check the image, resources, environment, and GREETING_TOKEN secret. Leave debug mode off; the demo needs no custom domain or volume.
  4. Review Mark v0.0.1 as the latest release once it’s running, then choose Create instance.
Wait for Running, then copy the instance’s domain from the dashboard or CLI output. The first instance creates its project automatically if that repository does not already have one. A source repository alone is not a running project or instance. Marking the tag as the latest release defaults to enabled (--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. Replace hello-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:
The CLI verifies attestation against your published release and pins the enclave’s TLS identity before sending the request. The untouched demo returns:
If you changed 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

  1. Edit MESSAGE in the config to A new message!. Open a config PR and merge it into the default branch.
  2. Release v0.0.2, using Release in the dashboard or:
  3. Wait for both workflow phases to succeed and for v0.0.2 to be published.
  4. Choose Update on hello-world and select v0.0.2, or run:
  5. After the update completes, repeat the verified request from step 6 with @v0.0.2. Expect MESSAGE: A new message! and GREETING_TOKEN: present.
The demo updates blue/green: the current enclave keeps serving until the replacement is healthy. Publishing alone never changes a running instance. To inspect a candidate before switching traffic, use Hold for review. For downtime, current-to-target settings, and rollback behavior, see Updating. Updates inherit the project’s hold default. If it is enabled, verify the candidate at its review URL and Promote it before expecting v0.0.2 at the production URL; or explicitly choose --hold=false for this update.

Cleanup

Choose Stop in the dashboard or run tinfoil 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.