Secrets

Store sensitive credentials — API keys, tokens, connection strings — as encrypted environment variables injected into your functions at runtime.

How secrets work

Secrets are stored in the database encrypted with AES-256-GCM. The encryption key is never stored alongside the data — it lives in the server environment. Secret values are never returned by the API under any circumstances — only the secret name is exposed in dashboard responses.

At function execution time, secrets are decrypted in memory and injected into the Deno subprocess as environment variables. Inside your function, access them with Deno.env.get('SECRET_NAME').

Encryption standard

Secrets are encrypted with AES-256-GCM — the same standard used by services like Stripe and Supabase. Ciphertext is base64-encoded before storage. The encryption key is stored separately in the server environment, never in the database.

Adding secrets

Navigate to your project → Secrets in the sidebar. Enter the secret name (e.g. STRIPE_KEY) and value, then click Save Secret.

Secret names are automatically uppercased. Use SCREAMING_SNAKE_CASE by convention.

Using secrets in functions

process-payment/index.tsTypeScript
export async function handler(ctx) {
  // Access secrets via Deno.env.get()
  const stripeKey = Deno.env.get('STRIPE_KEY');
  const sendgridKey = Deno.env.get('SENDGRID_KEY');
  const webhookSecret = Deno.env.get('WEBHOOK_SECRET');

  if (!stripeKey) {
    throw new Error('STRIPE_KEY secret is not configured');
  }

  const { amount, currency } = ctx.request;

  const response = await fetch('https://api.stripe.com/v1/charges', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${stripeKey}`,
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      amount: String(amount),
      currency,
      source: 'tok_visa',
    }),
  });

  const charge = await response.json();
  return { chargeId: charge.id, status: charge.status };
}

Updating a secret

Saving a secret with the same name as an existing one overwrites it. The new value takes effect on the next function execution — there is no need to redeploy the function.

Secrets are project-scoped

Secrets are scoped to the project, not to individual functions. Every function in the project has access to every secret. If you need to restrict access, use different projects or prefix secret names by function.

Secret name rules

Uppercase letters, numbers, and underscores only
Maximum 64 characters
Cannot start with a number
Examples: STRIPE_KEY, SENDGRID_API_KEY, DATABASE_URL, WEBHOOK_SECRET