chadtmiller.com/knotless
git that lives in your Atmosphere account
knotless login's page fits in the browser's Referer again
MergedThis shortens the loopback login scope so the authorize URL stays under the 4,096-byte Referer limit. Space scopes name their type alone. The ~55 rpc: scopes become one rpc?lxm=…&aud=*. behind() treats a login made with the old spelled-out scope as current for SCOPE, so existing logins aren't prompted again.
I found nothing that must change. The behind rewrite keeps the old semantics: no OAuth session is never behind, and an unknown scope is behind. The spelled-out equivalence applies only when asked == SCOPE, so the gateway grant is unaffected. The new URL-length test and the updated client and behind tests cover the change. A change file is included. The test, check and e2e runs were still queued when I looked, so I didn't see them pass.
Two risks you already name:
- The multi-
lxmscope is untried on bsky.social's PDS. If that PDS doesn't parse it, it may drop allrpcaccess, which would break login-dependent calls without any error at login. Try it there before relying on it. - The URL has only modest headroom, as the body says. The hosted client ID is the lasting fix.
8 passed, 2 skipped
What changes
The login's space scopes name their type alone.
oauth::SCOPEasks forspace:dev.knotless.space?authority=*&manage=…and the same ofdev.knotless.orgSpace, without acollection=for each collection the type's lexicon lists. The PDS resolves each type's lexicon and grants those collections as it issues the token (expandSpaceCollectionsin the spaces alpha), so the grant is the same.The methods called are one scope.
rpc?lxm=dev.knotless.pushRefs&lxm=…&aud=*in place of anrpc:<method>?aud=*for each. The permission syntax allows severallxmvalues in one scope;@atproto/oauth-scopes0.5.14 parses it and matches only the methods it names.Older logins stay current.
behind()takes a login asked for the old, spelled-out form (SPELLED_OUT) as holdingSCOPE, so no one, on the command line or the pages, is asked to log in again.The gateway's grant (
gateway::SCOPE) goes through a hosted client ID and is left as it is.Why
A user logging in with
knotless loginon bsky.social got{"error":"invalid_request","error_description":"Invalid referer …"}on approving. The loopback client's ID (http://localhost?redirect_uri=…&scope=…) carries the whole scope, encoded twice in the authorize URL, which had reached 4,624 bytes. Chrome and Firefox cut a Referer longer than 4,096 bytes to its origin, and the reference PDS refuses/oauth/authorize/acceptandsign-inunless the Referer is the authorize page with itsclient_idandrequest_uri. The spelled-out space scopes from the pull that named knotless's own space types (e4810f7e, about 1,000 bytes of the URL) took it over the limit; the ~55 rpc scopes were another 2,300. The pages and MCP log in under a hosted client ID and were not affected.Shortening the space scopes alone left the URL a few methods short of the limit again; folding the rpc scopes gives it room. A hosted client ID for the command line, as the pages have, would keep the URL short however the scope grows, and is left for later.
How it was checked
login_page_url_fits_a_refererbuilds the authorize URL asauthorizedoes, on bsky.social, and fails at 4,096 bytes or more.clientchecks the new form, andsessions_behind_what_is_askedthat a spelled-out login is current forSCOPEand not for the gateway's. Against the CI-pinned alpha (11c5d98c), a bare typed space scope is expanded to its lexicon's collections at issue. The Rust tests and e2e log in over OAuth against that PDS, so CI runs real logins through the new scope.Shortcomings
Not tried in a browser against bsky.social itself before landing: the upstream parser accepts the multi-
lxmscope, but bsky.social's PDS version is not known here. A bare space scope on a PDS without spaces is dropped, as before.