Environment variables & secrets
Projects carry configuration in two places: environment variables (returned in API responses, editable) and secrets (stored encrypted, never returned). Both are delivered to your build and running app the same way for every project type.
env vs secrets
Section titled “env vs secrets”| env | secrets | |
|---|---|---|
| Shape | [{ name, value }] | [{ name, value }] |
| Stored as | plain list | base64 of a JSON array ([base64(JSON([...]))]) |
| Returned in API responses? | Yes | No — never |
| On the deploy wire | plaintext (envData for containers) | encrypted (iv:cipher) |
| Use for | non-sensitive config, public keys | API keys, passwords, private tokens |
There is no separate build-time / runtime split in the schema. env is a single list surfaced in responses, plus a separate secrets list that is stored base64-encoded and never returned. Whether a variable reaches the browser depends on the framework and the project type, not on a schema flag — see the inlining rule below.
Secrets are encrypted at rest and ride the deploy (and cronjob) queue encrypted as iv:cipher; env rides plaintext. Because secrets are never returned, the only way to change a secret is to set a new value — you cannot read the current one back.
The critical NEXT_PUBLIC_* / build-time inlining rule
Section titled “The critical NEXT_PUBLIC_* / build-time inlining rule”For static and SPA builds (Vite, Next.js, Create React App), only variables the framework exposes at build time reach the client bundle. For Next.js that means variables prefixed NEXT_PUBLIC_*; for Vite, VITE_*; for Create React App, REACT_APP_*.
Two consequences follow:
- Runtime-only secrets are not baked into a static build. A static site has no server to read environment variables at request time, so anything not inlined at build time simply isn’t available to the shipped app.
- Anything inlined is public. A variable the framework inlines at build time is compiled into the JavaScript that every visitor downloads.
For container apps, env and secrets are available to the running server process at runtime, so a backend can read a secret without exposing it to the client.
How env and secrets are delivered
Section titled “How env and secrets are delivered”Both flow to the container build image (via entrypoint.sh) and to the running app the same way for all project types. On the deploy wire, env rides as envData (plaintext) and secrets ride encrypted. The same delivery path is used for cronjobs: env plaintext, secrets encrypted.
Setting env and secrets
Section titled “Setting env and secrets”You set env and secrets on the project’s settings page, on the create form, or via the Projects API. Changing them is applied on the next deploy.
The Deploy to PandaStack button prompts for variables declared in pandastack.json. Note that variables declared this way are submitted as plaintext env (visible and editable on the settings page afterward), not write-only secrets — so declare only non-sensitive config in pandastack.json, and add real secrets manually after deploy.
Reserved variables
Section titled “Reserved variables”Some environment variable names are reserved by the platform (system variables the runtime sets). PandaStack guards these against override — you cannot clobber a reserved/system variable with your own value.
Setting env from a connected integration
Section titled “Setting env from a connected integration”Connecting a third-party service under Integrations and linking it to a project injects that service’s variables into the project’s env automatically. For example, linking the Stripe integration writes STRIPE_SECRET_KEY (and, from metadata, STRIPE_PUBLISHABLE_KEY / STRIPE_WEBHOOK_SECRET); linking Sentry writes SENTRY_DSN and related vars. Linking triggers a best-effort redeploy so the new variables take effect. Disconnecting or unlinking strips exactly those injected variable names and leaves your own vars untouched. See Integrations.
Related
Section titled “Related”- Static sites — why runtime secrets don’t reach a static build
- Container apps — runtime env for servers
- Build & buildpacks
- Integrations — inject a service’s env into a project
- Deploy to PandaStack button — env prompts via
pandastack.json