K8s: namespace mapper should use authlib's util (#92332)

pull/92545/head
Charandas 9 months ago committed by GitHub
parent f9719d4ee9
commit af2e79aa83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      go.mod
  2. 12
      go.sum
  3. 2
      go.work.sum
  4. 4
      pkg/apimachinery/go.mod
  5. 8
      pkg/apimachinery/go.sum
  6. 4
      pkg/apimachinery/identity/wrapper.go
  7. 2
      pkg/apiserver/go.mod
  8. 4
      pkg/apiserver/go.sum
  9. 9
      pkg/services/apiserver/endpoints/request/namespace.go
  10. 7
      pkg/services/apiserver/endpoints/request/namespace_test.go
  11. 62
      pkg/services/authn/clients/ext_jwt.go
  12. 145
      pkg/services/authn/clients/ext_jwt_test.go
  13. 5
      pkg/services/authz/client.go
  14. 4
      pkg/storage/unified/apistore/go.mod
  15. 8
      pkg/storage/unified/apistore/go.sum
  16. 4
      pkg/storage/unified/resource/go.mod
  17. 8
      pkg/storage/unified/resource/go.sum
  18. 4
      pkg/storage/unified/resource/grpc/authenticator.go

@ -74,9 +74,9 @@ require (
github.com/googleapis/gax-go/v2 v2.13.0 // @grafana/grafana-backend-group github.com/googleapis/gax-go/v2 v2.13.0 // @grafana/grafana-backend-group
github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group
github.com/gorilla/websocket v1.5.0 // @grafana/grafana-app-platform-squad github.com/gorilla/websocket v1.5.0 // @grafana/grafana-app-platform-squad
github.com/grafana/alerting v0.0.0-20240827075410-70248a7a3a67 // @grafana/alerting-backend github.com/grafana/alerting v0.0.0-20240822131459-9daa6239cc41 // @grafana/alerting-backend
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db // @grafana/identity-access-team github.com/grafana/authlib v0.0.0-20240827201526-24af227df935 // @grafana/identity-access-team
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db // @grafana/identity-access-team github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd // @grafana/identity-access-team
github.com/grafana/codejen v0.0.3 // @grafana/dataviz-squad github.com/grafana/codejen v0.0.3 // @grafana/dataviz-squad
github.com/grafana/cuetsy v0.1.11 // @grafana/grafana-as-code github.com/grafana/cuetsy v0.1.11 // @grafana/grafana-as-code
github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics

@ -2246,12 +2246,12 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grafana/alerting v0.0.0-20240827075410-70248a7a3a67 h1:3spByRvTR3Qo7uDCEVVLB7+5VYH1q4hxwqVLdNpcS6k= github.com/grafana/alerting v0.0.0-20240822131459-9daa6239cc41 h1:p+UsX43BoDH5YlG6xUd9xDS3M4sWouy8VJ+ODv5S6uE=
github.com/grafana/alerting v0.0.0-20240827075410-70248a7a3a67/go.mod h1:GMLi6d09Xqo96fCVUjNk//rcjP5NKEdjOzfWIffD5r4= github.com/grafana/alerting v0.0.0-20240822131459-9daa6239cc41/go.mod h1:GMLi6d09Xqo96fCVUjNk//rcjP5NKEdjOzfWIffD5r4=
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db h1:z++X4DdoX+aNlZNT1ZY4cykiFay4+f077pa0AG48SGg= github.com/grafana/authlib v0.0.0-20240827201526-24af227df935 h1:nT4UY61s2flsiLkU2jDqtqFhOLwqh355+8ZhnavKoMQ=
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db/go.mod h1:ptt910z9KFfpVSIbSbXvTRR7tS19mxD7EtmVbbJi/WE= github.com/grafana/authlib v0.0.0-20240827201526-24af227df935/go.mod h1:ER7bMzNNWTN/5Zl3pwqfgS6XEhcanjrvL7lOp8Ow6oc=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd h1:sIlR7n38/MnZvX2qxDEszywXdI5soCwQ78aTDSARvus=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
github.com/grafana/codejen v0.0.3 h1:tAWxoTUuhgmEqxJPOLtJoxlPBbMULFwKFOcRsPRPXDw= github.com/grafana/codejen v0.0.3 h1:tAWxoTUuhgmEqxJPOLtJoxlPBbMULFwKFOcRsPRPXDw=
github.com/grafana/codejen v0.0.3/go.mod h1:zmwwM/DRyQB7pfuBjTWII3CWtxcXh8LTwAYGfDfpR6s= github.com/grafana/codejen v0.0.3/go.mod h1:zmwwM/DRyQB7pfuBjTWII3CWtxcXh8LTwAYGfDfpR6s=
github.com/grafana/cue v0.0.0-20230926092038-971951014e3f h1:TmYAMnqg3d5KYEAaT6PtTguL2GjLfvr6wnAX8Azw6tQ= github.com/grafana/cue v0.0.0-20230926092038-971951014e3f h1:TmYAMnqg3d5KYEAaT6PtTguL2GjLfvr6wnAX8Azw6tQ=

@ -714,6 +714,8 @@ github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/grafana/authlib v0.0.0-20240730122259-a0d13672efb1/go.mod h1:YA9We4kTafu7mlMnUh3In6Q2wpg8fYN3ycgCKOK1TB8= github.com/grafana/authlib v0.0.0-20240730122259-a0d13672efb1/go.mod h1:YA9We4kTafu7mlMnUh3In6Q2wpg8fYN3ycgCKOK1TB8=
github.com/grafana/authlib/claims v0.0.0-20240809101159-74eaccc31a06/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/authlib/claims v0.0.0-20240809101159-74eaccc31a06/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
github.com/grafana/authlib/claims v0.0.0-20240827173836-433b4fdb2f25/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
github.com/grafana/authlib/claims v0.0.0-20240827201239-81213c6670d3/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
github.com/grafana/gomemcache v0.0.0-20240229205252-cd6a66d6fb56/go.mod h1:PGk3RjYHpxMM8HFPhKKo+vve3DdlPUELZLSDEFehPuU= github.com/grafana/gomemcache v0.0.0-20240229205252-cd6a66d6fb56/go.mod h1:PGk3RjYHpxMM8HFPhKKo+vve3DdlPUELZLSDEFehPuU=
github.com/grafana/grafana-plugin-sdk-go v0.235.0/go.mod h1:6n9LbrjGL3xAATntYVNcIi90G9BVHRJjzHKz5FXVfWw= github.com/grafana/grafana-plugin-sdk-go v0.235.0/go.mod h1:6n9LbrjGL3xAATntYVNcIi90G9BVHRJjzHKz5FXVfWw=
github.com/grafana/prometheus-alertmanager v0.25.1-0.20240422145632-c33c6b5b6e6b h1:HCbWyVL6vi7gxyO76gQksSPH203oBJ1MJ3JcG1OQlsg= github.com/grafana/prometheus-alertmanager v0.25.1-0.20240422145632-c33c6b5b6e6b h1:HCbWyVL6vi7gxyO76gQksSPH203oBJ1MJ3JcG1OQlsg=

@ -3,8 +3,8 @@ module github.com/grafana/grafana/pkg/apimachinery
go 1.23.0 go 1.23.0
require ( require (
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db // @grafana/identity-access-team github.com/grafana/authlib v0.0.0-20240827201526-24af227df935 // @grafana/identity-access-team
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db // @grafana/identity-access-team github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd // @grafana/identity-access-team
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
k8s.io/apimachinery v0.31.0 k8s.io/apimachinery v0.31.0
k8s.io/apiserver v0.31.0 k8s.io/apiserver v0.31.0

@ -28,10 +28,10 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db h1:z++X4DdoX+aNlZNT1ZY4cykiFay4+f077pa0AG48SGg= github.com/grafana/authlib v0.0.0-20240827201526-24af227df935 h1:nT4UY61s2flsiLkU2jDqtqFhOLwqh355+8ZhnavKoMQ=
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db/go.mod h1:ptt910z9KFfpVSIbSbXvTRR7tS19mxD7EtmVbbJi/WE= github.com/grafana/authlib v0.0.0-20240827201526-24af227df935/go.mod h1:ER7bMzNNWTN/5Zl3pwqfgS6XEhcanjrvL7lOp8Ow6oc=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd h1:sIlR7n38/MnZvX2qxDEszywXdI5soCwQ78aTDSARvus=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=

@ -13,6 +13,10 @@ type IDClaimsWrapper struct {
Source Requester Source Requester
} }
func (i *IDClaimsWrapper) IsNil() bool {
return i.Source.IsNil()
}
// GetAuthenticatedBy implements claims.IdentityClaims. // GetAuthenticatedBy implements claims.IdentityClaims.
func (i *IDClaimsWrapper) AuthenticatedBy() string { func (i *IDClaimsWrapper) AuthenticatedBy() string {
return i.Source.GetAuthenticatedBy() return i.Source.GetAuthenticatedBy()

@ -4,7 +4,7 @@ go 1.23.0
require ( require (
github.com/google/go-cmp v0.6.0 github.com/google/go-cmp v0.6.0
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1
github.com/prometheus/client_golang v1.20.0 github.com/prometheus/client_golang v1.20.0
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0

@ -77,8 +77,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd h1:sIlR7n38/MnZvX2qxDEszywXdI5soCwQ78aTDSARvus=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1 h1:ItDcDxUjVLPKja+hogpqgW/kj8LxUL2qscelXIsN1Bs= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1 h1:ItDcDxUjVLPKja+hogpqgW/kj8LxUL2qscelXIsN1Bs=
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1/go.mod h1:DkxMin+qOh1Fgkxfbt+CUfBqqsCQJMG9op8Os/irBPA= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1/go.mod h1:DkxMin+qOh1Fgkxfbt+CUfBqqsCQJMG9op8Os/irBPA=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=

@ -3,6 +3,7 @@ package request
import ( import (
"context" "context"
"fmt" "fmt"
"strconv"
"k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/endpoints/request"
@ -17,8 +18,12 @@ type NamespaceMapper = claims.NamespaceFormatter
// GetNamespaceMapper returns a function that will convert orgIds into a consistent namespace // GetNamespaceMapper returns a function that will convert orgIds into a consistent namespace
func GetNamespaceMapper(cfg *setting.Cfg) NamespaceMapper { func GetNamespaceMapper(cfg *setting.Cfg) NamespaceMapper {
if cfg != nil && cfg.StackID != "" { if cfg != nil && cfg.StackID != "" {
//val := claims.CloudNamespaceFormatter(cfg.Sta) stackIdInt, err := strconv.ParseInt(cfg.StackID, 10, 64)
return func(orgId int64) string { return "stack-" + cfg.StackID } if err != nil {
stackIdInt = 0
}
cloudNamespace := claims.CloudNamespaceFormatter(stackIdInt)
return func(_ int64) string { return cloudNamespace }
} }
return claims.OrgNamespaceFormatter return claims.OrgNamespaceFormatter
} }

@ -26,11 +26,14 @@ func TestNamespaceMapper(t *testing.T) {
orgId: 123, orgId: 123,
expected: "org-123", expected: "org-123",
}, },
// an invalid use-case, but just documenting that it's handled as stack-0
// this currently prevents the need to have the Mapper return (mapped, err) instead of just mapped.
// err checking is avoided for now to keep the usage fluent
{ {
name: "with stackId", name: "with stackId",
cfg: "abc", cfg: "abc",
orgId: 123, // ignored orgId: 123, // ignored
expected: "stack-abc", expected: "stack-0", // we parse to int and default to 0
}, },
} }

@ -8,7 +8,7 @@ import (
"github.com/go-jose/go-jose/v3/jwt" "github.com/go-jose/go-jose/v3/jwt"
authlib "github.com/grafana/authlib/authn" authlib "github.com/grafana/authlib/authn"
authlibclaims "github.com/grafana/authlib/claims" "github.com/grafana/authlib/claims"
"github.com/grafana/grafana/pkg/apimachinery/errutil" "github.com/grafana/grafana/pkg/apimachinery/errutil"
"github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/apimachinery/identity"
@ -74,11 +74,13 @@ type ExtendedJWT struct {
func (s *ExtendedJWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) { func (s *ExtendedJWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
jwtToken := s.retrieveAuthenticationToken(r.HTTPRequest) jwtToken := s.retrieveAuthenticationToken(r.HTTPRequest)
claims, err := s.accessTokenVerifier.Verify(ctx, jwtToken) accessToken, err := s.accessTokenVerifier.Verify(ctx, jwtToken)
if err != nil { if err != nil {
return nil, errExtJWTInvalid.Errorf("failed to verify access token: %w", err) return nil, errExtJWTInvalid.Errorf("failed to verify access token: %w", err)
} }
accessTokenClaims := authlib.NewAccessClaims(*accessToken)
idToken := s.retrieveAuthorizationToken(r.HTTPRequest) idToken := s.retrieveAuthorizationToken(r.HTTPRequest)
if idToken != "" { if idToken != "" {
idTokenClaims, err := s.idTokenVerifier.Verify(ctx, idToken) idTokenClaims, err := s.idTokenVerifier.Verify(ctx, idToken)
@ -86,10 +88,10 @@ func (s *ExtendedJWT) Authenticate(ctx context.Context, r *authn.Request) (*auth
return nil, errExtJWTInvalid.Errorf("failed to verify id token: %w", err) return nil, errExtJWTInvalid.Errorf("failed to verify id token: %w", err)
} }
return s.authenticateAsUser(idTokenClaims, claims) return s.authenticateAsUser(authlib.NewIdentityClaims(*idTokenClaims), accessTokenClaims)
} }
return s.authenticateAsService(claims) return s.authenticateAsService(accessTokenClaims)
} }
func (s *ExtendedJWT) IsEnabled() bool { func (s *ExtendedJWT) IsEnabled() bool {
@ -97,42 +99,42 @@ func (s *ExtendedJWT) IsEnabled() bool {
} }
func (s *ExtendedJWT) authenticateAsUser( func (s *ExtendedJWT) authenticateAsUser(
idTokenClaims *authlib.Claims[authlib.IDTokenClaims], idTokenClaims claims.IdentityClaims,
accessTokenClaims *authlib.Claims[authlib.AccessTokenClaims], accessTokenClaims claims.AccessClaims,
) (*authn.Identity, error) { ) (*authn.Identity, error) {
// Only allow id tokens signed for namespace configured for this instance. // Only allow id tokens signed for namespace configured for this instance.
if allowedNamespace := s.namespaceMapper(s.getDefaultOrgID()); idTokenClaims.Rest.Namespace != allowedNamespace { if allowedNamespace := s.namespaceMapper(s.getDefaultOrgID()); !claims.NamespaceMatches(idTokenClaims, allowedNamespace) {
return nil, errExtJWTDisallowedNamespaceClaim.Errorf("unexpected id token namespace: %s", idTokenClaims.Rest.Namespace) return nil, errExtJWTDisallowedNamespaceClaim.Errorf("unexpected id token namespace: %s", idTokenClaims.Namespace())
} }
// Allow access tokens with either the same namespace as the validated id token namespace or wildcard (`*`). // Allow access tokens with either the same namespace as the validated id token namespace or wildcard (`*`).
if !accessTokenClaims.Rest.NamespaceMatches(idTokenClaims.Rest.Namespace) { if !claims.NamespaceMatches(accessTokenClaims, idTokenClaims.Namespace()) {
return nil, errExtJWTMisMatchedNamespaceClaims.Errorf("unexpected access token namespace: %s", accessTokenClaims.Rest.Namespace) return nil, errExtJWTMisMatchedNamespaceClaims.Errorf("unexpected access token namespace: %s", accessTokenClaims.Namespace())
} }
accessType, _, err := identity.ParseTypeAndID(accessTokenClaims.Subject) accessType, _, err := identity.ParseTypeAndID(accessTokenClaims.Subject())
if err != nil { if err != nil {
return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", accessTokenClaims.Subject) return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", accessTokenClaims.Subject())
} }
if !authlibclaims.IsIdentityType(accessType, authlibclaims.TypeAccessPolicy) { if !claims.IsIdentityType(accessType, claims.TypeAccessPolicy) {
return nil, errExtJWTInvalid.Errorf("unexpected identity: %s", accessTokenClaims.Subject) return nil, errExtJWTInvalid.Errorf("unexpected identity: %s", accessTokenClaims.Subject())
} }
t, id, err := identity.ParseTypeAndID(idTokenClaims.Subject) t, id, err := identity.ParseTypeAndID(idTokenClaims.Subject())
if err != nil { if err != nil {
return nil, errExtJWTInvalid.Errorf("failed to parse id token subject: %w", err) return nil, errExtJWTInvalid.Errorf("failed to parse id token subject: %w", err)
} }
if !authlibclaims.IsIdentityType(t, authlibclaims.TypeUser) { if !claims.IsIdentityType(t, claims.TypeUser) {
return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", idTokenClaims.Subject) return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", idTokenClaims.Subject())
} }
// For use in service layer, allow higher privilege // For use in service layer, allow higher privilege
allowedKubernetesNamespace := accessTokenClaims.Rest.Namespace allowedKubernetesNamespace := accessTokenClaims.Namespace()
if len(s.cfg.StackID) > 0 { if len(s.cfg.StackID) > 0 {
// For single-tenant cloud use, choose the lower of the two (id token will always have the specific namespace) // For single-tenant cloud use, choose the lower of the two (id token will always have the specific namespace)
allowedKubernetesNamespace = idTokenClaims.Rest.Namespace allowedKubernetesNamespace = idTokenClaims.Namespace()
} }
return &authn.Identity{ return &authn.Identity{
@ -140,30 +142,30 @@ func (s *ExtendedJWT) authenticateAsUser(
Type: t, Type: t,
OrgID: s.getDefaultOrgID(), OrgID: s.getDefaultOrgID(),
AuthenticatedBy: login.ExtendedJWTModule, AuthenticatedBy: login.ExtendedJWTModule,
AuthID: accessTokenClaims.Subject, AuthID: accessTokenClaims.Subject(),
AllowedKubernetesNamespace: allowedKubernetesNamespace, AllowedKubernetesNamespace: allowedKubernetesNamespace,
ClientParams: authn.ClientParams{ ClientParams: authn.ClientParams{
SyncPermissions: true, SyncPermissions: true,
FetchPermissionsParams: authn.FetchPermissionsParams{ FetchPermissionsParams: authn.FetchPermissionsParams{
ActionsLookup: accessTokenClaims.Rest.DelegatedPermissions, ActionsLookup: accessTokenClaims.DelegatedPermissions(),
}, },
FetchSyncedUser: true, FetchSyncedUser: true,
}}, nil }}, nil
} }
func (s *ExtendedJWT) authenticateAsService(claims *authlib.Claims[authlib.AccessTokenClaims]) (*authn.Identity, error) { func (s *ExtendedJWT) authenticateAsService(accessTokenClaims claims.AccessClaims) (*authn.Identity, error) {
// Allow access tokens with that has a wildcard namespace or a namespace matching this instance. // Allow access tokens with that has a wildcard namespace or a namespace matching this instance.
if allowedNamespace := s.namespaceMapper(s.getDefaultOrgID()); !claims.Rest.NamespaceMatches(allowedNamespace) { if allowedNamespace := s.namespaceMapper(s.getDefaultOrgID()); !claims.NamespaceMatches(accessTokenClaims, allowedNamespace) {
return nil, errExtJWTDisallowedNamespaceClaim.Errorf("unexpected access token namespace: %s", claims.Rest.Namespace) return nil, errExtJWTDisallowedNamespaceClaim.Errorf("unexpected access token namespace: %s", accessTokenClaims.Namespace())
} }
t, id, err := identity.ParseTypeAndID(claims.Subject) t, id, err := identity.ParseTypeAndID(accessTokenClaims.Subject())
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse access token subject: %w", err) return nil, fmt.Errorf("failed to parse access token subject: %w", err)
} }
if !authlibclaims.IsIdentityType(t, authlibclaims.TypeAccessPolicy) { if !claims.IsIdentityType(t, claims.TypeAccessPolicy) {
return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", claims.Subject) return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", accessTokenClaims.Subject())
} }
return &authn.Identity{ return &authn.Identity{
@ -172,12 +174,12 @@ func (s *ExtendedJWT) authenticateAsService(claims *authlib.Claims[authlib.Acces
Type: t, Type: t,
OrgID: s.getDefaultOrgID(), OrgID: s.getDefaultOrgID(),
AuthenticatedBy: login.ExtendedJWTModule, AuthenticatedBy: login.ExtendedJWTModule,
AuthID: claims.Subject, AuthID: accessTokenClaims.Subject(),
AllowedKubernetesNamespace: claims.Rest.Namespace, AllowedKubernetesNamespace: accessTokenClaims.Namespace(),
ClientParams: authn.ClientParams{ ClientParams: authn.ClientParams{
SyncPermissions: true, SyncPermissions: true,
FetchPermissionsParams: authn.FetchPermissionsParams{ FetchPermissionsParams: authn.FetchPermissionsParams{
Roles: claims.Rest.Permissions, Roles: accessTokenClaims.Permissions(),
}, },
FetchSyncedUser: false, FetchSyncedUser: false,
}, },

@ -51,6 +51,17 @@ var (
}, },
} }
validIDTokenClaimsWithStackSet = idTokenClaims{ validIDTokenClaimsWithStackSet = idTokenClaims{
Claims: &jwt.Claims{
Subject: "user:2",
Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)),
IssuedAt: jwt.NewNumericDate(time.Date(2023, 5, 2, 0, 0, 0, 0, time.UTC)),
},
Rest: authnlib.IDTokenClaims{
AuthenticatedBy: "extended_jwt",
Namespace: "stacks-1234",
},
}
validIDTokenClaimsWithDeprecatedStackClaimSet = idTokenClaims{
Claims: &jwt.Claims{ Claims: &jwt.Claims{
Subject: "user:2", Subject: "user:2",
Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)), Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)),
@ -61,7 +72,7 @@ var (
Namespace: "stack-1234", Namespace: "stack-1234",
}, },
} }
validAcessTokenClaimsWildcard = accessTokenClaims{ validAccessTokenClaimsWildcard = accessTokenClaims{
Claims: &jwt.Claims{ Claims: &jwt.Claims{
Subject: "access-policy:this-uid", Subject: "access-policy:this-uid",
Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)), Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)),
@ -71,15 +82,24 @@ var (
Namespace: "*", Namespace: "*",
}, },
} }
invalidWildcardNamespaceIDTokenClaims = idTokenClaims{ validAccessTokenClaimsWithStackSet = accessTokenClaims{
Claims: &jwt.Claims{ Claims: &jwt.Claims{
Subject: "user:2", Subject: "access-policy:this-uid",
Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)), Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)),
IssuedAt: jwt.NewNumericDate(time.Date(2023, 5, 2, 0, 0, 0, 0, time.UTC)), IssuedAt: jwt.NewNumericDate(time.Date(2023, 5, 2, 0, 0, 0, 0, time.UTC)),
}, },
Rest: authnlib.IDTokenClaims{ Rest: authnlib.AccessTokenClaims{
AuthenticatedBy: "extended_jwt", Namespace: "stacks-1234",
Namespace: "*", },
}
validAccessTokenClaimsWithDeprecatedStackClaimSet = accessTokenClaims{
Claims: &jwt.Claims{
Subject: "access-policy:this-uid",
Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)),
IssuedAt: jwt.NewNumericDate(time.Date(2023, 5, 2, 0, 0, 0, 0, time.UTC)),
},
Rest: authnlib.AccessTokenClaims{
Namespace: "stack-1234",
}, },
} }
invalidNamespaceIDTokenClaims = idTokenClaims{ invalidNamespaceIDTokenClaims = idTokenClaims{
@ -220,7 +240,7 @@ func TestExtendedJWT_Authenticate(t *testing.T) {
}, },
{ {
name: "should authenticate as service using wildcard namespace", name: "should authenticate as service using wildcard namespace",
accessToken: &validAcessTokenClaimsWildcard, accessToken: &validAccessTokenClaimsWildcard,
orgID: 1, orgID: 1,
want: &authn.Identity{ want: &authn.Identity{
ID: "this-uid", ID: "this-uid",
@ -258,7 +278,7 @@ func TestExtendedJWT_Authenticate(t *testing.T) {
}, },
{ {
name: "should authenticate as user using wildcard namespace for access token", name: "should authenticate as user using wildcard namespace for access token",
accessToken: &validAcessTokenClaimsWildcard, accessToken: &validAccessTokenClaimsWildcard,
idToken: &validIDTokenClaims, idToken: &validIDTokenClaims,
orgID: 1, orgID: 1,
want: &authn.Identity{ want: &authn.Identity{
@ -276,7 +296,7 @@ func TestExtendedJWT_Authenticate(t *testing.T) {
}, },
{ {
name: "should authenticate as user using wildcard namespace for access token, setting allowed namespace to specific", name: "should authenticate as user using wildcard namespace for access token, setting allowed namespace to specific",
accessToken: &validAcessTokenClaimsWildcard, accessToken: &validAccessTokenClaimsWildcard,
idToken: &validIDTokenClaimsWithStackSet, idToken: &validIDTokenClaimsWithStackSet,
orgID: 1, orgID: 1,
cfg: &setting.Cfg{ cfg: &setting.Cfg{
@ -291,7 +311,7 @@ func TestExtendedJWT_Authenticate(t *testing.T) {
ID: "2", ID: "2",
Type: claims.TypeUser, Type: claims.TypeUser,
OrgID: 1, OrgID: 1,
AllowedKubernetesNamespace: "stack-1234", AllowedKubernetesNamespace: "stacks-1234",
AuthenticatedBy: "extendedjwt", AuthenticatedBy: "extendedjwt",
AuthID: "access-policy:this-uid", AuthID: "access-policy:this-uid",
ClientParams: authn.ClientParams{ ClientParams: authn.ClientParams{
@ -301,14 +321,109 @@ func TestExtendedJWT_Authenticate(t *testing.T) {
}, },
}, },
{ {
name: "should return error when id token namespace is a wildcard", name: "should authenticate as service using specific namespace claim in access token",
accessToken: &validAccessTokenClaims, accessToken: &validAccessTokenClaimsWithStackSet,
idToken: &invalidWildcardNamespaceIDTokenClaims,
orgID: 1, orgID: 1,
wantErr: errExtJWTDisallowedNamespaceClaim, cfg: &setting.Cfg{
// default org set up by the authenticator is 1
StackID: "1234",
ExtJWTAuth: setting.ExtJWTSettings{
Enabled: true,
ExpectIssuer: "http://localhost:3000",
},
},
want: &authn.Identity{
ID: "this-uid",
UID: "this-uid",
Type: claims.TypeAccessPolicy,
OrgID: 1,
AllowedKubernetesNamespace: "stacks-1234",
AuthenticatedBy: "extendedjwt",
AuthID: "access-policy:this-uid",
ClientParams: authn.ClientParams{
SyncPermissions: true,
},
},
},
{
name: "should authenticate as service using specific deprecated namespace claim in access token",
accessToken: &validAccessTokenClaimsWithDeprecatedStackClaimSet,
orgID: 1,
cfg: &setting.Cfg{
// default org set up by the authenticator is 1
StackID: "1234",
ExtJWTAuth: setting.ExtJWTSettings{
Enabled: true,
ExpectIssuer: "http://localhost:3000",
},
},
want: &authn.Identity{
ID: "this-uid",
UID: "this-uid",
Type: claims.TypeAccessPolicy,
OrgID: 1,
AllowedKubernetesNamespace: "stack-1234",
AuthenticatedBy: "extendedjwt",
AuthID: "access-policy:this-uid",
ClientParams: authn.ClientParams{
SyncPermissions: true,
},
},
},
{
name: "should authenticate as user using specific deprecated namespace claim in access and id tokens",
accessToken: &validAccessTokenClaimsWithDeprecatedStackClaimSet,
idToken: &validIDTokenClaimsWithDeprecatedStackClaimSet,
orgID: 1,
cfg: &setting.Cfg{
// default org set up by the authenticator is 1
StackID: "1234",
ExtJWTAuth: setting.ExtJWTSettings{
Enabled: true,
ExpectIssuer: "http://localhost:3000",
},
},
want: &authn.Identity{
ID: "2",
Type: claims.TypeUser,
OrgID: 1,
AllowedKubernetesNamespace: "stack-1234",
AuthenticatedBy: "extendedjwt",
AuthID: "access-policy:this-uid",
ClientParams: authn.ClientParams{
SyncPermissions: true,
FetchSyncedUser: true,
},
},
},
{
name: "should authenticate as user using wildcard namespace for access token, setting allowed namespace to specific",
accessToken: &validAccessTokenClaimsWildcard,
idToken: &validIDTokenClaimsWithStackSet,
orgID: 1,
cfg: &setting.Cfg{
// default org set up by the authenticator is 1
StackID: "1234",
ExtJWTAuth: setting.ExtJWTSettings{
Enabled: true,
ExpectIssuer: "http://localhost:3000",
},
},
want: &authn.Identity{
ID: "2",
Type: claims.TypeUser,
OrgID: 1,
AllowedKubernetesNamespace: "stacks-1234",
AuthenticatedBy: "extendedjwt",
AuthID: "access-policy:this-uid",
ClientParams: authn.ClientParams{
FetchSyncedUser: true,
SyncPermissions: true,
},
},
}, },
{ {
name: "should return error when id token has wildcard namespace", name: "should return error when id token has an invalid namespace",
accessToken: &validAccessTokenClaims, accessToken: &validAccessTokenClaims,
idToken: &invalidNamespaceIDTokenClaims, idToken: &invalidNamespaceIDTokenClaims,
orgID: 1, orgID: 1,

@ -8,6 +8,7 @@ import (
authnlib "github.com/grafana/authlib/authn" authnlib "github.com/grafana/authlib/authn"
authzlib "github.com/grafana/authlib/authz" authzlib "github.com/grafana/authlib/authz"
authzv1 "github.com/grafana/authlib/authz/proto/v1" authzv1 "github.com/grafana/authlib/authz/proto/v1"
"github.com/grafana/authlib/claims"
grpcAuth "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth" grpcAuth "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
@ -105,7 +106,7 @@ func newInProcLegacyClient(server *legacyServer) (authzlib.MultiTenantClient, er
&authzlib.MultiTenantClientConfig{}, &authzlib.MultiTenantClientConfig{},
authzlib.WithGrpcConnectionLCOption(channel), authzlib.WithGrpcConnectionLCOption(channel),
// nolint:staticcheck // nolint:staticcheck
authzlib.WithNamespaceFormatterLCOption(authnlib.OnPremNamespaceFormatter), authzlib.WithNamespaceFormatterLCOption(claims.OrgNamespaceFormatter),
authzlib.WithDisableAccessTokenLCOption(), authzlib.WithDisableAccessTokenLCOption(),
) )
} }
@ -129,7 +130,7 @@ func newGrpcLegacyClient(address string) (authzlib.MultiTenantClient, error) {
grpc.WithStreamInterceptor(clientInterceptor.StreamClientInterceptor), grpc.WithStreamInterceptor(clientInterceptor.StreamClientInterceptor),
), ),
// nolint:staticcheck // nolint:staticcheck
authzlib.WithNamespaceFormatterLCOption(authnlib.OnPremNamespaceFormatter), authzlib.WithNamespaceFormatterLCOption(claims.OrgNamespaceFormatter),
// TODO(drclau): remove this once we have access token support on-prem // TODO(drclau): remove this once we have access token support on-prem
authzlib.WithDisableAccessTokenLCOption(), authzlib.WithDisableAccessTokenLCOption(),
) )

@ -3,7 +3,7 @@ module github.com/grafana/grafana/pkg/storage/unified/apistore
go 1.23.0 go 1.23.0
require ( require (
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da
github.com/grafana/grafana/pkg/apiserver v0.0.0-20240821155123-6891eb1d35da github.com/grafana/grafana/pkg/apiserver v0.0.0-20240821155123-6891eb1d35da
github.com/grafana/grafana/pkg/storage/unified/resource v0.0.0-20240821161612-71f0dae39e9d github.com/grafana/grafana/pkg/storage/unified/resource v0.0.0-20240821161612-71f0dae39e9d
@ -43,7 +43,7 @@ require (
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/gax-go/v2 v2.13.0 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db // indirect github.com/grafana/authlib v0.0.0-20240827201526-24af227df935 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect

@ -161,10 +161,10 @@ github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDP
github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db h1:z++X4DdoX+aNlZNT1ZY4cykiFay4+f077pa0AG48SGg= github.com/grafana/authlib v0.0.0-20240827201526-24af227df935 h1:nT4UY61s2flsiLkU2jDqtqFhOLwqh355+8ZhnavKoMQ=
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db/go.mod h1:ptt910z9KFfpVSIbSbXvTRR7tS19mxD7EtmVbbJi/WE= github.com/grafana/authlib v0.0.0-20240827201526-24af227df935/go.mod h1:ER7bMzNNWTN/5Zl3pwqfgS6XEhcanjrvL7lOp8Ow6oc=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd h1:sIlR7n38/MnZvX2qxDEszywXdI5soCwQ78aTDSARvus=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da h1:2E3c/I3ayAy4Z1GwIPqXNZcpUccRapE1aBXA1ho4g7o= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da h1:2E3c/I3ayAy4Z1GwIPqXNZcpUccRapE1aBXA1ho4g7o=
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da/go.mod h1:p09fvU5ujNL/Ig8HB7g4f+S0zyYbQq3x/f0jA4ujVOM= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da/go.mod h1:p09fvU5ujNL/Ig8HB7g4f+S0zyYbQq3x/f0jA4ujVOM=
github.com/grafana/grafana/pkg/apiserver v0.0.0-20240821155123-6891eb1d35da h1:xQMb8cRZYu7D0IO9q/lB7qFQpLGAoPUnCase1CGHrXY= github.com/grafana/grafana/pkg/apiserver v0.0.0-20240821155123-6891eb1d35da h1:xQMb8cRZYu7D0IO9q/lB7qFQpLGAoPUnCase1CGHrXY=

@ -4,8 +4,8 @@ go 1.23.0
require ( require (
github.com/fullstorydev/grpchan v1.1.1 github.com/fullstorydev/grpchan v1.1.1
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db github.com/grafana/authlib v0.0.0-20240827201526-24af227df935
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0
github.com/prometheus/client_golang v1.20.0 github.com/prometheus/client_golang v1.20.0

@ -128,10 +128,10 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s=
github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db h1:z++X4DdoX+aNlZNT1ZY4cykiFay4+f077pa0AG48SGg= github.com/grafana/authlib v0.0.0-20240827201526-24af227df935 h1:nT4UY61s2flsiLkU2jDqtqFhOLwqh355+8ZhnavKoMQ=
github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db/go.mod h1:ptt910z9KFfpVSIbSbXvTRR7tS19mxD7EtmVbbJi/WE= github.com/grafana/authlib v0.0.0-20240827201526-24af227df935/go.mod h1:ER7bMzNNWTN/5Zl3pwqfgS6XEhcanjrvL7lOp8Ow6oc=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd h1:sIlR7n38/MnZvX2qxDEszywXdI5soCwQ78aTDSARvus=
github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e h1:3vNpomyzv714Hgls5vn+fC0vgv8wUOSHepUl7PB5nUs= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e h1:3vNpomyzv714Hgls5vn+fC0vgv8wUOSHepUl7PB5nUs=
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e/go.mod h1:ORVFiW/KNRY52lNjkGwnFWCxNVfE97bJG2jr2fetq0I= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e/go.mod h1:ORVFiW/KNRY52lNjkGwnFWCxNVfE97bJG2jr2fetq0I=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=

@ -6,7 +6,7 @@ import (
"strconv" "strconv"
"github.com/grafana/authlib/authn" "github.com/grafana/authlib/authn"
"github.com/grafana/authlib/claims" authClaims "github.com/grafana/authlib/claims"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
@ -77,7 +77,7 @@ func (f *Authenticator) decodeMetadata(ctx context.Context, meta metadata.MD) (i
// TODO, remove after this has been deployed to unified storage // TODO, remove after this has been deployed to unified storage
if getter(mdUserID) == "" { if getter(mdUserID) == "" {
var err error var err error
user.Type = claims.TypeUser user.Type = authClaims.TypeUser
user.UserID, err = strconv.ParseInt(getter("grafana-userid"), 10, 64) user.UserID, err = strconv.ParseInt(getter("grafana-userid"), 10, 64)
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid user id: %w", err) return nil, fmt.Errorf("invalid user id: %w", err)

Loading…
Cancel
Save