Introducing AnonRouter Connect

Published
6 min read

Connected apps is live. An app can now sign you in with your AnonRouter account and run inference against your balance, without ever holding your API key and without learning who you are.

The problem with pasting a key

Today, an app that wants to use your router account asks you to generate an API key, paste it into a settings field, and hope. That key is your entire account: every workspace you own, the whole balance, and no ceiling specific to the app you handed it to. Cutting the app off means rotating the key, which breaks every other integration using it.

Connected apps replaces that with a grant you approve, cap, and revoke on its own. AnonRouter Connect is an OAuth 2.1 and OpenID Connect provider, so the flow is the familiar one: the app sends you to AnonRouter, you approve on our domain, the app receives tokens. What differs is how little those tokens carry.

What the app receives

A grant has exactly two scopes, openid and inference, and that is the complete list. Connect implements no profile scope and no email scope, so there is nothing of that kind for an app to ask for.

The identifier the app gets back is pairwise. It is derived from the app's hostname and your account, so two different apps receive two different identifiers for the same person. Each one works as that app's private account key, and none of them work as a way for two apps to compare notes and discover they are talking to the same user. Registered accounts and private accounts resolve through the same path, so which kind you hold does not change what the app sees.

Nothing else crosses the boundary. An authorized app cannot read:

  • your name, email address, or internal account ID
  • your balance, billing records, or payment methods
  • your recovery phrase, or any way to trigger a reset
  • your API keys, either to read them or to create new ones
  • your other workspaces, account settings, or sessions

A workspace of its own, and a ceiling

Approving an app does not hand it one of your existing workspaces to sit inside. Connect creates a dedicated workspace bound to that one app, names it after the app, and every request the app makes lands there. Your usage page separates its spend from your own without you configuring anything. Authorizing the same app again later reuses that workspace and creates a fresh grant.

The consent screen is where you set the lifetime spending cap and an optional expiry in days. The cap counts completed spend plus the cost reserved for requests still in flight, and Connect checks it with the grant locked, so a burst of parallel requests cannot race past the ceiling you set.

Why the app's token never sees your prompt

Delegated inference runs as two calls instead of one. The app presents its Connect token to request a ticket: content-free, short-lived, single-use, and bound to the model and limits it asked for. Then it sends the actual prompt with the ticket and without the token.

# 1. The app's Connect token buys a ticket. No prompt yet.
curl https://anonrouter.ai/api/anonrouter/v1/inference/tickets \
  -H "Authorization: Bearer $ANONROUTER_CONNECT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model": "/auto", "operation": "chat", "max_tokens": 512}'

# 2. The ticket carries the prompt. No Connect token on this call.
curl https://anonrouter.ai/api/anonrouter/v1/chat/completions \
  -H "x-anonrouter-ticket: $ANONROUTER_TICKET" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "/auto",
    "max_tokens": 512,
    "messages": [{"role": "user", "content": "Hello"}]
  }'

The split means the credential that identifies the app and authorizes spending is never attached to the request that carries your text. It is the same ticketed path our own Chat workspace uses, so delegated inference gets the same treatment as every other request: we hold the prompt in memory while the model serves it and let it go when the response finishes. Billing settles from token counts and a timestamp.

Registering an app

You do not need to talk to us first. Open Connected apps, scroll to Your apps, and select Create New App. You give it a display name, one or more exact redirect URIs, and optionally a Privacy Policy and Terms URL, which we show to users during authorization. The client secret appears once at creation. An account can run up to ten enabled apps, each with between one and twenty redirect URIs, and every URI on one app has to share a hostname, because that hostname is what defines the pairwise identity boundary.

Connect configuration
Issuer           https://anonrouter.ai/api/anonrouter/connect
Discovery        <issuer>/.well-known/openid-configuration
Scopes           openid inference
Response type    code
PKCE method      S256
Client auth      client_secret_basic
Resource base    https://anonrouter.ai/api/anonrouter

Use a maintained OpenID Connect library rather than assembling the protocol by hand, and read the endpoints out of the discovery document instead of hard-coding paths. Connect is for confidential clients only. If your app is a browser SPA or a mobile binary, the exchange and the token storage have to sit behind a server you control, since a secret shipped to a browser is not a secret. Access tokens last 15 minutes. Refresh tokens last 30 days and rotate on every use, and presenting one that has already been spent revokes the whole token family along with the grant behind it.

There is a working example in the repository. npm run demo:connect-chat brings up a small full-stack chat app that signs in through Connect and streams completions through delegated inference, with the client secret and both tokens staying on its server.

Turning an app off

The Connected apps table lists every authorization with its workspace, scopes, approved cap, spend so far, and last use. Disconnect kills the access and refresh tokens immediately. The workspace and its history stay on your account, so disconnecting an app does not erase your own record of what it spent.

Signing out of AnonRouter is not the same as disconnecting, and we kept those lifecycles separate on purpose so that closing a browser tab does not quietly break a running integration. A few events do revoke grants on your behalf: password recovery, account disablement, deleting the app, rotating its secret, and changing its redirects or hostname.

The authorization flow, the registration rules, and the delegated inference API are documented in full at docs.anonrouter.ai/connected-apps.

Keep reading

Your prompts are not our business.

Create account
Introducing AnonRouter Connect - AnonRouter