Docs

Environment variables

Tofu keeps each variable’s name, scopes and whether it is a secret. A secret’s value goes straight to the hosting provider’s write-only store, and nothing in Tofu — the dashboard, your agent or its database — can read it back.

Agent tools

  • listEnv
  • setPublicEnv
  • deletePublicEnv
  • manageEnvironment

Where a value lives

KindWhat Tofu keeps
SecretThe name, its scopes and a masked preview (the last four characters of a value of 12 or more; a shorter one is masked entirely). The value is sent to the hosting provider as sensitive and never comes back, so a secret is saved only with the production scope: the provider is the only place it is kept.
Not a secretThe name, its scopes and the value, which the dashboard shows.
ManagedWritten by Tofu — the database connection, for example — and read-only: see Database.

Every variable carries one or more scopes — production, preview and development — and a new one gets production and preview unless you choose otherwise. Tofu puts every version of your app online at its address, so every version it builds reads the production variables and no others. A variable that is not a secret can be kept without production, and no version Tofu builds reads it; a secret cannot, because Tofu never keeps its value itself.

Adding variables

On the app’s Keys & settings page in the dashboard — and, for a public value, by a coding agent on your computer.

  1. Before the first deployment

    Variables that are not secrets can be saved already; a secret needs the app's hosting project, which the first deployment creates.

  2. Before every build

    Each deployment receives the production variables before the build starts, so a build step can read them.

  3. On the next deployment

    A change applies to deployments that follow it. Saving does not redeploy the app.

A secret stays a secret: it cannot be turned into a plain variable later. Delete it and add it again if it was never meant to be one.

Importing a .env file

Pasting a .env file saves every value as a secret, one that is not a secret today included, because a variable's name cannot prove its value holds no credential — a DATABASE_URL with a password in it, for example — and before you save, the page marks each variable it would turn into a secret. The exception is a name your app's framework hands to every visitor's browser anyway, one that starts with NEXT_PUBLIC_, VITE_ or PUBLIC_, and APP_ADMIN_EMAILS, which works only when it is not a secret: these are ticked to be saved as plain variables, unless the name has SECRET, PASSWORD, PRIVATE_KEY or SERVICE_ROLE in it or the value looks like a password or a key, and you can untick a NEXT_PUBLIC_, VITE_ or PUBLIC_ name to keep it a secret. A variable that is a secret already stays one. To store other public configuration, add it on its own with Hide this value after saving switched off.

Lines that are invalid, that name a reserved key or that name a managed variable are skipped. An import saves one variable at a time, so if something fails partway, the ones before it are saved and the page says that some may have been.

Your agent: public values, never secrets

listEnv gives your agent the names, scopes and the secret flag — never a value, not even a non-secret one. A public value — an address, a feature flag, a key meant to be public, a public certificate — a coding agent on your computer can save itself with setPublicEnv and remove with deletePublicEnv; a chat you connected by Tofu's address hands you the Keys & settings link for it instead. Tofu refuses one whose name or value looks like a secret, as it is or base64-encoded; changing a value or its scopes, or removing one, needs your agreement for that exact key; and the change applies from the app's next deploy. A secret your agent never handles: manageEnvironment hands you the dashboard address for that exact app, and you type it there.

That is deliberate: a secret's value is never returned by Tofu's API or stored in its database, so it is never in a chat, a tool result or a transcript. For the same reason no tool reads back, changes or deletes a hidden value you saved yourself — an agent that could remove configuration it cannot restore could break an app it cannot fix. The exception is the tools that connect payments, email or Tofu AI: each writes into the app's settings a hidden value that Tofu makes, such as a sending key, which your agent never sees, and takes it out again when you disconnect.

What Tofu does not do with values

  • Show a secret again. Neither the dashboard nor your agent can read a secret’s value back; to change it, save a new one.

  • Set a reserved key. Keys starting with VERCEL_ are reserved, and Tofu refuses them.

  • Save two places at once. The provider and Tofu’s records are not one transaction: if a save fails after the provider accepted it, Tofu reports the failure, and saving again reconciles it.

  • Take a secret from your agent. No tool reads back, changes or deletes a hidden value you saved: you type a secret in the dashboard, and the only values a coding agent on your computer saves itself are public ones. The exception is the tools that connect payments, email or Tofu AI: each writes into the app a hidden value Tofu makes, which your agent never sees, and takes it out when you disconnect.