diff --git a/apps/docs/content/guides/functions/secrets.mdx b/apps/docs/content/guides/functions/secrets.mdx index ae432c437a2..769e686fb5f 100644 --- a/apps/docs/content/guides/functions/secrets.mdx +++ b/apps/docs/content/guides/functions/secrets.mdx @@ -9,23 +9,51 @@ Store API keys and other secrets where your Edge Functions can read them. Local ## Local secrets -In development, Edge Functions read secrets from `supabase/functions/.env`, which is automatically loaded on `supabase start`. To use a file you name yourself, such as `.env.local`, pass it to `supabase functions serve` with the `--env-file` option. +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. -```bash -supabase functions serve --env-file .env.local -``` +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 on its own, because the runtime reads the values rather than the variable names. - + ```bash + # supabase/functions/.env + STRIPE_SECRET_KEY=sk_test_... + ``` -A `.env` file committed to Git exposes every secret in it to anyone who can read the repository. Add the file to your `.gitignore` before you commit. +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. - + ```bash + # .gitignore + supabase/functions/.env + .env.local + ``` -Serve the function locally: +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. -```bash -supabase functions serve hello-world -``` + ```bash + supabase functions new hello-world + ``` + + ```tsx + // supabase/functions/hello-world/index.ts + Deno.serve(() => { + const secretKey = Deno.env.get('STRIPE_SECRET_KEY') + return Response.json({ configured: Boolean(secretKey) }) + }) + ``` + +4. Start the local stack. + + ```bash + supabase start + ``` + +5. Call the function. A `configured` of `true` means the runtime handed it the secret. + + ```bash + curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/hello-world' \ + --header 'apikey: ' + ``` + +Your function now reads the secret from your local environment. --- @@ -62,6 +90,24 @@ const supabaseAdmin = createClient( --- +## When 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: + +```bash +supabase functions serve hello-world --env-file supabase/functions/.env +``` + +To keep a separate file per environment, name your own and pass it the same way: + +```bash +supabase functions serve --env-file .env.local +``` + +--- + ## Production secrets Set secrets for your production Edge Functions in the Dashboard or with the CLI.