Repository navigation
feat: mint the viewer's authority per consumed method, not per module - #40
Merged
AntoineToussaint merged 1 commit intoSep 26, 2026
Conversation
A consumed method may declare its own Scopes, which replace the module's for a call to that method. One module's methods that need different authority are declared under one `as`, and each call mints only its own method's scopes, so a viewer who lacks one method's authority is refused that method as permission_denied (with the issuer's reason, naming the permission) and is still served the others. Declarations that could never mint are refused at boot. A mint refusal is now a typed WorkContextRefusal that still unwraps to the GatewayError it was. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
AntoineToussaint
merged commit Sep 26, 2026
ca2fac1
into
feat/consumed-module-passthrough
1 check passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A consumed method may declare its own
Scopes(ConsumedMethod.Scopes []Scope). They replace the module'sScopesfor a call to that method — never add to them. So one module whose methods need different authority is declared under oneas, for example a member'slistand an administrator'sinspectover the same resource kind, and each call mints only its own method's authority.permission_denied. The message carries the issuer's reason, which names the missing permission (accounts answersowner is not allowed <kind>:<action> at requested scope). Every other method is still served. The mint is never widened, and never retried with less.WorkContextRefusal{Audience, StatusCode, Code, Message}. It still unwraps to*GatewayError, so existingerrors.Ascallers are unchanged. The passthrough relays a 4xx refusal in the issuer's own Connect code. Before this, a refused mint reached the page as a bareForbidden.ViewerBearermodule;ViewerBearermodule where some method has neither its own nor the module's scopes;PassthroughOperationsdocuments each method's own effective scopes.Classification: fix. The all-or-nothing mint per module made a solution choose between breaking a method for every viewer who lacks one permission and never offering it at all. The mint is decided where it is owned: the passthrough's declaration.
Base
This is stacked on #39 (
feat/consumed-module-passthrough, head8ea2cca). The passthrough (passthrough.go,ConsumedModule) exists only there, not onmain. Retarget ontomainonce #39 lands. See the repo's note on stacked PRs: CI runs only againstmain, so this PR gets no CI until it is retargeted.Host
No host change is needed. Accounts'
StartTaskWorkContextalready resolves each requestedkind:actionagainst the owner's current role assignments and refuses one it does not hold withPermissionDenied, naming it. A narrower mint is just a smaller scope list.Verified
go build ./... && go test -race ./... && go vet ./...pass (Go 1.x, this checkout).inspectmint gives 403permission_denied, the message namesthings:inspect, and the module is never called, while thelistmethod is still served with alist-only mint;Not verified
🤖 Generated with Claude Code