Environment variables
Manage sensitive data securely across environments.
Store API keys and other secrets where your Edge Functions can read them. Local development and production load them differently, so set them in both.
Local secrets#
In development, Edge Functions read secrets from supabase/functions/.env, which is automatically loaded on supabase start. Create the file before you start the stack.
-
Create
supabase/functions/.envand add each secret with the value you want the function to read. A.env.exampletemplate isn't enough on its own, because the runtime reads the values rather than the variable names.# supabase/functions/.envSTRIPE_SECRET_KEY=sk_test_... -
Add the file to your
.gitignore, along with every other env file you create. A.envfile committed to Git exposes every secret in it to anyone who can read the repository.# .gitignoresupabase/functions/.env.env.local -
Create the function, then replace its contents to read the secret and report whether it arrived. Return the result of the check rather than the value, so the response never carries the secret.
supabase functions new hello-world// supabase/functions/hello-world/index.tsDeno.serve(() => {const secretKey = Deno.env.get('STRIPE_SECRET_KEY')return Response.json({ configured: Boolean(secretKey) })}) -
Start the local stack.
supabase start -
Call the function. A
configuredoftruemeans the runtime handed it the secret.curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/hello-world' \--header 'apikey: <SUPABASE_PUBLISHABLE_KEY>'
Your function now reads the secret from your local environment.
Accessing environment variables#
Access an environment variable with the Deno.env.get method, passing the name of the variable you want.
..('NAME_OF_SECRET')In an Edge Function#
import { createClient } from 'npm:@supabase/supabase-js@2'const SUPABASE_PUBLISHABLE_KEYS = JSON.parse(Deno.env.get('SUPABASE_PUBLISHABLE_KEYS')!)// For user-facing operations (respects RLS)const supabase = createClient( Deno.env.get('SUPABASE_URL')!, // To use a different API key, change 'default' to your preferred key name SUPABASE_PUBLISHABLE_KEYS['default'])const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)// For admin operations (bypasses RLS)const supabaseAdmin = createClient( Deno.env.get('SUPABASE_URL')!, // To use a different API key, change 'default' to your preferred key name SUPABASE_SECRET_KEYS['default'])In a Deno script#
A Deno script you run yourself, outside supabase functions serve, doesn't read supabase/functions/.env. Pass the file, and grant the script access to the environment with --allow-env:
deno run --allow-env --env-file=supabase/functions/.env script.tsOr set the variable for a single command:
STRIPE_SECRET_KEY=sk_test_... deno run --allow-env script.tsWhen your function can't read a secret#
The local runtime loads supabase/functions/.env when the stack starts, so a function that returns nothing for a variable usually means the value never reached it.
Restart the stack, or serve the function with the file passed explicitly:
supabase functions serve hello-world --env-file supabase/functions/.envTo keep a separate file per environment, name your own and pass it the same way:
supabase functions serve --env-file .env.localProduction secrets#
Set secrets for your production Edge Functions in the Dashboard or with the CLI.
Creating or deleting a production secret requires the Owner or Administrator role. Developers can view secrets but not change them. See Access control for the full matrix.
A secret name can't start with SUPABASE_. That prefix is reserved for the variables Supabase injects, and both the Dashboard and the Management API reject it.
Using the Dashboard#
- Open Edge Function Secrets in the Dashboard.
- Enter the Key and Value for your secret, then click Save.

You can paste multiple secrets at once.
Using the CLI#
Create a .env file with the secrets you want to deploy. Add it to your .gitignore before you commit.
# .envSTRIPE_SECRET_KEY=sk_live_...Push every secret in the file to your remote project with supabase secrets set, which also makes them visible in the Dashboard.
supabase secrets set --env-file .envThis command also sets production secrets individually, without a .env file.
supabase secrets set STRIPE_SECRET_KEY=sk_live_...To see the secrets you have set remotely, use supabase secrets list.
supabase secrets listSecrets are available in your functions immediately. You don't need to redeploy after setting them.
Your deployed functions can now read the secret.
Where local values come from#
A project can hold more than one file that feeds local environment variables, and they aren't interchangeable:
supabase/functions/.envis the one your Edge Functions read, loaded when the stack starts.- A file you name yourself, such as
.env.local, passed tosupabase functions servewith--env-file. - A
.envat the root of your project is the oneconfig.tomlreads, through itsenv()function. See Using secrets inside config.toml. A variable your function needs has to be insupabase/functions/.envtoo, even when the same value is already in the root file.
You can also set local values in config.toml itself, under [edge_runtime.secrets]:
[edge_runtime.secrets]STRIPE_SECRET_KEY = "env(STRIPE_SECRET_KEY)"Default secrets#
Alongside the secrets you set yourself, Edge Functions have access to these by default:
SUPABASE_URL: The API gateway for your Supabase projectSUPABASE_DB_URL: The URL for your Postgres database. Use it to connect directly to your databaseSUPABASE_PUBLISHABLE_KEYS: Thepublishablekeys JSON dictionary for your Supabase API. This is safe to use in a browser when you have Row Level Security enabledSUPABASE_SECRET_KEYS: Thesecretkeys JSON dictionary for your Supabase API. This is safe to use in Edge Functions, but never use it in a browser. These keys bypass Row Level SecuritySUPABASE_JWKS: The JSON Web Key Set used to verify user JWTs. Same value served athttps://<project-ref>.supabase.co/auth/v1/.well-known/jwks.json
Legacy keys:
SUPABASE_ANON_KEY: Theanonkey for your Supabase API. This is safe to use in a browser when you have Row Level Security enabledSUPABASE_SERVICE_ROLE_KEY: Theservice_rolekey for your Supabase API. This is safe to use in Edge Functions, but never use it in a browser. This key bypasses Row Level Security
In a hosted environment, functions have access to the following environment variables:
SB_REGION: The region the function was invoked inSB_EXECUTION_ID: A UUID for the function instance, or isolateDENO_DEPLOYMENT_ID: The version of the function code, formatted as{project_ref}_{function_id}_{version}