Passo Developers

Authentication

The OAuth 2.1 flow, the consent screen, tokens and refresh, and why an agent sees only what its human can.

Passo authenticates the user, never an app holding a shared secret. An agent or script connects, you approve it in the browser, and from then on it acts as you. There is no API key to mint, store, or rotate.

This works because Passo's authorization server is Supabase's OAuth 2.1 server. The token a client ends up with is an ordinary Supabase user session — the same kind the dashboard holds — so every read and write runs under the same row-level-security policies. That is the whole security model, and it is worth stating plainly:

An agent sees only what its human can

The token carries the user's identity. Every query a tool or endpoint runs is filtered by the same RLS policies as the dashboard, keyed on that identity. An agent cannot read a workspace you are not a member of, or change a video you could not change yourself — not by policy we remember to apply, but because the database enforces it on every row.

The flow

You rarely drive this by hand — an MCP client does it for you — but end to end it is standard OAuth 2.1 with PKCE:

Discovery

The client fetches the server's protected-resource metadata, which points it at Passo's authorization server (the Supabase project's /auth/v1). From there it reads the authorization-server metadata to find the authorization, token, and registration endpoints.

Dynamic registration

Passo has dynamic client registration enabled (RFC 7591), so a client registers itself from the server URL alone — no pre-provisioned client ID. This is what lets Claude add Passo from just the endpoint you paste in.

The client opens your browser to the Passo consent screen. It names the client requesting access and the account you are signed in as, and asks you to allow or deny. If you are not signed in, you sign in first and land back here. Approving redirects the client back with an authorization code.

Token exchange

The client exchanges the code (with its PKCE verifier) for an access token and a refresh token. The access token is a Supabase JWT carrying your user id, role, and the client id. The client sends it as Authorization: Bearer <token> on every request.

Tokens and refresh

Access tokens are short-lived — Supabase issues them with a one-hour lifetime by default. Refresh tokens are long-lived and rotate on each use. A well-behaved MCP client refreshes silently in the background, so you approve consent once and do not see it again unless you disconnect the client or revoke access.

You do not manage any of this in normal use. If you are integrating a client that does not handle OAuth for you, follow its documentation for the standard authorization-code-with-PKCE and refresh-token grants against the discovery endpoints above.

Scopes

The OAuth scopes Supabase issues — openid, email, profile, phone — control only what identity claims land in your ID token. They do not gate table access. What an agent can touch is decided entirely by RLS on your user, not by scopes. This is why read-only access is a separate MCP endpoint rather than a scope you withhold at consent.

Getting access

The MCP server is public today — connect any client by following the connection guide.

The REST API is built and documented but published on request. If you need direct HTTP access rather than MCP, get in touch and we will enable it for your account. The API reference documents every endpoint in the meantime.

API keys are deferred

OAuth covers a person connecting an agent. It does not cover a backend calling Passo from cron with no human in the loop — that needs an API key, which we have deliberately not built yet. If you need server-to-server access, tell us; it is on the roadmap with that trigger.

On this page