🇪🇺 Fixed egress for Edge Functions

🇪🇺 Static IP for Supabase Edge Functions

Supabase says it plainly: Edge Functions get no fixed egress IPs. Send each outbound fetch through two static EU IPs instead, whitelist them once, and IP-restricted partner APIs let your Deno functions back in.

supabase/functions/send-data/index.ts

// Edge Function secret, set via Supabase CLI

HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443

const client = Deno.createHttpClient({

  proxy: { url: Deno.env.get('HTTPS_PROXY') },

});

const res = await fetch('https://api.partner.eu/data', { client });

Why Edge Functions and IP allowlists collide

Supabase runs your functions on distributed edge infrastructure, and the platform's own documentation explains why that makes whitelisting impossible without help.

Supabase's docs say it can't be done

Supabase maintains a dedicated troubleshooting page, "Why Supabase Edge Functions cannot provide static egress IPs for whitelisting". Invocations leave from dynamic, distributed address ranges, so there is nothing stable for a partner to allowlist. Their suggested fix is an outbound proxy.

Network Restrictions won't save you

Supabase's Network Restrictions feature filters traffic arriving at your Postgres database. It has no effect on the requests your Edge Functions send out to third-party APIs, which is exactly where the allowlist problem lives.

The usual npm proxy tricks don't run on Deno

Edge Functions execute on Deno, not Node.js. Packages like https-proxy-agent depend on raw socket APIs that the edge runtime restricts. The supported path is Deno's own HTTP client, Deno.createHttpClient, which accepts a proxy configuration directly.

Allowlisted APIs reject unknown sources

Payment providers, banking APIs, and enterprise platforms check the caller's IP before anything else. A function invoking from an unlisted address gets a 403, and because Edge Functions often run from webhooks or cron, the rejection can sit unnoticed until a customer complains.

The Solution

Send every outbound fetch through one fixed EU address pair

Your Edge Function

Deno, on Supabase

HTTPS Proxy

(Static EU IP)

Partner API

with IP allowlist

On the partner's side, every request your functions make shows up from the same two EU addresses, no matter which edge region the invocation landed in. One address backs up the other, so a node restart never changes what the allowlist sees.

Keep the proxy URL in Edge Function secrets and hand it to Deno.createHttpClient; each fetch then leaves from your fixed address.
Two EU addresses back each other up. Add both to an allowlist once and traffic continues on the survivor if either node blinks out.
TLS passes straight through to the partner. Bearer tokens and request bodies arrive encrypted, never visible at the proxy.

Why Supabase teams route egress through OutboundGateway

Answers Supabase's own gap

The proxy approach their troubleshooting doc suggests, without renting and babysitting a VM to build one yourself.

Deno-native wiring

Built around Deno.createHttpClient, the API the edge runtime actually supports, instead of Node packages that crash on deploy.

European egress

Requests exit from EU data centres, which keeps the data-residency story you tell regulators simple.

Designed for

Teams whose Edge Functions have to look predictable to the APIs on the other end.

Fintech and payment flows

Functions that call payment processors or banking APIs where an allowlisted source address is a condition of getting credentials at all.

B2B SaaS integrations

Nightly syncs from Edge Functions into enterprise CRMs and ERMs that firewall their endpoints and onboard you by IP.

EU data-residency teams

Products that must keep personal data inside the Union and want function egress to match the rest of their EU footprint.

Agencies on Lovable and Supabase

Client projects that need to pass a security questionnaire before an enterprise integration goes live.

Implementation

One secret, one Deno HTTP client, and your fetches leave from a fixed EU address.

Deno / TypeScript (Edge Function)

Create a client with the proxy configuration and pass it to each outbound fetch.

// supabase/functions/send-data/index.ts

Deno.serve(async (req) => {
  // the proxy URL lives in Edge Function secrets
  const client = Deno.createHttpClient({
    proxy: { url: Deno.env.get('HTTPS_PROXY')! },
  });

  // this request leaves from your static EU IP
  const res = await fetch('https://api.partner.eu/data', {
    client,
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${Deno.env.get('PARTNER_TOKEN')}`,
    },
    body: JSON.stringify({ data: 'hello' }),
  });

  return new Response(await res.text());
});

Store the secret and deploy

Use the Supabase CLI to set the proxy URL as a function secret, then deploy.

# proxy URL and partner token as Edge Function secrets
supabase secrets set \
  HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443 \
  PARTNER_TOKEN=your_token

# deploy the function
supabase functions deploy send-data

# test locally with the same secret
supabase functions serve send-data --env-file ./supabase/.env.local

Allowlist both addresses, stay up through failover

Every OutboundGateway account ships with a pair of static EU addresses. Register both on each partner API: if one proxy node goes offline for maintenance, the other keeps answering and your functions never notice.

Prefer environment variables? Deno's built-in fetch also reads HTTPS_PROXY from the environment. On Supabase we recommend the explicit Deno.createHttpClient form above, because it applies per request and does not depend on startup-time environment handling.

📖 Complete Documentation: For detailed examples, error handling, and advanced configurations, see the all guides.

EU egress for function traffic

When an Edge Function forwards personal data to a partner, the path it takes matters as much as the destination.

GDPR-conscious routing

Your functions' requests exit through European data centres, so transfers to EU-hosted partners stay inside the Union from end to end.

TLS straight through

The connection to the partner is never terminated at the proxy. Authorization headers, tokens, and payload bytes stay encrypted the whole way.

What you get

A redundant IP pair

Two static EU addresses that cover for each other, so whitelisting survives a node restart.

Deno-first setup

One secret and one createHttpClient call. No Node shim, no layer, no bundler.

End-to-end encryption

TLS passthrough keeps tokens and payloads sealed past the proxy hop.

European data centres

An egress footprint that matches an EU-hosted Supabase project region for region.

Any allowlisted partner

Works uniformly across payment providers, banking APIs, CRMs, and internal enterprise endpoints.

Honest pricing

Starting from €19/month. Flexible plans for every scale. Cancel anytime.

Close the gap Supabase documents

Their troubleshooting page recommends an outbound proxy; ours ships with a redundant pair of EU addresses. Add one secret, point your fetches at it, and hand both IPs to your partner.

Starting from €19/month. Flexible plans for every scale. Cancel anytime.

Frequently asked questions

Supabase says static egress IPs aren't possible for Edge Functions. How does this work?

Their statement is about the platform itself: functions run on distributed edge infrastructure, so Supabase cannot hand you a fixed source address. What their troubleshooting doc recommends instead is routing outbound traffic through a proxy, which is precisely this product. Your function still executes wherever Supabase puts it; its requests simply leave through our two EU addresses.

Does Deno's fetch use HTTPS_PROXY inside Edge Functions?

Deno's fetch can read HTTPS_PROXY from the environment, but the dependable pattern on Supabase is explicit: build a client with Deno.createHttpClient({ proxy: { url } }) and pass it as the client option on each fetch call. It works per request, survives cold starts, and is the API Deno supports on restricted edge runtimes.

Which addresses do I put on my partner's allowlist?

Both of them. Your account includes a pair of static EU IPs, and registering the two together is what makes failover invisible: if one proxy node is briefly unavailable, the other already answers for it, so the partner never sees an unfamiliar source.

Weighing it against a self-hosted VM?

Happy to talk through whether a managed EU proxy pair fits how your Edge Functions are wired.

Contact Our Founders →