Using secrets
Give your sandbox the credentials it needs through requests, environment variables, or files.
Save a workspace secret before using these examples. The examples use a GitHub personal access token saved as GITHUB_TOKEN.
Choose the option that fits your app:
- Transparent injection replaces a placeholder in outgoing HTTPS requests, outside the sandbox.
- Files put the real value in a file the app can read.
Use SDK version 1.4.0 or later for the SDK examples. Your API key needs Secrets access. Transparent injection also requires an image with Tenki's managed HTTPS trust.
Call an API with transparent injection
Create the github request policy first. It allows GITHUB_TOKEN in the Authorization header of GitHub user requests. Select it when creating the sandbox:
tenki sandbox create --secret-policy githubThe new sandbox becomes your active session. Run:
tenki sandbox exec -- curl -fsS \
-H 'Authorization: Bearer secrets://GITHUB_TOKEN' \
https://api.github.com/userGitHub returns the account associated with your token. Inside the sandbox, the command contains only the placeholder. Tenki substitutes the token before forwarding the matching request to GitHub.
Tenki does not add Bearer. Your application supplies the header format the API expects. For example, Bearer secrets://GITHUB_TOKEN becomes Bearer YOUR_TOKEN. For an API that expects a raw key in X-API-Key, send just the placeholder in that header and allow X-API-Key in the policy.
When finished with this sandbox:
tenki sandbox terminateKeep the secret and policy to reuse them in the next sandbox.
Set a placeholder once
If an application reads its credential from an environment variable, set that variable when creating the sandbox:
tenki sandbox create --secret-policy github \
--env GITHUB_TOKEN=secrets://GITHUB_TOKENLater commands inherit this environment variable. Its value is the literal placeholder. Tenki substitutes it only when the application sends it in a request that matches a selected policy.
For a single command, use env:
tenki sandbox exec -- env GITHUB_TOKEN=secrets://GITHUB_TOKEN your-commandReplace your-command with the application you want to run. sandbox exec -- executes a program directly, so a leading GITHUB_TOKEN=... without env is not a shell assignment.
Select more than one policy
Pass saved policy names separated by commas. Both policies must already exist in your workspace:
tenki sandbox create --secret-policy github,internal-apiYou can also repeat --secret-policy. Permissions from the selected policies are combined. A matching rule from any selected policy can authorize a request.
Policies control secret substitution. They do not restrict all network traffic. Ordinary requests still follow the sandbox's network settings, and a policy does not override a network restriction.
Transparent injection from an SDK
These examples use the same GITHUB_TOKEN secret and github policy. Install your SDK and configure TENKI_API_KEY as described in the quickstart. Use a key for the workspace containing the secret and policy.
Each example closes its sandbox when it leaves scope. To set placeholders in the session environment, use TypeScript's env, Python's env, or Go's WithEnvs option when creating the sandbox.
Deliver a secret file
Use a file when your application reads credentials from disk. Tenki delivers it at the path you choose inside the sandbox.
This example uses a Node.js app that reads GITHUB_TOKEN from .env. Replace https://github.com/your-org/your-app.git with your public repository. It should have a package-lock.json and an npm run dev script that loads .env.
Create a local .env.example using the GITHUB_TOKEN secret saved earlier:
GITHUB_TOKEN=secrets://GITHUB_TOKENCreate a sandbox with the secret file, clone your app, and start it:
tenki sandbox create --secret-file ./.env.example:/app/.env
tenki sandbox exec -- git clone https://github.com/your-org/your-app.git /app/web
tenki sandbox exec --stream -- bash -c \
'cd /app/web && cp /app/.env .env && npm ci && npm run dev'Tenki writes the real token into /app/.env. The command copies it into the cloned app's directory before starting the dev server. Your local .env.example still contains only the placeholder. No request policy is needed.
The dev server runs in the foreground. When finished, terminate the sandbox from another terminal:
tenki sandbox terminateYou can repeat --secret-file for multiple files. Destinations must be below /app/, /workspace/, or /home/tenki/. Tenki creates files with owner-only read/write permissions, 0600.
Replacement is plain text: Tenki does not escape values for JSON, YAML, or shell syntax.
Secret files from an SDK
To use a .env.example already in your repository, see Using secrets with templates.
Declare the .env contents when creating the sandbox, then clone the app, copy in .env, install dependencies, and run the dev server. Use your own repository URL, with the same requirements as above. The SDK call waits while the server runs; the sandbox closes when the example exits normally.
Reuse an app with another secret
Keep the same .env.example file while choosing a different GitHub token at launch:
tenki sandbox create --secret-file ./.env.example:/app/.env \
--secret-override GITHUB_TOKEN=STAGING_GITHUB_TOKENBoth names refer to workspace secrets; create STAGING_GITHUB_TOKEN first. Overrides apply to environment and file references, not transparent injection policies.
Rotation, revocation, and pause/resume
| Change | Transparent injection | Environment variables and files |
|---|---|---|
| Rotate a secret | Subsequent requests use the active value. | Existing sandboxes keep the delivered value. Start a new sandbox to use the update. |
| Revoke or delete a secret | Further requests using it are denied. | Copies already inside the sandbox remain. New launches cannot resolve that secret. |
| Edit or delete a policy | Subsequent requests use the current permissions. | No effect; policies do not control guest delivery. |
| Pause and resume | Selected policies stay attached and current permissions apply. | The sandbox retains its existing values. Resume does not refresh them. |
Files and process memory can be retained in snapshots, including copies your app makes. Treat snapshots and images created from a sandbox with delivered secrets as containing those secrets. Revoking a secret in Tenki does not erase existing copies or revoke the credential at its provider.
Troubleshooting
If access is denied, check that your account can edit the workspace and your API key has Allow Secrets access. If the app cannot find an environment variable, check that its dev script loads the .env file copied into /app/web.
| Symptom | What to check |
|---|---|
The CLI does not recognize secrets policies | Update the CLI. |
| Secret or policy not found | Check the active workspace, spelling, and whether the object was deleted. Use the secret's actual name in secrets://NAME. |
Tenki returns 403 secret_injection_denied | Check the selected policies, secret status, origin, method, path, and placeholder location. A matching rule must allow that secret. |
The provider returns 401 | Check the token's validity, permissions, and required header format. Tenki does not add Bearer. |
| The application rejects the placeholder before sending a request | That client validates credentials locally. Use a client that accepts placeholders or explicit secret delivery. |
| TLS certificate verification fails | Use an image with Tenki's managed CA trust and make sure the application's trust store includes it. Keep certificate verification enabled. |
| A request is too large for JSON injection | Reduce the JSON body below 256 KiB. |
An allowed destination receives the real credential. Choose destinations you trust and keep both provider permissions and policy rules limited to what the sandbox needs. Transparent injection keeps the credential out of the guest's request construction; it cannot prevent an allowed service from returning it in a response.