Securing the Supabase Studio Dashboard for Self-Hosted Supabase

Self-hosted Supabase Studio ships with a single shared basic-auth login and full database access. Here's how to lock it down properly.

Cover Image for Securing the Supabase Studio Dashboard for Self-Hosted Supabase

When you spin up a self-hosted Supabase instance, the Studio dashboard is the friendly face of the whole stack: table editor, SQL runner, auth user management, storage browser. It's also, by default, one of the weakest links in your deployment. Studio ships protected by nothing more than a single shared HTTP basic-auth credential—no MFA, no per-user accounts, no login audit trail—while giving whoever gets through it full read/write access to your production database.

This guide covers why the default Studio setup is risky, the mistakes that expose it to the internet, and a layered approach to locking it down without making your own life miserable.

Why the Default Studio Setup Is a Problem

On the Supabase Cloud platform, the dashboard is gated behind your Supabase account, organization roles, and 2FA. Self-hosting throws all of that away. The Docker setup protects Studio with HTTP basic auth via two environment variables in your .env file:

DASHBOARD_USERNAME=supabase
DASHBOARD_PASSWORD=this-is-a-shared-secret

That's the entire access control model. A few things to sit with:

  • It's one credential for everyone. Your CTO, your contractor, and the intern all share the same username and password. When the contractor leaves, your only option is to rotate the secret and redistribute it to everyone else.
  • There's no MFA. Basic auth is a username and password sent on every request. If it leaks—in a screenshot, a .env committed to git, a shoulder-surf—there's no second factor to save you.
  • There's no audit trail. Studio doesn't record who logged in or which destructive query ran. Every action looks identical because every action is the same account.
  • The blast radius is total. Studio talks to your database with elevated privileges. Anyone past the login can drop tables, read every row regardless of Row Level Security, edit auth users, and browse storage buckets.

Basic auth over HTTPS is genuinely fine as one layer. The problem is treating it as the only layer for a panel this powerful.

The Exposure Mistakes That Bite People

Most Studio incidents aren't sophisticated attacks—they're misconfigurations. The recurring ones:

Publishing the wrong ports. A default docker-compose.yml maps Studio (port 3000) and the Kong/Envoy gateway (port 8000) to the host. If your server has a public IP and no firewall, http://your-server-ip:8000 serves the dashboard to the entire internet. Bots scan for exactly this. Only your reverse proxy's 443 should ever face the public.

Weak or default passwords. DASHBOARD_PASSWORD=password is depressingly common, often because the variable got skipped during a rushed install. Note also the quirk worth knowing: the password must contain at least one letter—numbers-only values silently break the login.

Leaking the Envoy admin port. If you run the newer Envoy gateway, its admin interface on 127.0.0.1:9901 exposes a /config_dump endpoint that includes the fully rendered config—including the basic-auth hash in plaintext. Never publish port 9901 to other containers or the host.

Trusting the LAN. "It's only on my private network" stops being true the moment you add a VPN gateway, a misconfigured Docker network, or a teammate's compromised laptop. Treat Studio as internet-facing even when it isn't.

A good starting point is a deny-by-default firewall—covered in depth in our network security guide—so that ports 3000, 8000, 5432, and 9901 are closed to everything except your reverse proxy and admin IPs.

Layer 1: Put Studio Behind a Reverse Proxy

Never expose Studio directly. Front it with Nginx, Caddy, or Traefik terminating TLS, so the dashboard is only reachable over HTTPS on a hostname you control. A minimal Caddy example:

studio.yourdomain.com {
    # Optional: restrict to known admin IPs
    @blocked not remote_ip 203.0.113.10 198.51.100.0/24
    respond @blocked "Forbidden" 403

    reverse_proxy localhost:8000
}

This buys you real TLS certificates and a single, well-understood entry point. If you're configuring custom hostnames and certificates for the first time, our custom domains setup guide walks through the DNS and SSL pieces.

Layer 2: Restrict Who Can Reach It At All

The cheapest, most effective control is to make Studio unreachable for everyone who shouldn't have it. Pick the option that matches your team:

  • IP allowlisting. If your admins have static IPs (office, home, jump box), allow only those at the firewall or proxy, as in the Caddy snippet above. Everyone else gets a 403 before authentication even happens.
  • A private overlay network. Tools like Tailscale or WireGuard let you bind Studio to a private interface so it's only resolvable inside your mesh. This is the gold standard for small teams: the dashboard simply doesn't exist on the public internet.
  • A bastion/SSH tunnel. Keep Studio bound to 127.0.0.1 and reach it with ssh -L 3000:localhost:8000 user@server. Zero public exposure, no extra services, ideal for solo operators.

If a route works for you here, you've eliminated the entire population of opportunistic scanners in one move.

Layer 3: Add Real Authentication In Front

For teams that need several people in Studio without sharing one password, put a proper identity layer ahead of basic auth. Forward-auth proxies like Authelia, Authentik, or oauth2-proxy sit between your reverse proxy and Studio and enforce per-user logins, MFA, and session policies—features Studio itself will never grow on its own.

The pattern with Authelia and Caddy looks like this:

studio.yourdomain.com {
    forward_auth authelia:9091 {
        uri /api/authz/forward-auth
        copy_headers Remote-User Remote-Groups
    }
    reverse_proxy localhost:8000
}

Now access requires an individual Authelia account with TOTP or WebAuthn, and you get a login audit trail for free. When someone leaves, you disable their user—no shared-secret rotation, no redistribution. This pairs naturally with the broader practices in our production hardening guide.

Layer 4: Reduce the Blast Radius

Defense in depth means assuming a layer fails. Two habits that limit the damage:

Don't run Studio in production unless you need it. Studio is an administrative convenience, not a runtime dependency. Your application talks to the API gateway and database directly. If you only use the dashboard for occasional admin work, consider keeping it stopped and starting it on demand, or running it only against staging.

Rotate secrets when people change. The basic-auth credential, your JWT secret, and your service-role key should all be treated as rotatable. Pair Studio access controls with sound JWT and session security so a leaked dashboard password doesn't also mean leaked API keys.

A Practical Checklist

Before you call your dashboard secure, confirm:

  • [ ] DASHBOARD_USERNAME and DASHBOARD_PASSWORD are strong and unique (and not in git)
  • [ ] Ports 3000, 8000, 5432, 6543, and 9901 are closed to the public internet
  • [ ] Studio is reachable only via HTTPS through a reverse proxy
  • [ ] Access is restricted by IP allowlist, VPN, or SSH tunnel
  • [ ] A forward-auth layer (Authelia/Authentik/oauth2-proxy) provides per-user MFA for teams
  • [ ] Studio is disabled or staging-only in production where practical
  • [ ] Secrets are rotated when team members leave

How Supascale Helps

Wiring up a reverse proxy, TLS, firewall rules, and a forward-auth gateway by hand is exactly the kind of fiddly, error-prone work that turns "I'll self-host" into a weekend you don't get back. Supascale handles the infrastructure layer for you: deployments sit behind managed reverse proxying with automatic SSL on your custom domains, services are exposed deliberately rather than dumped onto public ports, and you manage everything through an authenticated control panel instead of a shared basic-auth box. You still own your data and your servers—there's no vendor lock-in—but you skip the part where a forgotten port mapping exposes your database to the internet.

It's a one-time $39.99 purchase for unlimited projects, which you can compare against the ongoing cost of doing all of this manually on our pricing page.

Conclusion

The self-hosted Supabase Studio dashboard is powerful and, out of the box, under-protected: one shared password, no MFA, no audit log, and total database access for anyone who gets in. The fix isn't a single setting—it's layers. Close the ports, force everything through a reverse proxy, restrict who can reach it, add per-user authentication for teams, and shrink the blast radius by not running Studio where you don't need it.

Get those layers in place and the dashboard goes from "biggest liability in the stack" to a tool you can actually trust. Ready to skip the manual plumbing? Get started with Supascale.

Further Reading