6288fc1e
authn: accept tokens.sr.ht working tokens and PATs as bearer
The /mcp surface is bearer-only, and none of the three credential planes this service has fits an agent. ResolveBearer adds the fourth: it decodes the presented token once, locally, and routes on the ClientID — the only thing that tells a tokens.sr.ht working token from a meta.sr.ht PAT, since both are sealed with the same instance key. A working token goes through sr-ht-ecore's validator (one copy of that check for the whole instance) and carries its grants out on the result, so the surface can ask Authorize where the action is known. A PAT reuses ResolveBasic with the token's own username as the identity — there is no presented username to compare against in a bearer header — and the same TokenGrantsAllow read gate the clone path applies. An instance with no [tokens.sr.ht] section passes a nil validator: meta PATs and anonymity keep working, a working token is refused, because a machine credential this instance cannot verify is refused rather than guessed at. A failed credential is always a refusal and never a downgrade to anonymous, and backend.go's two error classes are preserved so a caller can still answer 401 against 503. core.GrantRead is the vocabulary tokens.sr.ht deliberately does not know. There is no dolt:write: nothing on that surface writes, and a grant nobody checks is a promise to an operator that no code keeps.
Eugene Blikh <bigbes@gmail.com> — 2026-08-12 20:25:32 UTC
Commit 6288fc1e6eb93ed5751f504c91b599b3058af361 —
view raw patch
Parent(s):
97e0f8a7
| File | Status | + | − |
|---|---|---|---|
authn/bearer.go
|
A | +303 | |
authn/bearer_test.go
|
A | +339 | |
core/grants.go
|
A | +23 |