Skip to content

fix(auth): disambiguate auth-denied vs missing component messages#4165

Merged
jlowin merged 1 commit into
mainfrom
claude/hardcore-bassi-bc03cd
May 20, 2026
Merged

fix(auth): disambiguate auth-denied vs missing component messages#4165
jlowin merged 1 commit into
mainfrom
claude/hardcore-bassi-bc03cd

Conversation

@strawgate
Copy link
Copy Markdown
Collaborator

When component-level auth= denies access to a tool, resource, or prompt, get_tool() / get_resource() / get_prompt() swallow the AuthorizationError and return None. AuthMiddleware then can't tell "doesn't exist" apart from "exists but you can't see it", and it picked the worst of both: it told the caller the component was not found. A user who genuinely lacks access would chase a phantom missing-tool problem, while a global-auth denial on the very same component reports "insufficient permissions" — the two paths gave contradictory stories for the same underlying cause.

This changes the three messages to not found or not authorized. The wording is deliberately ambiguous: it stops misleading authorized-but-mistaken users without disclosing the existence of components to callers who aren't allowed to see them (the anti-enumeration property some deployments rely on). The misleading inline comments claiming get_* "raises if unauthorized" are corrected to document the real None-collapsing behavior.

mcp = FastMCP(middleware=[AuthMiddleware(auth=allow_all)])

@mcp.tool(auth=require_scopes("admin"))
def secret_tool() -> str: ...

# caller without "admin" scope, before: "... secret_tool': tool not found"
# after:                                "... secret_tool': not found or not authorized"

Addresses Bug 1 of #4054. Bugs 2–4 are out of scope here (Bug 4 is handled in #4078).

@strawgate strawgate added bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. auth Related to authentication (Bearer, JWT, OAuth, WorkOS) for client or server. labels May 17, 2026
@SolvoFounder

This comment was marked as spam.

@strawgate strawgate force-pushed the claude/hardcore-bassi-bc03cd branch from a6e9d35 to 774ab2c Compare May 17, 2026 16:32
@jlowin jlowin merged commit 344a4f8 into main May 20, 2026
19 checks passed
@jlowin jlowin deleted the claude/hardcore-bassi-bc03cd branch May 20, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Related to authentication (Bearer, JWT, OAuth, WorkOS) for client or server. bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants