Prerequisites
Install the CLI:ghcr.io/tinfoilsh/tinfoil-cli.
You also need a Tinfoil organization with Containers enabled, the same prerequisite as the quickstart.
Authenticating
Container management endpoints accept an admin API key scoped to a single organization. Create one from the dashboard’s Admin tab by following Getting a Tinfoil admin key, then run:~/.tinfoil/config.json with mode 0600. These environment variables override saved configuration for one-off invocations:
Admin keys carry the organization ID, so the CLI never asks for an org. To act on a different org, log out and log in with that org’s admin key.
Inspecting your organization
-o json to get machine-readable output suitable for scripting:
owner/repo) or deployment UUID. Containers can be referenced by name or container UUID. If you have a debug-mode and a production-mode container with the same name, pass --debug-mode to disambiguate.
Publishing a config release
Before a tag can be deployed, the config repo must publish a measured release. In the dashboard, open the repository from Containers → Repositories, edittinfoil-config.yml, open and merge the generated pull request, then follow the Release steps.
Alternatively, commit the config change in GitHub and run the Tinfoil Release workflow from the repository’s Actions tab. Wait for both release workflow phases to finish before deploying the tag. See Updating & lifecycle for both workflows.
The same flow is available from the CLI with tinfoil repo, which acts through the Tinfoil GitHub App installed on the repository:
repo build info reports the latest tag and a suggested next patch version. repo build run accepts a semver version and adds the v prefix if missing. The config repository must be public, so never place secret values in tinfoil-config.yml; use secrets instead.
Deploying a container
Once you have a measured release in your config repo (see quickstart for the GitHub setup), deploy it:
The command returns once the deployment is queued. Poll for readiness with
tinfoil container get my-app.
Initial creates cannot use staging. Release promotion defaults to true; pass
--promote-release=false to decline it. Promotion happens only when the GitHub
App is connected, the repository is active, and an initial or changed tag
reaches production on a non-debug instance.
Explicit --host selection requires host-selection access for the organization,
and the selected host and GPU size must be available to it. --replace is
destructive: the old instance is stopped and removed before the replacement is
queued. If the replacement later fails, the old instance is not restored.
Managing deployments
One repository deployment contains all container instances in your organization that use the same GitHub repository. Inspect its aggregate status and instance counts with:--instance with each container UUID:
--staging true or --staging false to override the deployment’s default for one update. Staging applies only to ready CPU-only and single-GPU container instances; unsupported selected instances report per-instance failures rather than updating without staging. Only ready or failed instances are otherwise eligible. The dashboard may label ready instances as Running. An instance is skipped if it is in any other state or already has an update in progress. Results are reported per instance, and the command exits non-zero if any instance is skipped or fails.
Release promotion defaults to true and requests promotion for each eligible changed tag after it becomes production-serving, subject to the repository and GitHub App conditions described above. For staged updates, the request becomes eligible only after acceptance. Pass --promote-release=false to decline.
Lifecycle
start and relaunch support --tag, --variable, --secret, --ssh-key, --debug, --promote-release, --custom-domain, and --host. relaunch also supports --staging; start does not. Supplied variables replace the full saved per-instance variable map; they do not replace the measured env values in tinfoil-config.yml. A supplied secret list replaces the saved manual selection, then merges with secrets declared in tinfoil-config.yml that exist in repository or organization scope. Supplied SSH-key lists replace their saved selections.
Use --host with start only to move a stopped instance, and with relaunch only to move a failed instance. Relaunching a ready instance on another host is rejected; stop it first, then start it with the new host. Host access and GPU entitlement are validated when you explicitly select or move to a host.
Managing in-progress updates
CPU-only and single-GPU updates triggered byrelaunch go through a blue-green window. While the new version is booting, you can inspect or cancel it. Multi-GPU relaunches instead request deletion of the current deployment and immediately queue the replacement; they have downtime and cannot be canceled after replacement starts.
update accept while the existing container instance serves production. Without staging, traffic switches automatically once the candidate is ready. For blue-green updates, update cancel discards the candidate without changing the production-serving instance.
Secrets
Manage organization secrets withtinfoil secret:
tinfoil repo secret with the same subcommands and flags:
--value-file accepts - for stdin, which is the recommended way to set secrets — it avoids leaking the value via shell history or process listings. See secrets and env vars for the underlying model.
SSH keys
Debug-mode containers authorize SSH access using public keys registered at the org level: Choose one of the supported input forms:--ssh-key NAME on tinfoil container create (or relaunch / start).
Registry credentials
For private images, set credentials per registry. Tinfoil supportsghcr, gcr, and dockerhub:
Custom domains
tinfoil container create ... --custom-domain api.example.com. See custom domains for the DNS record details and troubleshooting.
Model weights
For GPU inference containers,tinfoil model prepares Hugging Face weights as
verified artifacts that enclaves load with integrity checking. See
Model weights for how the pieces fit together.
wrap pins the repo’s latest default-branch commit unless --commit is
given. update requires an existing completed wrap of the repo on that host
and resolves the newest commit when --commit is omitted; when an update run
with --wait completes, it prints the new models: block along with the
delete command for the previous wrap job — run that delete only after the new
config is released and deployed. delete is refused while a job is running
or while any deployment on the host references the artifact.
Model commands require tinfoil-cli v0.17.0 or later.
Connecting to a deployed container
tinfoil container connect <name> resolves a container’s enclave domain and source repo, then runs a verified local proxy — equivalent to the nested tinfoil proxy -e <domain> -r <repo> command, but without copy-pasting either value:
127.0.0.1 by default. Pass --bind <ADDRESS> to use another interface:
http://localhost:3301 exactly as you would to your container’s domain. The proxy verifies attestation on startup and pins the TLS certificate for subsequent requests. See connecting for the full client story (SDKs, raw tinfoil http).
Resource metrics
data_points and interval. Each data point has a timestamp, average and maximum CPU/GPU utilization, average and maximum CPU/GPU memory utilization, and CPU/GPU total memory. interval is the width of each time bucket. This is useful for piping into jq or a chart tool.
Scripting tips
-o jsonis supported on every list/get command.- Exit codes are non-zero on failure, with the API error message printed to stderr.
- All commands respect the environment overrides listed above, so the CLI is safe to use from CI — store the admin key as a secret and pass it through the environment instead of running
tinfoil login. --verboseand--traceincrease log verbosity for debugging connectivity issues.

