Skip to content
Edge Functions

Environment variables

Store API keys and other secrets where your Edge Functions can read them.

Local development and production load secrets differently, so set them in both.

Local secrets#

Locally, Edge Functions read secrets from supabase/functions/.env. The local stack loads that file on supabase start.

  1. Create supabase/functions/.env and add each secret with the value you want the function to read. A .env.example template isn't enough, because the runtime reads the values rather than the variable names.

    # supabase/functions/.env
    STRIPE_SECRET_KEY=sk_test_...
  2. Add the file to your .gitignore, along with every other env file you create. A .env file committed to Git exposes every secret in it to anyone who can read the repository.

    # .gitignore
    supabase/functions/.env
    .env.local
  3. 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.ts
    .(() => {
    const = ..('STRIPE_SECRET_KEY')
    return .({ : () })
    })
  4. Start the local stack.

    supabase start
  5. Call the function. When configured comes back true, the runtime handed the secret to your function.

    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.


Production secrets#

Set secrets for your production Edge Functions in the Supabase Dashboard or with the Supabase 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#

  1. Open Edge Function Secrets in the Dashboard.
  2. Enter the Key and Value for your secret, then click Save.
The Edge Function Secrets page in the Supabase Dashboard. An Add new secrets card holds a Key field whose placeholder reads "e.g. CLIENT_KEY" and a Value field with a reveal toggle and a remove button, above an Add another button and a Save button.

You can paste multiple secrets at once.

Using the CLI#

  1. Create a .env file with the secrets you want to deploy, and add it to your .gitignore before you commit.

    # .env
    STRIPE_SECRET_KEY=sk_live_...
  2. Push every secret in the file to your remote project. The command also makes them visible in the Dashboard.

    supabase secrets set --env-file .env

supabase secrets set also sets production secrets individually, without a .env file.

supabase secrets set STRIPE_SECRET_KEY=sk_live_...

List the secrets set on your remote project:

supabase secrets list

Your deployed functions can now read the secret.


Accessing environment variables#

Read an environment variable with Deno.env.get, passing the name of the variable.

..('NAME_OF_SECRET')

In an Edge Function#

Inside an Edge Function, the Supabase keys are already in the environment. Read them and pass them to createClient:

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 Row Level Security)
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 Row Level Security)
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 with --env-file, and grant the script access to environment variables with --allow-env:

deno run --allow-env --env-file=supabase/functions/.env script.ts

Or set the variable for a single command:

STRIPE_SECRET_KEY=sk_test_... deno run --allow-env script.ts

When your function can't read a secret#

A variable that comes back empty usually means the value never reached the runtime.

Restart the stack, or serve the function with the file passed explicitly:

supabase functions serve hello-world --env-file supabase/functions/.env

If the value still doesn't arrive, confirm you edited the file your runtime reads.


Reference#

Look up which file feeds which runtime, and which variables Supabase injects for you.

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/.env is the one your Edge Functions read, loaded when the stack starts.
  • A file you name yourself, such as .env.local, is read only when you pass it to supabase functions serve with --env-file.
  • A .env at the root of your project is the one config.toml reads, through its env() function. See Using secrets inside config.toml. A variable your function needs also has to be in supabase/functions/.env, even when the root file already holds the same value.

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:

VariableDescription
SUPABASE_URLThe API gateway for your Supabase project.
SUPABASE_DB_URLThe URL for your Postgres database. Use it to connect directly to your database.
SUPABASE_PUBLISHABLE_KEYSThe publishable keys JSON dictionary for your Supabase API. Safe to use in a browser when you have Row Level Security enabled.
SUPABASE_SECRET_KEYSThe secret keys JSON dictionary for your Supabase API. These keys bypass Row Level Security, so use them in Edge Functions and never in a browser.
SUPABASE_JWKSThe JSON Web Key Set used to verify user JWTs. Same value served at https://<project-ref>.supabase.co/auth/v1/.well-known/jwks.json.

Legacy keys:

VariableDescription
SUPABASE_ANON_KEYThe anon key for your Supabase API. Safe to use in a browser when you have Row Level Security enabled.
SUPABASE_SERVICE_ROLE_KEYThe service_role key for your Supabase API. This key bypasses Row Level Security, so use it in Edge Functions and never in a browser.

In a hosted environment, functions also have access to these variables:

VariableDescription
SB_REGIONThe region the function was invoked in.
SB_EXECUTION_IDA UUID for the function instance, or isolate.
DENO_DEPLOYMENT_IDThe version of the function code, formatted as {project_ref}_{function_id}_{version}.