Trino version
481
Please describe the bug
JWK/JWKS key fetch requests do not include a User-Agent header
Summary
When Trino fetches public keys from a JWKS endpoint — for both JWT authentication (http-server.authentication.jwt.key-file) and OAuth2 authentication (http-server.authentication.oauth2.jwks-url) — the outgoing HTTP requests do not include a User-Agent header. This causes failures with reverse proxies, WAFs, or identity providers that reject requests without a User-Agent.
Affected code paths
1. JWT authentication — JwkService.java
core/trino-main/src/main/java/io/trino/server/security/jwt/JwkService.java
private Map<String, PublicKey> fetchKeys() throws RuntimeException {
Request request = prepareGet().setUri(address).build();
StringResponse response;
try {
response = httpClient.execute(request, createStringResponseHandler());
}
// ...
}
The HTTP client is bound in JwtAuthenticatorSupportModule.java:
httpClientBinder(binder).bindHttpClient("jwk", ForJwt.class);
2. OAuth2 authentication — NimbusAirliftHttpClient.java
core/trino-main/src/main/java/io/trino/server/security/oauth2/NimbusAirliftHttpClient.java
@Override
public Resource retrieveResource(URL url) throws IOException {
try {
StringResponseHandler.StringResponse response = httpClient.execute(
prepareGet().setUri(url.toURI()).build(),
createStringResponseHandler());
return new Resource(response.getBody(), response.getHeader(CONTENT_TYPE).orElse(null));
}
// ...
}
This is used by Nimbus to fetch the JWKS endpoint during OAuth2 token validation. The HTTP client is bound in OAuth2ServiceModule.java:
httpClientBinder(binder)
.bindHttpClient("oauth2-jwk", ForOAuth2.class)
.withConfigDefaults(clientConfig -> clientConfig
.setRequestBufferSize(DataSize.of(32, KILOBYTE))
.setResponseBufferSize(DataSize.of(32, KILOBYTE)));
Root cause
Airlift's JettyHttpClient explicitly removes the default Jetty User-Agent during initialization:
airlift/http-client/src/main/java/io/airlift/http/client/jetty/JettyHttpClient.java
// remove default user agent
httpClient.setUserAgentField(null);
Since neither JwkService nor NimbusAirliftHttpClient explicitly adds a User-Agent header to their requests, and the underlying Jetty client has its default User-Agent nulled out, no User-Agent header is sent.
Impact
Any environment where the JWKS/OAuth2 endpoint is behind a reverse proxy or WAF that requires a User-Agent header (a common security policy) will fail to fetch keys, causing authentication to break entirely. This affects both JWT and OAuth2 authentication modes.
Suggested fix
Fix at the request level (minimal, targeted):
Add a User-Agent header in JwkService.fetchKeys() and NimbusAirliftHttpClient.retrieveResource():
// JwkService.java
private Map<String, PublicKey> fetchKeys() throws RuntimeException {
Request request = prepareGet()
.setUri(address)
.setHeader("User-Agent", "Trino/v481")
.build();
// ...
}
// NimbusAirliftHttpClient.java
@Override
public Resource retrieveResource(URL url) throws IOException {
try {
StringResponseHandler.StringResponse response = httpClient.execute(
prepareGet()
.setUri(url.toURI())
.setHeader("User-Agent", "Trino/v481")
.build(),
createStringResponseHandler());
// ...
}
}
Environment
- Trino version: all (verified on master as of 2026-05-29)
- Airlift version: all (the
setUserAgentField(null) has been present since the Jetty migration)
Trino version
481
Please describe the bug
JWK/JWKS key fetch requests do not include a User-Agent header
Summary
When Trino fetches public keys from a JWKS endpoint — for both JWT authentication (
http-server.authentication.jwt.key-file) and OAuth2 authentication (http-server.authentication.oauth2.jwks-url) — the outgoing HTTP requests do not include aUser-Agentheader. This causes failures with reverse proxies, WAFs, or identity providers that reject requests without a User-Agent.Affected code paths
1. JWT authentication —
JwkService.javacore/trino-main/src/main/java/io/trino/server/security/jwt/JwkService.javaThe HTTP client is bound in
JwtAuthenticatorSupportModule.java:2. OAuth2 authentication —
NimbusAirliftHttpClient.javacore/trino-main/src/main/java/io/trino/server/security/oauth2/NimbusAirliftHttpClient.javaThis is used by Nimbus to fetch the JWKS endpoint during OAuth2 token validation. The HTTP client is bound in
OAuth2ServiceModule.java:Root cause
Airlift's
JettyHttpClientexplicitly removes the default Jetty User-Agent during initialization:airlift/http-client/src/main/java/io/airlift/http/client/jetty/JettyHttpClient.javaSince neither
JwkServicenorNimbusAirliftHttpClientexplicitly adds aUser-Agentheader to their requests, and the underlying Jetty client has its default User-Agent nulled out, noUser-Agentheader is sent.Impact
Any environment where the JWKS/OAuth2 endpoint is behind a reverse proxy or WAF that requires a
User-Agentheader (a common security policy) will fail to fetch keys, causing authentication to break entirely. This affects both JWT and OAuth2 authentication modes.Suggested fix
Fix at the request level (minimal, targeted):
Add a
User-Agentheader inJwkService.fetchKeys()andNimbusAirliftHttpClient.retrieveResource():Environment
setUserAgentField(null)has been present since the Jetty migration)