-
Notifications
You must be signed in to change notification settings - Fork 276
fix(auth): require audience when introspecting via Google tokeninfo #6236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3075,3 +3075,30 @@ func TestEnsureJWKSRegistered_NonFatalRegistrationErrors(t *testing.T) { | |
| require.True(t, validator.jwksRegistered) | ||
| }) | ||
| } | ||
|
|
||
| func TestNewTokenValidator_GoogleTokeninfoRequiresAudience(t *testing.T) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional style nit: this reads fine as-is, but since it's really one test with two input variants (empty vs set audience), our testing rules lean toward table-driven for this shape rather than two sequential imperative blocks. Up to you whether it's worth the churn for two cases. |
||
| t.Setenv("TOOLHIVE_SKIP_OIDC_DISCOVERY", "true") | ||
|
|
||
| // Google tokeninfo + no audience must be rejected at startup: tokeninfo | ||
| // returns no iss claim (the provider synthesises it locally), so an | ||
| // issuer check is self-satisfying and the audience check is the only | ||
| // binding to this deployment. Without it, any valid Google access token | ||
| // passes regardless of which OAuth client minted it. | ||
| _, err := NewTokenValidator(context.Background(), TokenValidatorConfig{ | ||
| Issuer: "https://accounts.google.com", | ||
| JWKSURL: "https://www.googleapis.com/oauth2/v3/certs", | ||
| IntrospectionURL: GoogleTokeninfoURL, | ||
| Audience: "", | ||
| }) | ||
| require.Error(t, err) | ||
| require.Contains(t, err.Error(), "audience is required") | ||
|
|
||
| // With an audience configured, the same setup must be accepted. | ||
| _, err = NewTokenValidator(context.Background(), TokenValidatorConfig{ | ||
| Issuer: "https://accounts.google.com", | ||
| JWKSURL: "https://www.googleapis.com/oauth2/v3/certs", | ||
| IntrospectionURL: GoogleTokeninfoURL, | ||
| Audience: "my-client-id.apps.googleusercontent.com", | ||
| }) | ||
| require.NoError(t, err) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: this only catches a literally empty audience. If someone sets it to
" "by accident (bad env templating etc.) it'd sail past this check, then fail every single token at runtime instead of failing loudly at startup. Might be worth trimming, same as the issuer check does elsewhere:Optional, not blocking.