fix(auth): two-tier 401 distinguishing bad Bearer scheme from key failure#106
Merged
Conversation
…lure HTTP authMiddleware and gRPC unary interceptor collapsed both the bad/missing Bearer scheme case and the key-validation failure case into a bare Unauthorized / codes.Unauthenticated. Callers pasting a raw cav7_ key without the "Bearer " prefix got a generic 401 with no hint. Split into two tiers on both surfaces: - Bearer-scheme problem (ParseBearerToken returns empty): name the expected format. HTTP body "Unauthorized: expected 'Authorization: Bearer <key>' header"; gRPC codes.Unauthenticated with mirrored message. gRPC unifies the missing-metadata / missing-header / empty-token branches here. - Key-validation failure (token present, ValidateApiKey nil/err): keep the generic message, leaking nothing about key existence/expiry/scopes. ParseBearerToken unchanged (empty-return contract intact). Adds gateway auth_test.go (no prior coverage) and grpc interceptor cases exercising both 401 branches on both surfaces. Closes #99 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Closes #99
Splits the bare
Unauthorized/codes.Unauthenticatedinto two tiers on both auth surfaces:ParseBearerToken): 401 body names the expected format —Unauthorized: expected 'Authorization: Bearer <key>' header(gRPC mirrors withcodes.Unauthenticated+ metadata-accurate wording).ValidateApiKeynil/err): genericUnauthorized— no leak about key existence/expiry/scopes.ParseBearerTokenunchanged (contract is fine — fix is caller-side reaction). HTTP + gRPC kept consistent in spirit.Tests
servers/gateway/auth_test.go(gateway had no test file): 5 cases across both 401 branches.servers/grpc/auth_test.go: +3 cases (no header, raw-key-no-prefix → names Bearer; bad key → generic no-leak).Gate
build ✅ ·
go test ./...✅ ·buf lint+buf breaking --against develop✅ · auth local-stack smoke pending pre-land.🤖 Generated with Claude Code