2026-04-28·13 min read·

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:

ComponentTechnologySupabase Layer
DatabasePostgreSQL 15+Managed, per-project instance
AuthenticationGoTrue (forked)JWT-based Auth service
File StorageS3-compatible APIBuilt on AWS S3 (EU region: eu-central-1)
RealtimeElixir Phoenix ChannelsWebSocket subscriptions to DB changes
Edge FunctionsDeno DeployJavaScript/TypeScript at edge
Vectorpgvector extensionAI/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:

What the DPA does not cover:

Component-Level GDPR Risk

Authentication (GoTrue)

Supabase Auth stores:

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

FeatureSupabase (EU region)NhostSelf-hosted SupabasePocketbaseDirectus
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/moFree–$25/moVPS 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:

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:

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:

The Practical Reality

Many European startups and developer teams are using Supabase in production with EU users. The practical enforcement risk varies significantly by:

  1. Data sensitivity: A dev tool storing GitHub repository metadata has much lower enforcement risk than a healthcare app storing patient records.

  2. 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.

  3. 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.

  4. 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

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.