Secrets & environment
Project secrets, per-sandbox overrides, and how environment variables reach a running sandbox.
Your app needs API keys, database URLs, and feature flags to run. You configure them once on the project, and every sandbox gets them — no copying .env files between threads.
Project secrets
Secrets are stored on the project and injected into every sandbox's .env. Updates merge: adding a key never wipes the others, so you can add one value without re-entering the rest.
Managing them is manager-gated — Project Settings → Secrets — so not everyone with access to a thread can read or rotate them. See Roles & permissions for who counts as a manager.
The server owns .env
This is the rule worth internalizing: .env is not a file you edit, it's a file that gets rewritten wholesale from project secrets. A hand-edit to it — yours or an agent's — doesn't survive the next sync, and a new thread's boot rewrites it as a matter of course.
For a value that should exist in one sandbox only, agents use .env.local instead:
| File | Written by | Survives a secret sync | Reaches other threads |
|---|---|---|---|
.env | The server, from project secrets | Rewritten from scratch | Yes — every sandbox |
.env.local | An agent, inside one sandbox | Yes | No |
.env.local overrides .env, which makes it the right place for a throwaway test value or a local experiment you don't want other threads inheriting.
Restart to pick up new values
A dev server that's already running keeps the environment it started with. Change a secret and the process won't see it until it restarts — so restart the app, then check the dev-server logs to confirm it came back with the new value.
Scope write-capable tokens narrowly
Any project secret is visible to every sandbox, and every agent in every thread runs inside one. That's fine for the credentials your app needs to boot. It's the wrong home for a token that can change the world — a deploy key, a write-capable third-party token, a production database password.
Keep those out of project secrets and scope them to the automation that actually needs them. The blast radius of a secret is exactly the set of places it's injected; keep that set small.
What's never in a sandbox
Two categories of credential don't flow through project secrets at all:
- LLM API keys live server-side and are never exposed to the browser. Agents reach models through the platform, not through a key you configure.
- Git tokens are stored per user, not per project. When an agent pushes a branch, it pushes with the credentials of the person whose work it is — see GitHub App & authentication.
Where secrets fit in a thread's life
Secrets are rewritten at boot, which is why they're part of the run config and snapshot story rather than something you re-supply per thread. Set them once, rotate them in one place, and every thread — including ones already paused in the warm pool — comes up with the current values.