# Polylane agent authentication (auth.md)

How an AI agent obtains and uses credentials for Polylane. This document follows the auth.md convention (https://workos.com/auth-md): the machine-readable `agent_auth` discovery lives in the OAuth authorization server metadata; this page is the prose walkthrough.

## Discover

Polylane exposes three agent surfaces:

- **REST API** — `https://api.polylane.com/v1`. OpenAPI 3.0 spec at `https://api.polylane.com/v1/doc` (mirrored at `https://polylane.com/openapi.json`). Security schemes: `ApiKeyAuth` (`x-api-key` header), `BearerAuth`, and `CookieAuth`.
- **MCP server** — `https://mcp.polylane.com/mcp` (Streamable HTTP). The platform over MCP: `search` and `execute` against the API, plus `searchTools`/`runTool`/`runCode` for the workspace's agent tools. Requires OAuth 2.0 or a Polylane API key. An unauthenticated request returns `401` with a `WWW-Authenticate: Bearer resource_metadata="https://mcp.polylane.com/.well-known/oauth-protected-resource/mcp"` header pointing at the RFC 9728 protected-resource metadata. RFC 8414 authorization-server metadata is at `https://mcp.polylane.com/.well-known/oauth-authorization-server`. Server card: `https://mcp.polylane.com/.well-known/mcp/server-card.json`.
- **Docs MCP server** — `https://docs.polylane.com/mcp` (Streamable HTTP). Anonymous: no credentials required.

## Pick a method

- **anonymous** — the docs MCP server needs no credential, and neither does the pre-launch waitlist (`POST https://polylane.com/api/auth/email`).
- **identity_assertion / OAuth 2.0** — the MCP server supports the standard MCP authorization flow: dynamic client registration, authorization code + PKCE, refresh tokens. The resulting bearer token also works against the REST API.
- **API key** — Polylane accounts can mint API keys (`sk_...`) in the console; send as `Authorization: Bearer sk_...` or `x-api-key` to both the REST API and the MCP server.

## Register

The authorization server supports RFC 7591 dynamic client registration. The `register_uri` is:

```
POST https://mcp.polylane.com/register
Content-Type: application/json

{"client_name": "my-agent", "redirect_uris": ["http://localhost:8976/callback"], "grant_types": ["authorization_code", "refresh_token"], "token_endpoint_auth_method": "none"}
```

The response contains your `client_id`. No pre-approval is needed.

## Claim

Run the authorization code flow with PKCE against `https://mcp.polylane.com/authorize`, then exchange the code at `https://mcp.polylane.com/token`. A human account holder approves the grant in the browser. Polylane does not yet accept cross-app identity assertions (`urn:ietf:params:oauth:token-type:id-jag`); when it does, the `identity_assertion.assertion_types_supported` list in the AS metadata will say so.

## Use the credential

Send the access token on every MCP request:

```
POST https://mcp.polylane.com/mcp
Authorization: Bearer <access_token>
```

The same credential works against the REST API:

```
GET https://api.polylane.com/v1/auth/whoami
Authorization: Bearer <access_token>
```

Tokens are workspace-scoped: an agent only sees the workspaces its authorizing user can see. Writes over the MCP server's agent tools additionally require the `x-polylane-allow-writes: true` header as a per-session opt-in.

## Errors

- `401` with `WWW-Authenticate: Bearer resource_metadata=...` — missing or expired token; restart discovery from the metadata URL.
- `401 invalid_token` — the token was revoked; re-run the flow.
- `403` — the token is valid but lacks access to the requested workspace or tool.

## Revocation

Account holders revoke agent grants and API keys in the Polylane console. Revocation is immediate: the next request returns `401`. To rotate, register a fresh client or mint a new key before revoking the old one.

## Questions

Email boris@coreplane.ai. Pre-launch: if an endpoint above rejects you unexpectedly, the waitlist (`POST https://polylane.com/api/auth/email`) is the way in.
