Skip to content

Feature/supabase integration - #1

Merged
savrcbl merged 4 commits into
masterfrom
feature/Supabase-integration
Sep 15, 2026
Merged

savrcbl merged 4 commits into
masterfrom
feature/Supabase-integration

Conversation

@savrcbl

@savrcbl savrcbl commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Summary

Adds Supabase as a supported database source, via two paths:

  1. PostgreSQL provider (direct connection) — Supabase's database is a real Postgres instance, so the existing PostgreSQL provider now also accepts a postgresql://user:pass@host:port/db URI (e.g. Supabase's own connection string) in addition to the classic Host=...;Port=...; keyword format. Full schema browsing via normal pg_catalog introspection, no API keys involved.
  2. New Supabase provider (REST/PostgREST-based) — talks to Supabase's auto-generated REST API instead of the database directly, for cases where a direct DB connection isn't available or desired.

What changed

New provider

  • DataProviders/Supabase/ — SupabaseDatabaseProvider, SupabaseDatabaseConnection, SupabaseQueryService, SupabaseConnectionInfo
  • DatabaseProviderType.Supabase added to the enum; registered in App.xaml.cs DI alongside the other providers — no other wiring needed, the provider dropdown builds itself from DI registrations

PostgreSQL provider

  • PostgreSqlConnectionStringNormalizer — detects a postgres:///postgresql:// prefix and converts it to an NpgsqlConnectionStringBuilder string before use, so a pasted Supabase (or any) Postgres URI just works
  • ConnectionStringPlaceholder updated to mention the URI form is accepted

UI (MainWindow.xaml / MainViewModel.cs)

  • Selecting "Supabase" swaps the single connection-string box for two boxes (Project URL, API Key) — both read/write into the same underlying ConnectionString (Url=...;ApiKey=...;), so saved connections and the connect flow are unaffected
  • Live inline warning (red text) if a sb_publishable_... key is pasted into the API Key box — Supabase blocks that key tier from schema introspection at the platform level, so it needs to fail loudly and immediately rather than only on Connect
  • Query editor placeholder/hint text switches for Supabase connections to describe RPC-call syntax instead of SQL

Query editor for Supabase

  • PostgREST has no raw-SQL endpoint, so ExecuteQueryAsync on the Supabase provider instead calls a Postgres function (RPC) by name: my_function or my_function {"arg": 1}
  • Handles array, single-object, and scalar function results, all rendered into the same grid
  • Errors surface Postgrest's actual JSON message field rather than a generic HTTP failure

Docs

  • README.md: new "Connecting to Supabase" section covering both paths, with an explicit warning about the secret key (see below); Supabase added to feature list, connection string table, project structure tree, and Known limitations

Why two paths, and why the REST one needs a secret key

Supabase's REST API only exposes schema introspection (/rest/v1/ OpenAPI spec) to the secret key, not the publishable/anon key — a publishable key connects fine but can't list tables/columns, by design on Supabase's end, not a bug here. The app now makes this explicit instead of silently failing: the connect error, the textbox warning, and the README all say secret-key-required.

The PostgreSQL path (Option 1) is the one to recommend when a direct DB connection is available, since it avoids the API-key/permission-tier question entirely.

⚠️ Security considerations (please read before merging)

The Supabase secret key is not equivalent to a scoped database login. It bypasses Row Level Security entirely and has full administrative access to every table in the project. A leaked SQL Server/Postgres password exposes one database with whatever permissions that login has; a leaked Supabase secret key exposes the entire project.

Mitigations already in place:

  • Saved connections (including this key) are encrypted at rest via Windows DPAPI, same as every other provider's saved credentials
  • README calls this out explicitly with a [!WARNING] callout, separate from the general security notes
  • UI never echoes the key anywhere except the input box itself (no logging of ConnectionString)

Worth a second opinion from reviewers: is DPAPI-at-rest + inline warnings sufficient here, or do we want something stronger (e.g. a confirmation dialog on first paste of a sb_secret_...-prefixed value) before this ships?

Testing done

  • Connected via Supabase provider using both publishable and secret keys — confirmed publishable key connects but shows the "needs secret key" state, secret key shows full table/column tree
  • Verified postgres:// URI pasted into the PostgreSQL provider connects and browses schema identically to the keyword format
  • Ran RPC query editor against a function with no args, a function with JSON args, and a function returning a scalar — all rendered correctly
  • Tested malformed JSON args in the query editor — fails with a clear message instead of an unhandled exception
  • Confirmed the two-textbox Supabase UI doesn't fight the binding (typing doesn't get reset mid-keystroke — this was a real bug caught and fixed during development)

Known follow-ups (not blocking, not in this PR)

  • Supabase provider only sees the public schema and can't distinguish views from tables (both come from the same OpenAPI spec)
  • No raw-SQL execution against Supabase — RPC only, since PostgREST doesn't expose one
  • Could add a "known tables" typed mode using the official Supabase/Supabase.Postgrest NuGet package for users who want compile-time models for specific tables, but that doesn't fit the app's dynamic-schema-discovery model as a replacement for the current approach

Updated connection string to require Supabase secret key instead of publishable key.
SupabaseQueryService now supports executing Postgres function (RPC) calls via Supabase REST by parsing input and sending POST requests to the RPC endpoint.
@savrcbl
savrcbl merged commit 276b7d3 into master Sep 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant