Environment and secrets
Set environment values for your build and your running app, choose where each one goes, and know when a change takes effect.
Environment values are the API keys, passwords and configuration your project needs without writing them into its code. Fortly encrypts each value before storing it and never hands it back: the API and the console show names, scopes and dates, never values. You choose, per value, whether it goes to your build, your running app, or both.
Set a value
Open the environment
Open your project, go to Deployments, and choose the Environment tab.
Add a value
Under Add a value, enter the Name and the Value, and choose Where it may be used: Runs only, Builds only, or Builds and runs.
Save it
The value is stored encrypted and cannot be shown again. It appears under Set on this project with its scope and the date it was set.
curl -X POST https://api.fortly.com/projects/my-app-ada/secrets \
-H "Authorization: Bearer $FORTLY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "STRIPE_SECRET_KEY", "value": "sk_live_...", "scope": "runtime"}'namestringRequiredvaluestringRequiredscopestringruntime, build or both. Defaults to runtime.The reply is 201 with {"name": "STRIPE_SECRET_KEY", "scope": "runtime"}. Setting a name that already exists replaces its value and its scope. Use the project's full API name, such as my-app-ada — see Deploying your code. The full reference is in Secrets API.
Choose where a value goes
| Scope | Console label | Given to | Use it for |
|---|---|---|---|
runtime | Runs only | Your running app | Database passwords, payment keys, anything only your server reads |
build | Builds only | Your build, not your running app | Values a framework bakes into its output at build time |
both | Builds and runs | Both | A value the build embeds and the server also reads |
runtime is the default because it hands a value to the fewest places. A build runs your project's own install scripts, so keep a value out of it unless the build needs it.
Frameworks like Next.js read variables such as NEXT_PUBLIC_API_URL while they build and write them into the files they produce. Give those values the build or both scope. A value the build cannot see ends up missing from the site, which then fails in the visitor's browser rather than at deploy time.
A scope you spell wrong is refused rather than read as runtime: "runtme" is not a secret scope; use one of runtime, build, both.
When a change takes effect
Setting or removing a value takes effect without a deploy for values your running app already reads: Fortly clears the project's cached responses, and the next request runs with the new set of values.
Two cases need a new deploy:
- A value with the
buildorbothscope. It is read while the build runs, so output that is already built keeps the value it was built with. Deploy again to rebuild with the new one. - A new name for a server-rendered app or Node server. A release built into a Worker receives the
runtimeandbothvalues whose names existed when it was built. After adding a new name, deploy again so the new release picks it up. Changing or removing a value for an existing name does not need this.
A static site has no running server, so only its build-time values matter to it.
List and remove values
curl https://api.fortly.com/projects/my-app-ada/secrets \
-H "Authorization: Bearer $FORTLY_TOKEN"Each entry in secrets has name, created_at and scope. There is no route that returns a value: if you lose one, set a new one.
curl -X DELETE https://api.fortly.com/projects/my-app-ada/secrets/STRIPE_SECRET_KEY \
-H "Authorization: Bearer $FORTLY_TOKEN"Removing answers 204, or 404 with no secret by that name.
/ projects/ {name}/ secretsNames, scopes and dates — never the values/ projects/ {name}/ secretsSet one, or replace it/ projects/ {name}/ secrets/ {key}Remove oneNames Fortly reserves
These names are reserved for the platform, and setting one is refused with PORT is set by Fortly and cannot be replaced (naming the one you tried):
| Group | Names |
|---|---|
| Process | PORT, HOST, PATH |
| Fortly | FORTLY_API, FORTLY_TOKEN |
| Database | DATABASE_URL, DATABASE_TRANSACTION_URL, PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE |
The database names are reserved so that no value of yours can stand in for the connection details the platform manages for your project's database. A name that only contains one of these, such as MY_DATABASE_URL, is yours to use.
Other names are refused when they break the naming rule: a name cannot start with a digit, or a name can use capital letters, digits and underscores — for example DATABASE_URL.
How values are protected
- Encrypted at rest with AES-256-GCM. The key is held outside the database, so a copy of the database does not carry readable values.
- Never returned. No API route and no console page shows a value after it is set.
- Given only where their scope says. A build receives
buildandbothvalues; a running app receivesruntimeandbothvalues. - Masked in logs. A value 8 characters or longer that appears in your project's log is replaced with
[redacted]. Shorter values are not masked, because they cannot be told apart from ordinary words.