# Polylane agent authentication (auth.md)

How an AI agent signs up for Polylane on behalf of a user, connects their stack, and starts using it. Email signup and verification work without a TTY or browser. OAuth consent and access to the user's inbox may still need the user; pause at that step and resume rather than restarting signup.

The default setup script is an interactive human wizard. Agents use the install-only bootstrap and explicit commands below. Do not allocate a fake terminal or pipe guessed answers into the wizard. This guide follows the auth.md convention (https://workos.com/auth-md); OAuth client discovery is in the authorization-server metadata.

## 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; the current tool list, with schemas, is the server card at `https://mcp.polylane.com/.well-known/mcp/server-card.json`, published by the server itself. 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`.
- **Docs MCP server**: `https://docs.polylane.com/mcp` (Streamable HTTP). Anonymous: no credentials required.

## Pick a method

| Agent has | Method |
| --- | --- |
| An existing CLI session | Validate it with `polylane auth whoami --non-interactive`, then resume at workspace selection. |
| An existing Polylane API key | `polylane auth login --api-key "$POLYLANE_API_KEY" --non-interactive`, then validate identity and workspace. |
| The intended user's email and access to its inbox | Email signup → verification code → workspace → connections → MCP. |
| An email but no inbox access | Start email signup, ask the user for the emailed code, then resume verification. |
| An existing email/password account | Reuse the saved password with `auth signup --email "$EMAIL" --password "$PASSWORD" --non-interactive`; it also signs existing accounts in. |
| A browser-capable MCP client | Use the OAuth flow below; the account holder approves access. |
| No account, inbox, or user available | Read the anonymous docs MCP; report that authenticated setup is pending. |

Use the intended person's email, not an invented identity. Preserve another account's existing CLI configuration. Keep passwords, codes, tokens, and credential files out of project files and chat output. An existing API key must have access to the chosen workspace and the operations you need; a read-only key cannot create connections.

## 1. Install the CLI without starting the wizard

On macOS, Linux, or WSL, check for Node.js 20+ and run:

```sh
node --version
curl -fsSL 'https://polylane.com/setup?ref=agent-auth' | bash -s -- --install-only
export PATH="$HOME/.polylane/bin:$PATH"
polylane --version
```

The bootstrap verifies the release checksum and installs the CLI. It stops before agent configuration, sign-in, credential minting, and connections. Use the binary path it prints if a custom install prefix or Homebrew was used. `--no-setup` is different: it skips agent configuration but still runs the interactive sign-in wizard.

On native Windows, install with `npm install -g @coreplane/polylane` and use the same CLI flags below. The POSIX installer completion in step 5 is for macOS/Linux/WSL; on Windows use `polylane setup` and the client's OAuth flow below to authenticate MCP.

## 2. Create or resume the account

First try `polylane auth whoami --non-interactive --output json`. A valid response identifying the intended user means signup can be skipped. A file on disk or `auth status` alone is not proof that the session works.

For a new account, set `EMAIL` to the user's email. Capture both output streams privately: signup generates a strong password and prints it once, and JSON responses can include session tokens.

Show the account holder this notice before signup: **By signing up, you agree to the [Terms of Service](https://polylane.com/terms/) and acknowledge the [Privacy Policy](https://polylane.com/privacy/).**

```sh
umask 077
ONBOARDING_DIR="$(mktemp -d)"
polylane auth signup --email "$EMAIL" --non-interactive --output json > "$ONBOARDING_DIR/signup.json" 2> "$ONBOARDING_DIR/signup.log"
```

Check the exit status before continuing. Signup can print status lines around its JSON object, so do not assume the entire output file is one JSON document. Store the generated password securely from the private result; do not print the files. For an existing account use its saved password and the same private output handling, rather than generating a new one.

For a new email account, signup sends a verification email. Exit 0 at this stage does **not** mean the account is verified or the CLI is signed in. Read the latest six-digit code for this recipient and attempt using an available inbox tool, or ask the user for it. Preserve leading zeros and set `CODE` to that string:

```sh
polylane auth signup --email "$EMAIL" --code "$CODE" --non-interactive --output json > "$ONBOARDING_DIR/verification.json" 2> "$ONBOARDING_DIR/verification.log"
polylane auth whoami --non-interactive --output json
```

Verification saves the session in `~/.polylane/credentials.json` and may create or join the user's workspace according to the server's landing policy. Do not print that file. Check both commands succeeded and the identity matches; no session or a pending landing is not completed signup. Remove the temporary output files after saving any needed password in the user's credential store.

If the code expires, rerun signup with the **same saved password** to request a fresh verification code for the existing account. Use the newest email, honor rate limits, and do not repeatedly regenerate passwords or create another account. If an existing account's password is unavailable, use the console's password-reset or OAuth flow with the account holder.

For API-only agents, the same operations are `POST https://api.polylane.com/v1/auth/signup` with `{email, password}` and `POST https://api.polylane.com/v1/auth/verify_email` with `{email, code}`; both accept JSON without prior authentication. Inspect `success`, `result`, and `error` in the response and use the verified session token as a bearer credential. The CLI handles session persistence and expiry for you. Discover current request/response schemas from https://api.polylane.com/v1/doc before using the API directly.

## 3. Select the intended workspace

```sh
polylane workspace list --non-interactive --output json
polylane workspace use "$WORKSPACE_ID" --non-interactive
```

Set `WORKSPACE_ID` to the intended workspace's returned ID. A single workspace can be selected automatically by sign-in; with several workspaces the CLI deliberately leaves the choice to the caller. Resolve an ambiguous choice with the user. If none exists, inspect the signup landing result and `polylane workspace create --help`: create only the intended workspace when permitted. A verification, invitation, or capacity gate must be resolved before continuing; do not create a duplicate workspace to work around it.

## 4. Connect the user's stack

Inspect existing connections first:

```sh
polylane integration list --non-interactive --output json
polylane cloud list --non-interactive --output json
polylane integration catalog --non-interactive --output json
polylane integration connect --help
polylane cloud connect --help
```

Use the provider-specific flags with `--non-interactive`; missing inputs should be supplied explicitly. For example, an authorized Axiom token can connect without a browser. Set `AXIOM_REGION` to the organization's actual Edge deployment region from Axiom Settings → General (`us-east-1` or `eu-central-1`); supplying it explicitly also works for scoped tokens that cannot auto-detect their region:

```sh
polylane integration connect --type axiom --region "$AXIOM_REGION" --api-token "$AXIOM_API_TOKEN" --non-interactive --output json
```

For GitHub, Slack, Sentry, or another OAuth connection, the non-interactive command prints an authorization URL. For example:

```sh
polylane integration connect --type github --no-browser --non-interactive --output json
```

Give the actual returned URL to the user when consent is required. A printed URL or exit 0 is **not** evidence the connection completed: recheck `integration list` or `cloud list` after consent. Poll with a bounded wait, then report pending if it has not appeared. Reuse existing connections; do not reconnect or create duplicates just to advance setup. Add further clouds and observability tools relevant to the user's work when credentials are available.

## 5. Authenticate the coding agents and finish

On macOS/Linux/WSL, once identity, workspace, and at least one source are verified, resume the installer in the agent's non-TTY shell:

```sh
curl -fsSL 'https://polylane.com/setup?ref=agent-auth' | bash
```

It reuses the installed CLI and saved session, registers detected coding agents and skills through `polylane setup`, and authenticates their MCP entries with a workspace API key. Without a TTY it verifies existing sources rather than asking connection questions. A missing source or failed lookup stops with recovery guidance; it never loops waiting for terminal input. A source is required for completed onboarding, but a pending connection does not undo the account already created.

Restart or reload the coding agent if needed to load the MCP registration. Verify authenticated MCP access with a read through the connected client, then inspect `polylane service list --non-interactive --output json`. Connection records can precede discovered resources; an empty topology means discovery may still be running. On clients requiring manual registration, follow the setup command's guidance and use the OAuth flow below.

The installer may start the first "what should I fix first?" investigation and prints its URL. Reuse that thread if present. Report the actual workspace URL, which sources were verified, whether MCP access was tested, and anything still pending. Offer to investigate a real issue or explain the latest deploy once data is available; never claim that installation alone means the stack is connected.

## OAuth alternative: register the MCP client

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 support@polylane.com.
