-
Notifications
You must be signed in to change notification settings - Fork 337
Support JWT Profile for Authorization Grant (RFC 7523 3.1) #862
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
Conversation
Signed-off-by: Jorge Turrado <[email protected]>
Signed-off-by: Jorge Turrado <[email protected]>
Signed-off-by: Jorge Turrado <[email protected]>
jkroepke
left a comment
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.
One question before we start the deeper review: What was the reason for using github.com/golang-jwt/jwt/v5 instead of golang.org/x/oauth2/jwt? Is it really necessary to define custom algorithms, or could we just rely on RS256 as golang.org/x/oauth2 does?
Background: I’m asking because the common library is shared across the whole Prometheus ecosystem including exporters, and we should be careful about which dependencies we pull in.
Similar to the UUID dependency used for the jti claim. As far as I know, jti is optional and not required when the JWT is short-lived.
|
Nice questions! I didn't think about the radius blast of adding new dependencies at core. The problem that I see is that
Although RS256 is the most common signing alg, there are auth providers which don't support it because they require RS512 as minimum (and eventually, there can be servers requesting other alg than RS but I guess that this is more overthinking because RS is accepted almost everywhere) About
So it's also on authorization server the option to enforce the value if it's verified. Said this,
The biggest problem that I see is the signature methods hardcoded to RS256. RS384 and RS512 are the same method with different lengths and for enterprise authorization servers, increasing the length is mandatory. About |
Signed-off-by: Jorge Turrado <[email protected]>
|
I didn't notice it but prometheus is also using |
Signed-off-by: Jorge Turrado <[email protected]>
|
Tested locally against STACKIT API package main
import (
"fmt"
"io"
"net/http"
"time"
"github.com/prometheus/common/config"
)
func main() {
httpConfig := config.HTTPClientConfig{
OAuth2: &config.OAuth2{
GrantType: "urn:ietf:params:oauth:grant-type:jwt-bearer",
ClientID: "f9355e72-eada-4ed7-9e16-d5b52e9cfdf4",
ClientCertificateKeyFile: "/Users/jok/Documents/stackit.key",
ClientCertificateKeyID: "f9355e72-eada-4ed7-9e16-d5b52e9cfdf4",
SignatureAltgorithm: "RS512",
Scopes: []string{},
TokenURL: "https://service-account.api.stackit.cloud/token",
Audience: "https://stackit-service-account-prod.apps.01.cf.eu01.stackit.cloud",
Iss: "[email protected]",
EndpointParams: map[string]string{"hi": "hello"},
Claims: map[string]interface{}{
"sub": "3ba4a9e6-724a-437f-ae81-c311fca4e194",
},
},
}
if err := httpConfig.Validate(); err != nil {
panic(err)
}
rt, err := config.NewRoundTripperFromConfig(httpConfig, "my-agent")
if err != nil {
panic(err)
}
client := http.Client{
Transport: rt,
}
for {
fmt.Printf("Making request... %s\n", time.Now().String())
resp, err := client.Get("https://resource-manager.api.stackit.cloud/v2/projects?limit=50&[email protected]&offset=0")
if err != nil {
panic(err)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
resp.Body.Close()
fmt.Println("Response status:", resp.Status)
fmt.Println("Body:", string(body))
time.Sleep(time.Minute * 5)
}
}It works over a hour, refresh a token should work as well. @JorTurFer Could you confirm that refreshing works on your side as well? |
|
And it confirm that the upstream |
|
As per indirect dep spread, I think we are safe from client_golang perspective for this particular package (config) as per: https://cloud-native.slack.com/archives/C01AUBA4PFE/p1762179354393169?thread_ts=1762169496.875849&cid=C01AUBA4PFE |
For sure, let me keep it running for a long time too.
I'm going to update client_golang with this specific branch and I'll check too |
I can confirm it too, the refresh works as expected |
jkroepke
left a comment
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.
LGTM
|

This PR implements JWT Authentication for Authorization Grant (RFC 7523 3.1) as alternative to static client credentials.
As usage example, this auth flow is used by STACKIT Service Accounts (Key Flow).
Note: This PR does not provide support for JWTs in Client Authentication Processing, but I can include it if you think that it's worth or I can add it as another PR following this