Native Supabase-Compatible Layer

We have exciting news for the database ecosystem! We’ve implemented a fully Supabase-compatible layer for GuardianDB.

In practice, it works as an HTTP gateway, providing the same role as Kong in the original Supabase stack, allowing the official libraries and clients (supabase-js, PostgREST clients, and GoTrue) to communicate directly with a GuardianDB node. This means your frontend applications don’t require a single line of GuardianDB-specific code.

This entire layer lives behind the supabase feature flag.

What Has Been Implemented End-to-End?

To provide a seamless experience for developers already familiar with Supabase, we’ve implemented its core services:

  • REST: Fully compatible with PostgREST.
  • Auth: GoTrue-compatible user and token management.
  • Storage: Compatible with the Supabase Storage API.
  • postgres-meta: The API that allows Supabase Studio to inspect the database.
  • Realtime: Phoenix protocol WebSockets supporting postgres_changes and broadcast.
  • GraphQL: Automatic reflection of the public schema, compatible with pg_graphql.

Any route that is not yet supported (such as the Functions service) does not return a misleading success response or an empty 404. Instead, it returns a properly typed 501 Not Implemented error.

Core Architecture and Advanced Security

The HTTP gateway processes incoming requests, validates JWT authentication through an implementation written entirely in Rust, without relying on heavyweight external dependencies, and forwards secure, parameterized commands to the database engine.

One of Supabase’s most important features is Row-Level Security (RLS), and GuardianDB provides native, integrated support:

  • Tables with RLS enabled correctly filter access for the anon, authenticated, or custom roles.
  • JWT claims are injected directly into the database session, allowing policies to use familiar helper functions such as auth.uid() and auth.role().
  • If an INSERT or UPDATE violates an RLS policy, the database correctly returns a typed 403 Forbidden error in the PostgREST response format.

Module Details

Storage: Where Your Files Live

Bucket and object metadata are stored in the storage schema, while the actual file bytes are persisted in the dedicated storage._blobs table.

As a result, uploads are persisted and replicated natively through the same Iroh network that synchronizes the rest of GuardianDB’s documents.

RLS also applies to storage buckets, allowing downloads and uploads to be restricted exclusively to the owners of the files.

postgres-meta: Bringing Supabase Studio

Since we’ve implemented pg-meta, you can connect the official Supabase Studio directly to a local GuardianDB instance running in Docker.

This gives you access to:

  • Table Editor
  • SQL Editor
  • RLS Management
  • View Explorer

Realtime and GraphQL

The Realtime WebSocket listens for local database commit events and broadcasts JSON deltas through the Phoenix protocol while always respecting the permissions of the authenticated user.

If a row is protected by RLS and the user lacks read permission, the event is simply never delivered.

GraphQL automatically reflects database tables without requiring any manual configuration, supporting cursors, pagination, filtering, and secure transactional mutations.

Getting Started

You can launch the gateway entirely in memory for development and testing with a single command:

# Starts the database and prints the credentials (URL, ANON_KEY, SERVICE_KEY)
cargo run --features supabase --bin guardian-supabase

If you’d like to start a persistent node replicated through Iroh:

cargo run --features supabase --bin guardian-supabase -- \
  --addr 127.0.0.1:54321 \
  --database app \
  --jwt-secret "your-jwt-secret-here" \
  --path ./guardian_supabase_data

On the client side, integration is immediate using the standard library:

import { createClient } from "@supabase/supabase-js";

// Connect directly to your GuardianDB node
const supabase = createClient("http://127.0.0.1:54321", ANON_KEY);

// REST queries work exactly as expected
const { data } = await supabase.from("todos").select("*").eq("done", false);

// Authentication
await supabase.auth.signUp({
  email: "dev@test.com",
  password: "secure-password",
});

What’s Next?

This compatibility layer already supports the vast majority of modern application use cases.

Our roadmap includes several additional features that currently return a typed 501 Not Implemented response:

  • Edge Functions
  • Native multipart uploads (TUS)
  • Transactional email delivery through Auth
  • Full support for replicated changefeed events

At the moment, Realtime observes only commits performed on the local node.

We invite everyone to test the integration by running the complete test suite:

cargo test --features supabase

…and experience the convenience of the Supabase API combined with the performance of GuardianDB’s Rust-native database engine.