feat: authenticate as an OAuth resource server against mcp-auth #3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "oauth-resource-server"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
babash on a public port is an unauthenticated root shell — anyone who reaches
it can call
babash_initializeand get one.chat_idisolates conversationsfrom each other, but it is a value the model carries, not a secret, so it keeps
no stranger out.
This makes babash a resource server in the fleet's existing OAuth: it
validates tokens and serves tools,
mcp-authmints them. No/authorize,/tokenor client registration lives here — passing the SDK only atoken_verifiermounts the resource-server half and leaves the rest unmounted.That absence is load-bearing: advertising a registration endpoint we cannot
serve would send compliant clients into it, and they abandon the flow rather
than fall back.
Two gates, for two different jobs
serve a whole fleet: a token minted for websearch carries
websearchandwill not open a shell here.
verify_token. A scope cannot say who you are,since anyone who can log in may ask for one. The per-service licence is the
record that names a person and can be withdrawn from one without disturbing
anyone else.
A caller holding no
babashlicence is refused at verification, before thereis a tool to call. Paid siblings do the opposite — admit the caller, refuse the
tool with a note about buying — which is right for something a stranger is
meant to buy into, and wrong for a root shell, where nothing is for sale.
Metadata at the bare well-known path too
Not only at the RFC 9728 §3.1 path the 401 points at. Some clients probe the
bare one first and read a 404 as "no OAuth here" — and more concretely, the
nginx in front of this proxies discovery to the upstream's bare path:
so without it discovery 404s in the deployment this is for. It is built by the
same SDK call from the same three values, so there is one document, not a copy
free to drift.
Off by default
Auth is on exactly when
MCP_AUTH_URLis set, so stdio and local dev areunchanged. Set without
PUBLIC_URL, the server refuses to start rather thanserve on a resource URL it invented — one clients would pin against and then be
unable to reach.
Verification
112 passed(96 before, no regressions) — 16 new tests covering the200 + nulltrap, the licence gate's fail-closed directions, an unreachableissuer, the 401 challenge, metadata at both paths, and that no AS endpoint is
advertised.
mypy --strict src/babashclean,ruff checkclean.⚠️ Deployment ordering — issue the licence first
The licence gate means enabling auth before issuing yourself a
babashlicencelocks you out of babash-remote. Correct order, in
andyjazzy.cloud:mcp_auth: addbabashtomcp_auth_extra_scopes+ prefixbabash: BB, redeploybabashlicence and bind it on the mcp-auth login formMCP_AUTH_URL,PUBLIC_URL=https://raidmen.ru/mcp-servers/babash,REQUIRED_SCOPE=babashnginx.yml: babashneeds_oauth: false→truedocker pullon raidmen, redeploy🤖 Generated with Claude Code