Backend Secrets
Backend Secrets are generic, user-defined runtime secrets you reference by name in your endpoints and workflows. They're encrypted at rest, write-only, and never shipped to the browser — perfect for webhook signing keys, internal tokens, or any sensitive value your backend needs at runtime.
You manage them on the Variables page (Ship → Frontend → Variables, route /variables), where Backend Secrets is the default tab.
Encrypted and write-only
Backend Secrets are encrypted with Fernet (per-project key) and decrypted only at execution time inside the engine. Once saved, you can't read a value back from the dashboard — you can only overwrite or delete it. They never appear in your client bundle.
Add a secret
Open the Backend Secrets tab
In your project dashboard, go to Frontend → Variables. The Backend Secrets tab is open by default.
Add a secret by name
Click Add secret, enter a name (for example STRIPE_WEBHOOK_SIGNING_KEY) and the value, then save. The value is encrypted immediately.
Reference it in a workflow
Read the secret from any endpoint or workflow by its name — no redeploy needed. New secrets are available to the engine right away.
Reference a secret
Use the secret name in two equivalent ways inside your endpoints and workflows:
${ secrets.STRIPE_WEBHOOK_SIGNING_KEY }
Both resolve to the decrypted value at execution time. Secrets are wired into the engine via /api/engine/{id}/secrets.
The Code node can't read Backend Secrets
The javascript_code workflow node uses its own plaintext env_vars exposed as ctx.env — it does not have access to ctx.secrets or typed Credentials. Keep sensitive values out of env_vars; use Backend Secrets in the surrounding workflow nodes instead.
Three places for configuration
DYPAI has three distinct stores. Backend Secrets sit in the middle — private runtime values, but generic (not tied to a specific provider).
| Store | Where | Visibility | Use it for |
|---|---|---|---|
| Frontend (Build) vars | Frontend → Variables → Frontend (Build) | Public — baked into the browser bundle | API base URL, public keys (pk_), feature flags |
| Backend Secrets | Frontend → Variables → Backend Secrets | Private — encrypted, never shipped to the browser | Runtime secrets by name, read as ctx.secrets.X / ${ secrets.X } |
| Credentials | Build → Credentials | Private — encrypted, typed | Third-party provider keys (Stripe sk_, OpenAI, Slack…) used by integration nodes |
Secret vs Credential?
If a value belongs to a specific integration that has a node (Stripe, Slack, Resend…), store it as a typed Credential. If it's a generic runtime secret you just need to read by name — a signing key, an internal API token — use a Backend Secret.
Edit or delete a secret
- Update: Click the secret, enter a new value, and save. You overwrite the encrypted value (you can't read the old one).
- Delete: Click the trash icon. The secret is removed and stops resolving in workflows.