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.
Consent
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.