Supabase EU Alternative 2026: GDPR, CLOUD Act, and the BaaS Jurisdiction Problem
Post #673 in the sota.io EU Compliance Series
Supabase is one of the most popular Backend-as-a-Service (BaaS) platforms for developers. It bundles a managed Postgres database, authentication, file storage, realtime subscriptions, and Edge Functions into a single platform. For developers who want to move fast without managing backend infrastructure, Supabase is compelling.
Supabase has an EU region in Frankfurt. It has a GDPR Data Processing Agreement. It has SOC 2 Type II certification. On the surface, it appears GDPR-compliant.
The problem is not the Frankfurt datacenter. The problem is what the Frankfurt datacenter runs on and who owns it.
Supabase Inc. is a US corporation incorporated in San Francisco, California. Its infrastructure runs on Amazon Web Services — another US corporation. The CLOUD Act (18 U.S.C. § 2713) applies to both. Under this statute, the US government can compel Supabase to produce data stored on its Frankfurt servers, and Supabase can compel AWS to assist, regardless of what the GDPR says about transfers to third countries.
There is a second structural issue specific to Supabase's architecture. Unlike a pure managed Postgres provider, Supabase bundles authentication, storage, and realtime into a single platform. Each of these components processes EU user data. Each component is owned by a US entity on US-owned infrastructure. The CLOUD Act exposure is not limited to database rows — it extends to auth tokens, user sessions, file metadata, and function invocations.
This post analyses Supabase's GDPR and CLOUD Act exposure in full, evaluates what their DPA actually covers, examines each product component's risk profile, and provides a complete comparison of EU-native alternatives.
What Supabase Actually Is
Before the compliance analysis, it is worth understanding what Supabase bundles:
| Component | Technology | Supabase Layer |
|---|---|---|
| Database | PostgreSQL 15+ | Managed, per-project instance |
| Authentication | GoTrue (forked) | JWT-based Auth service |
| File Storage | S3-compatible API | Built on AWS S3 (EU region: eu-central-1) |
| Realtime | Elixir Phoenix Channels | WebSocket subscriptions to DB changes |
| Edge Functions | Deno Deploy | JavaScript/TypeScript at edge |
| Vector | pgvector extension | AI/ML embeddings in Postgres |
Each component is deeply integrated. Your auth JWT contains user IDs referenced in your database. Your storage objects are linked to auth users. Your realtime subscriptions filter by row-level security policies tied to auth sessions. This integration is the product's appeal — and it is also the compliance surface.
The Jurisdiction Stack
When you deploy to Supabase's EU region, the actual infrastructure chain is:
Your EU User
↓ (HTTPS)
Supabase EU Frankfurt
↓ (runs on)
AWS eu-central-1 (Frankfurt)
↓ (owned by)
Amazon.com Inc. (Seattle, WA, USA) — CLOUD Act subject
↑
Supabase Inc. (San Francisco, CA, USA) — CLOUD Act subject
Both companies in this chain are US entities. Under CLOUD Act § 2713(a), US persons must preserve and disclose the contents of wire or electronic communications stored regardless of geographic location. "Supabase stores your data in Frankfurt" does not exempt it from this statute. The CLOUD Act was passed precisely to close the argument that offshore storage circumvents US legal process.
A valid US legal order directed at Supabase Inc. can compel production of Frankfurt-stored data. Supabase can challenge such an order under CLOUD Act § 2703(d) provisions, but the GDPR does not override US federal statute — the challenge would be on US procedural grounds, not EU privacy grounds.
GDPR DPA Analysis
Supabase offers a Data Processing Agreement that covers:
- Data controller/processor relationship: You are the controller, Supabase is the processor ✓
- Processing purposes: Defined as operating the platform services ✓
- Sub-processors list: AWS (US), Cloudflare (US), GitHub (US), Vercel (US) ✓ (disclosed)
- SCCs: Standard Contractual Clauses for EU→US transfers included ✓
- Data residency: EU region stores data within EU-Central-1 Frankfurt ✓
What the DPA does not cover:
- CLOUD Act override: SCCs cannot override US statute. The CJEU's Schrems II ruling (C-311/18) established that SCCs are insufficient when the recipient country's laws undermine their effectiveness. US CLOUD Act compulsion falls in this category.
- AWS sub-processor: Supabase's DPA binds Supabase Inc., but AWS operates under its own DPA. Your data has a US-company processing chain regardless of the contractual framework.
- Support access: Supabase support staff (US-based employees) can access project data for debugging purposes. This is disclosed in their DPA but represents a direct transfer to US persons.
Component-Level GDPR Risk
Authentication (GoTrue)
Supabase Auth stores:
- Email addresses of registered users
- Encrypted passwords (bcrypt) or OAuth provider tokens
- Session tokens (JWTs)
- Phone numbers (if SMS auth enabled)
- Identity provider tokens (Google, GitHub, etc.)
Risk: Auth data is personally identifiable. EU users' email addresses and identity tokens stored in Supabase Auth are accessible to US legal process. If you use Google OAuth through Supabase, you have Google AND Supabase AND AWS in your US-entity chain.
GDPR Article 9 consideration: If your app stores health, political, or sensitive data and links it to Supabase Auth user IDs, that linkage makes the Auth data subject to stricter processing requirements.
Database (PostgreSQL)
Supabase Postgres runs as isolated per-project instances on AWS infrastructure. Row-Level Security (RLS) is applied at the PostgreSQL level.
Risk: The database is the most direct CLOUD Act exposure point. All user-generated data stored in Postgres — regardless of RLS policies — is accessible via the underlying AWS storage layer in response to legal compulsion. RLS is an application-level control, not a legal jurisdiction control.
Connection pooling: Supabase uses PgBouncer/Supavisor for connection pooling. Pool connections traverse Supabase's control plane, adding another US-entity processing layer beyond the database itself.
Storage
Supabase Storage is built on AWS S3. EU region storage uses S3 bucket in eu-central-1.
Risk: S3 buckets owned by a US entity (through Supabase's AWS account) are directly subject to CLOUD Act compulsion via both Supabase and Amazon. This is a double exposure: US government can compel either Supabase Inc. or Amazon.com Inc.
File metadata (filenames, sizes, MIME types, user associations) is stored in Supabase's metadata database — adding a third layer of US-entity exposure for storage objects.
Edge Functions
Supabase Edge Functions run on Deno Deploy (owned by Deno Land Inc., a US company). Functions execute globally, not constrained to your EU region selection.
Risk: If your Edge Functions process personal data — validating tokens, transforming user records, calling external APIs — that processing occurs on US-company infrastructure outside your EU region selection. This is a data transfer risk that the EU region selection does not address.
Realtime
Supabase Realtime uses an Elixir Phoenix Channels server to deliver database change events over WebSocket.
Risk: Realtime events contain database row data. If rows contain personal data, that data transits through Supabase's Realtime infrastructure — US-company owned, not covered by the EU region's data residency guarantees.
Python: SupabaseComplianceChecker
from dataclasses import dataclass, field
from enum import Enum
from typing import List
class RiskLevel(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
@dataclass
class ComplianceFinding:
component: str
risk_level: RiskLevel
finding: str
gdpr_articles: List[str]
recommendation: str
class SupabaseComplianceChecker:
"""
Evaluates GDPR compliance posture for a Supabase-based application.
Identifies CLOUD Act exposure and recommends EU-native alternatives.
"""
def __init__(
self,
uses_auth: bool = True,
uses_storage: bool = False,
uses_edge_functions: bool = False,
uses_realtime: bool = False,
stores_sensitive_data: bool = False,
eu_users_only: bool = True,
):
self.uses_auth = uses_auth
self.uses_storage = uses_storage
self.uses_edge_functions = uses_edge_functions
self.uses_realtime = uses_realtime
self.stores_sensitive_data = stores_sensitive_data
self.eu_users_only = eu_users_only
def check(self) -> List[ComplianceFinding]:
findings = []
# Base CLOUD Act exposure — always present
findings.append(ComplianceFinding(
component="Platform",
risk_level=RiskLevel.HIGH,
finding=(
"Supabase Inc. is a US corporation on AWS infrastructure. "
"Both entities are CLOUD Act subjects. EU region selection "
"does not exempt data from US legal process."
),
gdpr_articles=["Art. 44", "Art. 46", "Art. 49"],
recommendation=(
"For CLOUD Act-free Postgres, use Neon EU (Netherlands) or "
"managed Postgres on Hetzner/OVH. "
"For full BaaS replacement: Nhost (EU-native) or self-hosted Supabase."
),
))
if self.uses_auth:
findings.append(ComplianceFinding(
component="Auth (GoTrue)",
risk_level=RiskLevel.HIGH,
finding=(
"User email addresses, session tokens, and OAuth provider tokens "
"are stored in Supabase Auth — US-entity owned, CLOUD Act accessible."
),
gdpr_articles=["Art. 5(1)(f)", "Art. 32", "Art. 44"],
recommendation=(
"Replace with Keycloak (self-hosted, EU VPS) or "
"Ory Hydra + Kratos (open source, EU deployable). "
"Nhost includes EU-native auth."
),
))
if self.uses_storage:
findings.append(ComplianceFinding(
component="Storage (S3/AWS)",
risk_level=RiskLevel.CRITICAL,
finding=(
"Supabase Storage is built on AWS S3 (eu-central-1). "
"Double CLOUD Act exposure: US government can compel "
"Supabase Inc. AND Amazon.com Inc. independently."
),
gdpr_articles=["Art. 44", "Art. 32", "Art. 83"],
recommendation=(
"Replace with MinIO on EU VPS, Hetzner Object Storage "
"(Frankfurt), or OVH Object Storage. "
"All are EU-jurisdiction S3-compatible APIs."
),
))
if self.uses_edge_functions:
findings.append(ComplianceFinding(
component="Edge Functions (Deno Deploy)",
risk_level=RiskLevel.HIGH,
finding=(
"Edge Functions run on Deno Deploy (US company). "
"Functions execute globally — not constrained to EU region. "
"Personal data processed in functions transits US-company infrastructure."
),
gdpr_articles=["Art. 44", "Art. 5(1)(a)"],
recommendation=(
"Move business logic to application server on EU VPS "
"(Hetzner, OVH, or sota.io managed PaaS). "
"EU-deployed Cloudflare Workers are not EU-entity owned — "
"Cloudflare Inc. is also a US company."
),
))
if self.uses_realtime:
findings.append(ComplianceFinding(
component="Realtime (Phoenix Channels)",
risk_level=RiskLevel.MEDIUM,
finding=(
"Database change events delivered via Realtime contain row data. "
"If rows contain PII, that PII transits Supabase Realtime "
"infrastructure outside EU region data residency guarantees."
),
gdpr_articles=["Art. 5(1)(f)", "Art. 32"],
recommendation=(
"Implement realtime via WebSocket from EU-hosted application "
"server (e.g. Elixir/Phoenix on Hetzner) reading from "
"EU-jurisdiction Postgres via LISTEN/NOTIFY."
),
))
if self.stores_sensitive_data:
findings.append(ComplianceFinding(
component="Database (Sensitive Data)",
risk_level=RiskLevel.CRITICAL,
finding=(
"Application stores sensitive data (GDPR Art. 9 categories) "
"in Supabase Postgres. Art. 9 requires explicit consent AND "
"higher technical/organisational measures. CLOUD Act exposure "
"of Art. 9 data is a severe enforcement risk."
),
gdpr_articles=["Art. 9", "Art. 32", "Art. 83(5)"],
recommendation=(
"Art. 9 data MUST be in EU-jurisdiction infrastructure. "
"Use Postgres on Hetzner dedicated server (Germany) with "
"encryption at rest (LUKS) + application-level encryption. "
"DPO consultation required before processing."
),
))
return findings
def risk_summary(self) -> dict:
findings = self.check()
counts = {level: 0 for level in RiskLevel}
for f in findings:
counts[f.risk_level] += 1
return {
"total_findings": len(findings),
"critical": counts[RiskLevel.CRITICAL],
"high": counts[RiskLevel.HIGH],
"medium": counts[RiskLevel.MEDIUM],
"low": counts[RiskLevel.LOW],
"compliant_for_eu_production": counts[RiskLevel.CRITICAL] == 0,
}
# Example usage
checker = SupabaseComplianceChecker(
uses_auth=True,
uses_storage=True,
uses_edge_functions=False,
uses_realtime=False,
stores_sensitive_data=False,
)
summary = checker.risk_summary()
print(f"Total findings: {summary['total_findings']}")
print(f"Critical: {summary['critical']}, High: {summary['high']}")
print(f"EU production ready: {summary['compliant_for_eu_production']}")
EU-Native Supabase Alternatives
| Feature | Supabase (EU region) | Nhost | Self-hosted Supabase | Pocketbase | Directus |
|---|---|---|---|---|---|
| Postgres | ✅ AWS eu-central-1 | ✅ EU-native (Hetzner) | ✅ Your EU VPS | ❌ (SQLite/Postgres) | ✅ Your EU VPS |
| Authentication | ✅ GoTrue (US entity) | ✅ Hasura Auth (EU) | ✅ GoTrue (your server) | ✅ Built-in | ✅ Built-in |
| Storage | ✅ AWS S3 (US entity) | ✅ MinIO on Hetzner | ✅ MinIO (your server) | ✅ Local/S3 | ✅ Local/S3 |
| Realtime | ✅ Phoenix (US entity) | ✅ Hasura subscriptions | ✅ Your server | ✅ Built-in SSE | ✅ WebSockets |
| Edge Functions | ✅ Deno Deploy (US) | ❌ | ❌ | ❌ | ❌ |
| GraphQL | ❌ | ✅ Hasura (EU) | ❌ | ❌ | ✅ |
| EU Entity | ❌ US corporation | ✅ EU-deployable | ✅ Your infra | ✅ Your infra | ✅ Your infra |
| CLOUD Act free | ❌ | ✅ (on EU VPS) | ✅ (on EU VPS) | ✅ (on EU VPS) | ✅ (on EU VPS) |
| Managed PaaS | ✅ | ✅ (nhost.run) | ❌ | ❌ | ❌ |
| Cost (starter) | Free–$25/mo | Free–$25/mo | VPS cost (~€5/mo) | VPS cost (~€5/mo) | VPS cost (~€5/mo) |
Nhost (EU-Native Managed BaaS)
Nhost is the closest EU-native equivalent to Supabase:
- Postgres (managed, deployable to EU regions via Hetzner/OVH infrastructure)
- Hasura GraphQL engine (open source, EU-deployable)
- Auth via nhost-auth (open source, your data)
- Storage via nhost-storage (MinIO-based)
- Cloud functions via Nhost's serverless (deployable to EU)
Nhost's hosted platform (nhost.run) uses AWS us-east-1 by default for management plane — check their DPA for EU-region options. For full EU sovereignty, self-host on Hetzner.
Self-Hosted Supabase on EU VPS
Supabase publishes a Docker Compose stack. Running it on a Hetzner or OVH VPS in Germany or France eliminates the CLOUD Act exposure entirely:
# Clone Supabase self-hosting
git clone --depth 1 https://github.com/supabase/supabase
cd supabase/docker
# Copy and configure
cp .env.example .env
# Edit: POSTGRES_PASSWORD, JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY, SITE_URL
# Start (EU VPS, Hetzner Frankfurt)
docker compose up -d
# Verify
docker compose ps
The full self-hosted stack (Postgres + GoTrue + PostgREST + Realtime + Storage + Studio) requires approximately 2GB RAM and 20GB storage. A Hetzner CPX21 (3 vCPU, 4GB RAM, €8.21/mo) is sufficient for moderate workloads.
When self-hosted on an EU VPS owned by you (not Supabase Inc. or AWS), the CLOUD Act no longer applies. The processing chain is: EU User → Your EU VPS → Postgres on Your EU VPS. All entities in the chain are EU-jurisdiction.
Pocketbase
For smaller applications where Postgres is not required:
- Single binary (Go), runs on any Linux VPS
- Built-in auth, file storage, realtime (SSE)
- SQLite or external Postgres backend
- Admin UI included
- No external dependencies, no US-entity processing
A Pocketbase instance on a Hetzner CX22 (€3.92/mo) handles thousands of users with zero CLOUD Act exposure.
The SaaS-to-PaaS Migration Pattern
For teams currently using Supabase managed and wanting to migrate to EU-sovereign infrastructure, the migration path is:
Current stack:
Supabase Managed (Frankfurt region)
→ AWS eu-central-1 (Amazon.com Inc.)
→ Supabase Inc.
Migration path:
1. Export: pg_dump from Supabase Postgres
2. Import: pg_restore to Hetzner/OVH Postgres
3. Auth: Export users via Supabase Admin API → import to Keycloak/GoTrue self-hosted
4. Storage: aws s3 sync from Supabase storage → MinIO on EU VPS
5. Update: Connection strings in your application
6. Deploy: Application on EU-native PaaS (sota.io, Scaleway, OVH)
The database migration typically takes under an hour for databases under 10GB. Auth migration requires a password reset flow (hashed passwords cannot be migrated — users set new passwords at next login). Storage migration is a straight file copy.
GDPR Compliance Checklist for Supabase Users
Before deploying to Supabase in production with EU user data:
- Read Supabase's Data Processing Agreement (available in dashboard under Settings → Legal)
- Document all sub-processors in your GDPR Records of Processing Activities (Art. 30)
- Assess CLOUD Act risk against your data sensitivity — is it tolerable for your use case?
- Verify your DPA covers all regions you use (EU region only, or global CDN?)
- Check Edge Functions — are they enabled? If yes, disable or ensure no PII processing
- Verify Realtime is disabled or personal-data-free if EU sovereignty is required
- If storing Art. 9 data (health, political, biometric) — Supabase is not appropriate
- If using Supabase Auth, ensure your privacy policy discloses US sub-processing
- Implement client-side encryption for high-sensitivity fields (encrypt before sending to Supabase)
- Review Supabase support access policies — support staff CAN access project data
- Check if your sector has specific requirements (healthcare: HIPAA/DSGVO, finance: DORA/MiFID)
- Test EU region selection — confirm pg_show_all_settings() location is Frankfurt
- Document your decision rationale for using a US-entity BaaS (required under GDPR accountability)
- Set up database backups to EU-jurisdiction storage (not Supabase's managed backups on AWS)
- Establish a data breach response plan that accounts for Supabase's breach notification timelines
The Practical Reality
Many European startups and developer teams are using Supabase in production with EU users. The practical enforcement risk varies significantly by:
-
Data sensitivity: A dev tool storing GitHub repository metadata has much lower enforcement risk than a healthcare app storing patient records.
-
Company size: Data protection authorities typically focus enforcement on systematic violations and large-scale processing. A startup with 500 users faces different risk than a company with 50,000.
-
Sector: Financial services (DORA), healthcare (GDPR Art. 9 + sector laws), and government contractors face mandatory compliance requirements that Supabase's CLOUD Act exposure genuinely blocks.
-
Customer contracts: B2B SaaS selling to enterprise EU customers will face DPA reviews that flag Supabase's US-entity status. Enterprise procurement teams frequently require EU-jurisdiction processing.
The CLOUD Act risk is real and structural — it cannot be resolved by contractual means. The question is whether that risk is acceptable for your specific application, data type, and customer base.
For developers who need CLOUD Act-free infrastructure from day one, the EU-native options above provide the same developer experience without the jurisdiction problem.
See Also
- Managed Postgres in Europe: EU Hosting and GDPR Compliance Guide
- Google Cloud Platform EU Alternative 2026: GDPR, CLOUD Act, and the Google Analytics Precedent
- AWS European Sovereign Cloud: Why It Does Not Solve the CLOUD Act Problem
- GDPR Article 44: General Principle for Transfers — What EU Developers Need to Know
EU-Native Hosting
Ready to move to EU-sovereign infrastructure?
sota.io is a German-hosted PaaS — no CLOUD Act exposure, no US jurisdiction, full GDPR compliance by design. Deploy your first app in minutes.