From 0f4885e503a633d5e78252842d8885d396ad1bab Mon Sep 17 00:00:00 2001 From: Roberto Jimenez Sanchez Date: Thu, 18 Dec 2025 10:50:54 +0100 Subject: [PATCH] Fix AccessPolicy identity detection in ST authorizer - Add check for AccessPolicy identities via GetAuthID() in authorizeRoleBasedResource - Extended JWT may set identity type to TypeUser but AuthID is 'access-policy:...' - Forward user ID token in X-Grafana-Id header in RoundTripper for aggregator forwarding --- apps/provisioning/pkg/auth/round_tripper.go | 10 ++++++++++ pkg/registry/apis/provisioning/register.go | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/apps/provisioning/pkg/auth/round_tripper.go b/apps/provisioning/pkg/auth/round_tripper.go index f5da0d778f0..535dda9bb88 100644 --- a/apps/provisioning/pkg/auth/round_tripper.go +++ b/apps/provisioning/pkg/auth/round_tripper.go @@ -66,6 +66,8 @@ func NewRoundTripper(tokenExchangeClient tokenExchanger, base http.RoundTripper, // RoundTrip exchanges credentials for an access token and injects it into the request. // The token is scoped to all configured audiences and the wildcard namespace ("*"). +// If a user identity is present in the request context, its ID token is forwarded +// in the X-Grafana-Id header so aggregators can forward it to MT API servers. func (t *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { audiences := []string{t.audience} if t.extraAudience != "" && t.extraAudience != t.audience { @@ -82,5 +84,13 @@ func (t *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { req = utilnet.CloneRequest(req) req.Header.Set("X-Access-Token", "Bearer "+tokenResponse.Token) + + // Forward user ID token from context if present, so aggregators can forward it to MT + if requester, err := identity.GetRequester(req.Context()); err == nil && requester != nil { + if idToken := requester.GetIDToken(); idToken != "" { + req.Header.Set("X-Grafana-Id", idToken) + } + } + return t.transport.RoundTrip(req) } diff --git a/pkg/registry/apis/provisioning/register.go b/pkg/registry/apis/provisioning/register.go index e116dfcd8cf..fa895b3e733 100644 --- a/pkg/registry/apis/provisioning/register.go +++ b/pkg/registry/apis/provisioning/register.go @@ -520,6 +520,10 @@ func authorizeRoleBasedResource(ctx context.Context, resource string, id identit if authInfo, ok := authlib.AuthInfoFrom(ctx); ok { isAccessPolicy = authlib.IsIdentityType(authInfo.GetIdentityType(), authlib.TypeAccessPolicy) } + // Also check AuthID for AccessPolicy identities (Extended JWT may set TypeUser but AuthID is "access-policy:...") + if !isAccessPolicy && id.GetAuthID() != "" { + isAccessPolicy = strings.HasPrefix(id.GetAuthID(), "access-policy:") + } } switch resource {