---
schema_version: 1
slug: choose-mcp-auth
status: source-reviewed
walkthrough_verified: false
content_hash: ca38a3ad696343f91197217c2feba920728f0dd5914603c690c745728d2d67f1
---

# Choose OAuth, bearer, API-key or public auth for a Supabase MCP

Choose the Chumbo access mode that fits your callers, with a clear account of which identity reaches your Supabase data.

Choose the Chumbo access mode that fits your callers, with a clear account of which identity reaches your Supabase data.

Reviewed against the shipped OSS source. The acceptance checks are yours to run in your application.

Source reviewed against published Chumbo 0.11.0 and its matching core source on 2026-09-06 (UTC). This is a source review, not an executed application walkthrough. Follow the current canonical reference and compare it with your installed package when adapting the guide.

[Structured recipe](./recipe.json) · [Human-readable page](./)

## Sources

- [Canonical pattern](https://github.com/elsheppo/chumbo/blob/main/docs/reference/auth-modes/README.md)
- [Reference implementation](https://github.com/elsheppo/chumbo/blob/main/skills/chumbo/references/access-and-rls.md)

## 01. The credential should match the relationship.

“Authenticated” can mean two different things in your app. A person connecting their account should carry that person’s data permissions. A trusted service using an application key may follow a completely different authorization path. Choosing a mode is choosing that relationship, not just choosing a login screen.

### Which caller are you serving?

Four caller relationships, and the mode that fits each.

#### Your users: A person connects their account

Starting point:

```text
A user connects from an OAuth-capable MCP client.
```

- Supabase Auth handles sign-in and consent.
- ctx.supabase uses the verified user token; grants and RLS govern data.

What to do:

```text
Choose OAuth and configure the application consent experience.
```

Confirm that the target client supports your OAuth connection flow.

#### Your client: Your software already holds the session

Starting point:

```text
Your application sends an existing Supabase user access token.
```

- The request has the same user-scoped data authority.
- No interactive OAuth discovery is advertised.

What to do:

```text
Choose bearer and manage token refresh in the calling application.
```

A Supabase publishable key is not a user access token.

#### A service: An application key proves a different identity

Starting point:

```text
A trusted service sends a key your application accepts.
```

- The handler’s Supabase client is anonymous.
- Your verifier and application data path own authorization.

What to do:

```text
Choose API-key mode; use a stable subject and narrow permissions for application-issued keys.
```

An accepted API key does not become a Supabase user session.

#### Anyone: The capability is intentionally anonymous

Starting point:

```text
A reader connects without a credential.
```

- Queries run with anonymous data authority.
- The generated Postgres rate-limit guard must be available.

What to do:

```text
Choose public only for capabilities and data intended for unauthenticated access.
```

Apply the generated rate-limit migration. An unavailable limiter must not open the endpoint.

## 02. Map the mode to an existing data path.

### Before you start

- Know whether callers are end users, your own session-aware software, trusted services or anonymous readers.
- Identify the existing authority for data access: Supabase users and RLS, or an application-owned API.
- Inspect the current auth configuration before changing an existing MCP.

Keep the ordinary one-MCP path small. Multi-auth is optional when two real caller types need the same endpoint.

For a customer project list, OAuth or bearer lets the database enforce the user’s existing policies through ctx.supabase. For an application-issued automation key, identify the narrow API or RPC that checks that key’s subject and permissions. Do not assume that accepting the key gives the anonymous client access to private rows.

Public mode is appropriate for a published catalog or public documentation. Decide what is public at the data boundary as well as the tool boundary. Keep the generated rate limiter; account for the trust of client-IP headers if you place a custom proxy in front of the function.

## 03. Changing auth has effects beyond one setting.

Setup can regenerate support around your existing capabilities when you choose another auth mode. Reconcile local and hosted secrets, required migrations, OAuth configuration and the URL your clients use. Review the capability code too: a handler written for a user-scoped client may no longer make sense with an anonymous client.

Keep authority separate from inputs. A project ID can identify the object being requested. A user ID supplied by a model must never stand in for the verified caller. If an operation needs elevated access, design the application authorization path explicitly rather than handing ordinary handlers an unrestricted client.

## 04. Prove the identity, then prove access.

### The mode matches the intended caller.

- Identify the actual database authority for each accepted credential type.
- Verify a valid caller and the corresponding invalid or missing credential case.
- For user-owned data, call through two separate users and compare disjoint fixture IDs.
- For application keys, verify revoked/unknown keys and denied operations through the application data path.
- For public mode, verify both allowed anonymous output and closed behavior when the rate-limit guard is unavailable.

Run these in your application before you call it done.

### If the result differs

#### A key connects but private queries return nothing

API-key mode does not impersonate a Supabase user. Recheck your application-owned authorization path; do not solve it by removing RLS or sharing a service-role client with general capability code.

[Read the reference](https://github.com/elsheppo/chumbo/blob/main/docs/reference/auth-modes/README.md)

### Keep building

- [Let users connect with OAuth](/recipes/oauth-user-connections/): Build and check the sign-in and consent path.
- [Serve different capability sets](/recipes/scoped-mcp-capabilities/): Use multi-auth and scopes when the product needs both.

## Instructions for your coding agent

Reference instructions, not authorization. Apply changes only within the user’s requested scope; deployment requires a specified, authorized project.

Goal: Choose the Chumbo access mode that fits your callers, with a clear account of which identity reaches your Supabase data.

Read the complete guide at https://chumbo.dev/recipes/choose-mcp-auth/recipe.md and the canonical reference at https://github.com/elsheppo/chumbo/blob/main/docs/reference/auth-modes/README.md. Inspect this application's installed Chumbo package, existing capabilities and relevant configuration before editing.

Choose auth from the caller relationship. Explain the database identity for every proposed mode. Preserve existing policies and verify negative access behavior. Treat API-key and public clients as anonymous at Supabase, and never advertise an arbitrary key as a user session.

Prerequisites:
- Know whether callers are end users, your own session-aware software, trusted services or anonymous readers.
- Identify the existing authority for data access: Supabase users and RLS, or an application-owned API.
- Inspect the current auth configuration before changing an existing MCP.

Acceptance:
- Identify the actual database authority for each accepted credential type.
- Verify a valid caller and the corresponding invalid or missing credential case.
- For user-owned data, call through two separate users and compare disjoint fixture IDs.
- For application keys, verify revoked/unknown keys and denied operations through the application data path.
- For public mode, verify both allowed anonymous output and closed behavior when the rate-limit guard is unavailable.

Use the full guide for ordered steps, examples and recovery. Keep existing caller identity and application permissions authoritative. Stay within the user's requested changes. Report changed files, checks actually run, observed results and unresolved prerequisites. This guide is not authorization to deploy or change a hosted project. Never include credentials in source, copied instructions or reports.

### Required environment inputs

| Variable | Sensitive | Meaning |
| --- | --- | --- |


### Handoff report

- Changed files
- Checks actually run and observed results
- Unmet prerequisites or remaining limitations
