How I built keyless OAuth sign‑in for my AI companion
Description and use
Implemented a keyless OAuth sign‑in using PKCE and a single‑use loopback callback, ensuring no client secret or token is stored on disk while authenticating the Ankita desktop app with Composio’s MCP server.
Problem
The MCP server only accepts a Bearer token from the standard OAuth flow, rejecting API keys and client secrets, so the AI companion needed a keyless sign‑in that never stores a client secret or token on disk.
Outcome
A fully keyless OAuth sign‑in that never writes secrets to disk, uses a single‑use loopback callback, and passes all 12 unit tests, including handling denied authorizations and missing tokens.
Workflow
- Discover MCP endpoints
- Register client dynamically with token_endpoint_auth_method="none"
- Open user browser to authorize URL with PKCE and state
- Listen on 127.0.0.1:5757 for single‑use loopback callback
- Exchange code for token using PKCE verifier and resource indicator
- Store grant metadata on disk and token in OS keychain
- Close loopback listener after success or timeout
Evidence
The only credential it accepts is a Bearer minted by the standard MCP OAuth flow.
The redirect URI is a loopback listener on 127.0.0.1 that lives only for the duration of one sign‑in (RFC 8252).
Dynamic client registration sends token_endpoint_auth_method: "none" — no client secret is issued or stored, ever.
The token never leaves the vault. The grant file on disk holds no secret — just grantId, the endpoint, the connected apps, and timestamps. The actual token goes to the OS keychain through the injected secret store.
The full connect flow runs against injected fetch and URL opening in the test suite — 12 tests, all green, including "a denied authorization fails the connect instead of hanging" and "a token endpoint that returns no token is an error, not an empty grant".
- Record date: 2026-10-15T11:55:58.616Z