Security
- Don’t use debug mode in production. Debug mode enables SSH access and logging that you don’t want in a production enclave. Deploy a separate debug instance for troubleshooting.
- Use secrets for all sensitive values. Database URLs, API keys, tokens, and credentials should be stored as secrets, not as environment variables in your config file or repo.
- Use minimal registry credentials. If you’re pulling from a private registry, create access tokens with read-only scope. See registry auth.
- Rotate application credentials periodically. Update managed secret values in the dashboard, then update your container to pick up the new values. Persistent-volume keys are different: retain the original key in your private secret store. Volume-key rotation requires explicit migration or re-encryption, not just a secret-value change.
- Only expose necessary paths. The
pathslist in your config acts as an allowlist. Only list the endpoints your app needs to serve externally. - Know the CLI’s connection policy. CLI connections to your containers (
connect,forward,ssh,scp,attest-ssh) check the resolved config against a local policy; scripts without a terminal fail closed on unknown configs and should state their expectation with--repo. Avoid--dangerous— it skips the config check entirely. If a machine should never learn new trust,tinfoil trust set --mode frozenlocks the policy.
Reliability
- Use the update flow. Update running containers through the Update flow rather than deleting and recreating them. CPU-only and single-GPU containers without persistent volumes update blue/green, so the current version keeps serving if the new one fails its health checks. Multi-GPU containers and containers with persistent volumes have downtime during updates; the dashboard and CLI ask you to confirm it first.
- Hold updates for review before they take traffic. For running CPU-only and single-GPU instances without persistent volumes, hold the update, try it at its review URL, and promote it after testing. Reserve debug mode for troubleshooting with non-sensitive data.
Resources
- Right-size your container. Start with the smallest resource tier that works and scale up if needed. Over-provisioning wastes resources; under-provisioning causes OOM kills and slow responses. See resource options for guidance.
- Monitor memory usage. If your container is using close to its memory limit, it may get killed under load. Allocate headroom above your typical usage.
Networking
- Set up a custom domain. For production APIs, use a custom domain rather than the default
*.containers.tinfoil.devURL to control your application’s address. - Listen on the right port. Your app must listen on the port you configured as
upstream-portintinfoil-config.yml.
Secrets hygiene
- Watch for stale secrets. The dashboard shows a warning when secrets have been updated since the container was last deployed. Update promptly after rotating secrets.
- Don’t log secret values. Even though secrets are only available inside the enclave, avoid printing them to stdout/stderr. Treat the enclave runtime the same way you’d treat any production server.
- Clean up unused secrets. Remove organization and repository secrets that are no longer referenced by any container.
Deployment workflow
- Start from the template. Create your repo from the tinfoil-containers-template for a complete config and measured-release workflows.
- Pin images with SHA256 digests. Commit the real image digest before releasing the config so verification identifies the exact image. See Building images.
- Tag releases in Git. Use semantic versioning or a consistent tagging scheme so you can track which version is deployed and roll back to a known-good tag.

