diff --git a/common/authorization/default_jwt_claim_mapper.go b/common/authorization/default_jwt_claim_mapper.go index 0909fbee0969..24b95318058b 100644 --- a/common/authorization/default_jwt_claim_mapper.go +++ b/common/authorization/default_jwt_claim_mapper.go @@ -31,6 +31,7 @@ import ( "github.com/golang-jwt/jwt/v4" "go.temporal.io/api/serviceerror" + "go.temporal.io/server/common/primitives" "go.temporal.io/server/common/config" "go.temporal.io/server/common/log" @@ -40,7 +41,7 @@ const ( defaultPermissionsClaimName = "permissions" authorizationBearer = "bearer" headerSubject = "sub" - permissionScopeSystem = "system" + permissionScopeSystem = primitives.SystemLocalNamespace permissionRead = "read" permissionWrite = "write" permissionWorker = "worker" @@ -110,7 +111,7 @@ func (a *defaultJWTClaimMapper) extractPermissions(permissions []interface{}, cl a.logger.Warn(fmt.Sprintf("ignoring permission in unexpected format: %v", permission)) continue } - namespace := strings.ToLower(parts[0]) + namespace := parts[0] if strings.EqualFold(namespace, permissionScopeSystem) { claims.System |= permissionToRole(parts[1]) } else { diff --git a/common/authorization/default_jwt_claim_mapper_test.go b/common/authorization/default_jwt_claim_mapper_test.go index 74fda73b1e56..94fdbc3f7541 100644 --- a/common/authorization/default_jwt_claim_mapper_test.go +++ b/common/authorization/default_jwt_claim_mapper_test.go @@ -38,6 +38,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "go.temporal.io/server/common/primitives" "go.temporal.io/server/common/config" "go.temporal.io/server/common/log" @@ -65,7 +66,7 @@ const ( ) var ( - permissionsAdmin = []string{"system:admin", "default:read"} + permissionsAdmin = []string{primitives.SystemLocalNamespace + ":admin", "default:read"} permissionsReaderWriterWorker = []string{"default:read", "default:write", "default:worker"} ) @@ -163,6 +164,25 @@ func (s *defaultClaimMapperSuite) testTokenWithAdminPermissions(alg keyAlgorithm s.Equal(RoleReader, defaultRole) } +func (s *defaultClaimMapperSuite) TestNamespacePermissionCaseSensitive() { + tokenString, err := s.tokenGenerator.generateToken(RSA, + testSubject, []string{"Foo:read"}, errorTestOptionNoError) + s.NoError(err) + authInfo := &AuthInfo{ + AddBearer(tokenString), + nil, + nil, + "", + "", + } + claims, err := s.claimMapper.GetClaims(authInfo) + s.NoError(err) + s.Equal(testSubject, claims.Subject) + s.Equal(1, len(claims.Namespaces)) + fooRole := claims.Namespaces["Foo"] // claims contain namespace role for 'Foo', not for 'foo'. + s.Equal(RoleReader, fooRole) +} + func (s *defaultClaimMapperSuite) TestTokenWithReaderWriterWorkerPermissionsRSA() { s.testTokenWithReaderWriterWorkerPermissions(RSA) }