> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veroreceipts.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> How the Vero MCP Server authenticates users with OAuth 2.0 and Auth0

The Vero MCP Server uses **OAuth 2.0 Authorization Code** flow with **Auth0** as the identity provider. MCP clients that support OAuth handle this automatically — users just log in when prompted.

***

## How authentication works

<Steps>
  <Step title="Client requests /mcp">
    The MCP client sends an initial request to `/mcp` without a token. The server responds with `401 Unauthorized` and a `WWW-Authenticate` header containing a link to the protected resource metadata.

    ```http theme={null}
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Bearer realm="mcp", resource_metadata="https://mcp.veroreceipts.com/.well-known/oauth-protected-resource"
    ```
  </Step>

  <Step title="Client discovers OAuth metadata">
    The client fetches the protected resource metadata (RFC 9728), which points to the authorization server. It then fetches the authorization server metadata (RFC 8414) to learn the OAuth endpoints.
  </Step>

  <Step title="Dynamic client registration">
    The client registers itself via the `/oauth/register` endpoint (RFC 7591) and receives a `client_id`.
  </Step>

  <Step title="User authorizes">
    The client redirects the user to `/oauth/authorize`, which proxies to Auth0's authorization endpoint. The user logs in (or signs up) and grants access. Auth0 redirects back with an authorization code.
  </Step>

  <Step title="Token exchange">
    The client sends the authorization code to `/oauth/token`, which proxies to Auth0's token endpoint and injects the client secret. The client receives an access token.
  </Step>

  <Step title="Authenticated requests">
    All subsequent requests to `/mcp` include the access token as a Bearer token. The server validates it and forwards it to the Vero API.
  </Step>
</Steps>

***

## OAuth endpoints

The server implements the following OAuth-related endpoints:

| Endpoint                                  | RFC                                                       | Purpose                                                                               |
| ----------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `/.well-known/oauth-protected-resource`   | [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) | Protected Resource Metadata — tells the client where to find the authorization server |
| `/.well-known/oauth-authorization-server` | [RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414) | Authorization Server Metadata — lists supported endpoints, scopes, and grant types    |
| `/oauth/register`                         | [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) | Dynamic Client Registration — returns the pre-configured `client_id`                  |
| `/oauth/authorize`                        |                                                           | Authorization proxy — injects OIDC scopes and redirects to Auth0                      |
| `/oauth/callback`                         |                                                           | Callback proxy — forwards the authorization code to the MCP client                    |
| `/oauth/token`                            |                                                           | Token proxy — injects the client secret and forwards to Auth0                         |

***

## Token validation

The server supports two token validation strategies depending on configuration:

<Tabs>
  <Tab title="JWT (recommended)">
    When an Auth0 API audience is configured, tokens are signed JWTs. The server validates them locally:

    1. Fetches the JSON Web Key Set (JWKS) from Auth0
    2. Caches keys for 5 minutes
    3. Verifies the JWT signature (RSA)
    4. Validates the issuer (`iss`), expiration (`exp`), and audience (`aud`) claims

    This is faster because it doesn't require a network call per request.
  </Tab>

  <Tab title="Opaque tokens">
    When no audience is configured, tokens are opaque. The server validates them by calling Auth0's `/userinfo` endpoint on every request.

    This is simpler to set up but adds latency to each request.
  </Tab>
</Tabs>

***

## Scopes

The server requests the following OAuth scopes during authorization:

| Scope            | Purpose                                        |
| ---------------- | ---------------------------------------------- |
| `openid`         | Required for OIDC — enables ID token issuance  |
| `profile`        | Access to user's name and nickname             |
| `email`          | Access to user's email address                 |
| `offline_access` | Enables refresh tokens for long-lived sessions |

***

## Token flow through the system

Once authenticated, the user's Bearer token flows through the entire system:

```
MCP Client
  │ Bearer token
  ▼
Vero MCP Server ──validates──▶ Auth0 (JWKS or /userinfo)
  │ Same Bearer token
  ▼
Vero API (plaid-wrapper) ──validates──▶ Auth0
  │
  ▼
Plaid / Gmail / OCR services
```

The MCP server does not mint its own tokens. It validates the Auth0 token and passes it through to the Vero API, which performs its own independent validation.

***

## PKCE support

The authorization server metadata advertises support for `S256` code challenge method (PKCE). MCP clients that implement PKCE will use it automatically for added security during the authorization code exchange.
