CVE-2025-14987
Description
When system.enableCrossNamespaceCommands is enabled (on by default), the Temporal server permits certain workflow task commands (e.g. StartChildWorkflowExecution, SignalExternalWorkflowExecution, RequestCancelExternalWorkflowExecution) to target a different namespace than the namespace authorized at the gRPC boundary. The frontend authorizes RespondWorkflowTaskCompleted based on the outer request namespace, but the history service later resolves and executes the command using the namespace embedded in command attributes without authorizing the caller for that target namespace. This can allow a worker authorized for one namespace to create, signal, or cancel workflows in another namespace. This issue affects Temporal: through 1.29.1. Fixed in 1.27.4, 1.28.2, 1.29.2.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
go.temporal.io/serverGo | < 1.27.4 | 1.27.4 |
go.temporal.io/serverGo | >= 1.28.0, < 1.28.2 | 1.28.2 |
go.temporal.io/serverGo | >= 1.29.0, < 1.29.2 | 1.29.2 |
go.temporal.io/serverGo | >= 1.29.0-0, < 1.29.0-135.0.0.20251218190115-b292a32bacdf | 1.29.0-135.0.0.20251218190115-b292a32bacdf |
Affected products
1- Range: dummy-tag, norbert-109, norbert/wip, …
Patches
43162b75c656c09d90574e0f0dfc3c9ad6540b292a32bacdfAuthorize cross namespace commands (#8858)
4 files changed · +434 −24
common/authorization/interceptor.go+101 −18 modified@@ -7,7 +7,10 @@ import ( "crypto/x509/pkix" "time" + enumspb "go.temporal.io/api/enums/v1" "go.temporal.io/api/serviceerror" + "go.temporal.io/api/workflowservice/v1" + "go.temporal.io/server/common/api" "go.temporal.io/server/common/dynamicconfig" "go.temporal.io/server/common/headers" "go.temporal.io/server/common/log" @@ -77,15 +80,16 @@ func PeerCert(tlsInfo *credentials.TLSInfo) *x509.Certificate { } type Interceptor struct { - claimMapper ClaimMapper - authorizer Authorizer - metricsHandler metrics.Handler - logger log.Logger - namespaceChecker NamespaceChecker - audienceGetter JWTAudienceMapper - authHeaderName string - authExtraHeaderName string - exposeAuthorizerErrors dynamicconfig.BoolPropertyFn + claimMapper ClaimMapper + authorizer Authorizer + metricsHandler metrics.Handler + logger log.Logger + namespaceChecker NamespaceChecker + audienceGetter JWTAudienceMapper + authHeaderName string + authExtraHeaderName string + exposeAuthorizerErrors dynamicconfig.BoolPropertyFn + enableCrossNamespaceCommands dynamicconfig.BoolPropertyFn } // NewInterceptor creates an authorization interceptor. @@ -99,17 +103,19 @@ func NewInterceptor( authHeaderName string, authExtraHeaderName string, exposeAuthorizerErrors dynamicconfig.BoolPropertyFn, + enableCrossNamespaceCommands dynamicconfig.BoolPropertyFn, ) *Interceptor { return &Interceptor{ - claimMapper: claimMapper, - authorizer: authorizer, - logger: logger, - namespaceChecker: namespaceChecker, - metricsHandler: metricsHandler, - authHeaderName: cmp.Or(authHeaderName, defaultAuthHeaderName), - authExtraHeaderName: cmp.Or(authExtraHeaderName, defaultAuthExtraHeaderName), - audienceGetter: audienceGetter, - exposeAuthorizerErrors: exposeAuthorizerErrors, + claimMapper: claimMapper, + authorizer: authorizer, + logger: logger, + namespaceChecker: namespaceChecker, + metricsHandler: metricsHandler, + authHeaderName: cmp.Or(authHeaderName, defaultAuthHeaderName), + authExtraHeaderName: cmp.Or(authExtraHeaderName, defaultAuthExtraHeaderName), + audienceGetter: audienceGetter, + exposeAuthorizerErrors: exposeAuthorizerErrors, + enableCrossNamespaceCommands: enableCrossNamespaceCommands, } } @@ -154,6 +160,11 @@ func (a *Interceptor) Intercept( if err := a.Authorize(ctx, claims, ct); err != nil { return nil, err } + + // Authorize target namespaces in cross-namespace commands + if err := a.authorizeTargetNamespaces(ctx, claims, namespace, req); err != nil { + return nil, err + } } return handler(ctx, req) } @@ -255,3 +266,75 @@ func (a *Interceptor) getMetricsHandler(nsName string) metrics.Handler { } return a.metricsHandler.WithTags(metrics.OperationTag(metrics.AuthorizationScope), nsTag) } + +// authorizeTargetNamespaces authorizes cross-namespace commands in RespondWorkflowTaskCompleted. +// Commands like SignalExternalWorkflow, StartChildWorkflow, and CancelExternalWorkflow can target +// workflows in different namespaces. This method ensures the caller has permission in those target +// namespaces as well. +func (a *Interceptor) authorizeTargetNamespaces( + ctx context.Context, + claims *Claims, + sourceNamespace string, + req interface{}, +) error { + // Skip if cross-namespace commands are not enabled + if !a.enableCrossNamespaceCommands() { + return nil + } + + // Cross-namespace commands can only be initiated via RespondWorkflowTaskCompletedRequest. + // Here we handle authorization for all such commands: SignalExternalWorkflow, + // StartChildWorkflow, and RequestCancelExternalWorkflow targeting a different namespace. + wftRequest, ok := req.(*workflowservice.RespondWorkflowTaskCompletedRequest) + if !ok { + return nil + } + + // Track namespace+API combinations we've already authorized to avoid duplicate checks + authorizedNamespaceAPIs := make(map[string]struct{}) + + for _, cmd := range wftRequest.GetCommands() { + var targetNamespace string + var apiName string + + switch cmd.GetCommandType() { + case enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION: + if attr := cmd.GetSignalExternalWorkflowExecutionCommandAttributes(); attr != nil { + targetNamespace = attr.GetNamespace() + apiName = "SignalWorkflowExecution" + } + case enumspb.COMMAND_TYPE_START_CHILD_WORKFLOW_EXECUTION: + if attr := cmd.GetStartChildWorkflowExecutionCommandAttributes(); attr != nil { + targetNamespace = attr.GetNamespace() + apiName = "StartWorkflowExecution" + } + case enumspb.COMMAND_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION: + if attr := cmd.GetRequestCancelExternalWorkflowExecutionCommandAttributes(); attr != nil { + targetNamespace = attr.GetNamespace() + apiName = "RequestCancelWorkflowExecution" + } + default: + // Other command types don't target external namespaces + } + + // Skip if empty, same as source, or already authorized + if targetNamespace == "" || targetNamespace == sourceNamespace { + continue + } + key := targetNamespace + ":" + apiName + if _, ok := authorizedNamespaceAPIs[key]; ok { + continue + } + + // Authorize access to target namespace for this specific API + if err := a.Authorize(ctx, claims, &CallTarget{ + APIName: api.WorkflowServicePrefix + apiName, + Namespace: targetNamespace, + Request: req, + }); err != nil { + return err + } + authorizedNamespaceAPIs[key] = struct{}{} + } + return nil +}
common/authorization/interceptor_test.go+319 −5 modified@@ -7,8 +7,11 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + commandpb "go.temporal.io/api/command/v1" + enumspb "go.temporal.io/api/enums/v1" "go.temporal.io/api/serviceerror" "go.temporal.io/api/workflowservice/v1" + "go.temporal.io/server/common/api" "go.temporal.io/server/common/dynamicconfig" "go.temporal.io/server/common/log" "go.temporal.io/server/common/metrics" @@ -19,7 +22,9 @@ import ( ) const ( - testNamespace string = "test-namespace" + testNamespace string = "test-namespace" + targetNamespace string = "target-namespace" + anotherNamespace string = "another-namespace" ) var ( @@ -30,6 +35,8 @@ var ( startWorkflowExecutionRequest = &workflowservice.StartWorkflowExecutionRequest{Namespace: testNamespace} startWorkflowExecutionTarget = &CallTarget{Namespace: testNamespace, Request: startWorkflowExecutionRequest, APIName: "/temporal.api.workflowservice.v1.WorkflowService/StartWorkflowExecution"} startWorkflowExecutionInfo = &grpc.UnaryServerInfo{FullMethod: "/temporal.api.workflowservice.v1.WorkflowService/StartWorkflowExecution"} + + respondWorkflowTaskCompletedInfo = &grpc.UnaryServerInfo{FullMethod: api.WorkflowServicePrefix + "RespondWorkflowTaskCompleted"} ) type ( @@ -75,7 +82,8 @@ func (s *authorizerInterceptorSuite) SetupTest() { nil, "", "", - dynamicconfig.GetBoolPropertyFn(false), + dynamicconfig.GetBoolPropertyFn(false), // exposeAuthorizerErrors + dynamicconfig.GetBoolPropertyFn(false), // enableCrossNamespaceCommands ) s.handler = func(ctx context.Context, req interface{}) (interface{}, error) { return true, nil } } @@ -149,7 +157,8 @@ func (s *authorizerInterceptorSuite) TestAuthorizationFailedExposed() { nil, "", "", - dynamicconfig.GetBoolPropertyFn(true), + dynamicconfig.GetBoolPropertyFn(true), // exposeAuthorizerErrors + dynamicconfig.GetBoolPropertyFn(false), // enableCrossNamespaceCommands ) authErr := serviceerror.NewInternal("intentional test failure") @@ -181,7 +190,8 @@ func (s *authorizerInterceptorSuite) TestNoopClaimMapperWithoutTLS() { nil, "", "", - dynamicconfig.GetBoolPropertyFn(false), + dynamicconfig.GetBoolPropertyFn(false), // exposeAuthorizerErrors + dynamicconfig.GetBoolPropertyFn(false), // enableCrossNamespaceCommands ) _, err := interceptor.Intercept(ctx, describeNamespaceRequest, describeNamespaceInfo, s.handler) s.NoError(err) @@ -197,7 +207,8 @@ func (s *authorizerInterceptorSuite) TestAlternateHeaders() { nil, "custom-header", "custom-extra-header", - dynamicconfig.GetBoolPropertyFn(false), + dynamicconfig.GetBoolPropertyFn(false), // exposeAuthorizerErrors + dynamicconfig.GetBoolPropertyFn(false), // enableCrossNamespaceCommands ) cases := []struct { @@ -246,3 +257,306 @@ func (n mockNamespaceChecker) Exists(name namespace.Name) error { } return errors.New("doesn't exist") } + +// multiNamespaceChecker is a mock that recognizes multiple namespaces +type multiNamespaceChecker []string + +func (m multiNamespaceChecker) Exists(name namespace.Name) error { + for _, ns := range m { + if ns == string(name) { + return nil + } + } + return errors.New("doesn't exist") +} + +// Helper to create a cross-namespace command +func makeCrossNamespaceCommand(commandType enumspb.CommandType, targetNs string) *commandpb.Command { + switch commandType { + case enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION: + return &commandpb.Command{ + CommandType: commandType, + Attributes: &commandpb.Command_SignalExternalWorkflowExecutionCommandAttributes{ + SignalExternalWorkflowExecutionCommandAttributes: &commandpb.SignalExternalWorkflowExecutionCommandAttributes{ + Namespace: targetNs, + }, + }, + } + case enumspb.COMMAND_TYPE_START_CHILD_WORKFLOW_EXECUTION: + return &commandpb.Command{ + CommandType: commandType, + Attributes: &commandpb.Command_StartChildWorkflowExecutionCommandAttributes{ + StartChildWorkflowExecutionCommandAttributes: &commandpb.StartChildWorkflowExecutionCommandAttributes{ + Namespace: targetNs, + }, + }, + } + case enumspb.COMMAND_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION: + return &commandpb.Command{ + CommandType: commandType, + Attributes: &commandpb.Command_RequestCancelExternalWorkflowExecutionCommandAttributes{ + RequestCancelExternalWorkflowExecutionCommandAttributes: &commandpb.RequestCancelExternalWorkflowExecutionCommandAttributes{ + Namespace: targetNs, + }, + }, + } + default: + return nil + } +} + +// Helper to create interceptor with cross-namespace commands enabled +func (s *authorizerInterceptorSuite) newCrossNamespaceInterceptor(namespaces ...string) *Interceptor { + return NewInterceptor( + s.mockClaimMapper, + s.mockAuthorizer, + s.mockMetricsHandler, + log.NewNoopLogger(), + multiNamespaceChecker(namespaces), + nil, + "", + "", + dynamicconfig.GetBoolPropertyFn(false), // exposeAuthorizerErrors + dynamicconfig.GetBoolPropertyFn(true), // enableCrossNamespaceCommands + ) +} + +func (s *authorizerInterceptorSuite) TestCrossNamespaceCommands_Authorized() { + testCases := []struct { + name string + commandType enumspb.CommandType + expectedAPI string + }{ + { + name: "SignalExternalWorkflow", + commandType: enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION, + expectedAPI: "SignalWorkflowExecution", + }, + { + name: "StartChildWorkflow", + commandType: enumspb.COMMAND_TYPE_START_CHILD_WORKFLOW_EXECUTION, + expectedAPI: "StartWorkflowExecution", + }, + { + name: "CancelExternalWorkflow", + commandType: enumspb.COMMAND_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION, + expectedAPI: "RequestCancelWorkflowExecution", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + request := &workflowservice.RespondWorkflowTaskCompletedRequest{ + Namespace: testNamespace, + Commands: []*commandpb.Command{makeCrossNamespaceCommand(tc.commandType, targetNamespace)}, + } + + sourceTarget := &CallTarget{ + Namespace: testNamespace, + Request: request, + APIName: api.WorkflowServicePrefix + "RespondWorkflowTaskCompleted", + } + crossNsTarget := &CallTarget{ + Namespace: targetNamespace, + Request: request, + APIName: api.WorkflowServicePrefix + tc.expectedAPI, + } + + interceptor := s.newCrossNamespaceInterceptor(testNamespace, targetNamespace) + + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, sourceTarget). + Return(Result{Decision: DecisionAllow}, nil) + s.mockMetricsHandler.EXPECT().WithTags( + metrics.OperationTag(metrics.AuthorizationScope), + metrics.NamespaceTag(targetNamespace), + ).Return(s.mockMetricsHandler) + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, crossNsTarget). + Return(Result{Decision: DecisionAllow}, nil) + + res, err := interceptor.Intercept(ctx, request, respondWorkflowTaskCompletedInfo, s.handler) + s.True(res.(bool)) + s.NoError(err) + }) + } +} + +func (s *authorizerInterceptorSuite) TestCrossNamespaceCommand_Unauthorized() { + request := &workflowservice.RespondWorkflowTaskCompletedRequest{ + Namespace: testNamespace, + Commands: []*commandpb.Command{makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION, targetNamespace)}, + } + + sourceTarget := &CallTarget{ + Namespace: testNamespace, + Request: request, + APIName: api.WorkflowServicePrefix + "RespondWorkflowTaskCompleted", + } + crossNsTarget := &CallTarget{ + Namespace: targetNamespace, + Request: request, + APIName: api.WorkflowServicePrefix + "SignalWorkflowExecution", + } + + interceptor := s.newCrossNamespaceInterceptor(testNamespace, targetNamespace) + + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, sourceTarget). + Return(Result{Decision: DecisionAllow}, nil) + s.mockMetricsHandler.EXPECT().WithTags( + metrics.OperationTag(metrics.AuthorizationScope), + metrics.NamespaceTag(targetNamespace), + ).Return(s.mockMetricsHandler) + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, crossNsTarget). + Return(Result{Decision: DecisionDeny}, nil) + s.mockMetricsHandler.EXPECT().Counter(metrics.ServiceErrUnauthorizedCounter.Name()).Return(metrics.NoopCounterMetricFunc) + + res, err := interceptor.Intercept(ctx, request, respondWorkflowTaskCompletedInfo, s.handler) + s.Nil(res) + s.Error(err) +} + +func (s *authorizerInterceptorSuite) TestNoExtraAuthCheck() { + testCases := []struct { + name string + targetNs string + description string + }{ + { + name: "SameNamespace", + targetNs: testNamespace, // Same as source + description: "command targeting same namespace should not trigger extra auth", + }, + { + name: "EmptyNamespace", + targetNs: "", // Empty defaults to source + description: "command with empty namespace should not trigger extra auth", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + request := &workflowservice.RespondWorkflowTaskCompletedRequest{ + Namespace: testNamespace, + Commands: []*commandpb.Command{makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION, tc.targetNs)}, + } + + sourceTarget := &CallTarget{ + Namespace: testNamespace, + Request: request, + APIName: api.WorkflowServicePrefix + "RespondWorkflowTaskCompleted", + } + + // Only expect authorization for source namespace + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, sourceTarget). + Return(Result{Decision: DecisionAllow}, nil) + + res, err := s.interceptor.Intercept(ctx, request, respondWorkflowTaskCompletedInfo, s.handler) + s.True(res.(bool)) + s.NoError(err) + }) + } +} + +func (s *authorizerInterceptorSuite) TestCrossNamespaceCommand_DisabledFeature() { + // When cross-namespace commands are disabled, no extra auth check should happen + request := &workflowservice.RespondWorkflowTaskCompletedRequest{ + Namespace: testNamespace, + Commands: []*commandpb.Command{makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION, targetNamespace)}, + } + + sourceTarget := &CallTarget{ + Namespace: testNamespace, + Request: request, + APIName: api.WorkflowServicePrefix + "RespondWorkflowTaskCompleted", + } + + // Interceptor with cross-namespace commands DISABLED (uses default s.interceptor which has it disabled) + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, sourceTarget). + Return(Result{Decision: DecisionAllow}, nil) + + res, err := s.interceptor.Intercept(ctx, request, respondWorkflowTaskCompletedInfo, s.handler) + s.True(res.(bool)) + s.NoError(err) +} + +func (s *authorizerInterceptorSuite) TestMultipleCommands_AuthDeduplication() { + // Test that authorization is deduplicated per namespace+API combination + request := &workflowservice.RespondWorkflowTaskCompletedRequest{ + Namespace: testNamespace, + Commands: []*commandpb.Command{ + makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION, targetNamespace), + makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_START_CHILD_WORKFLOW_EXECUTION, targetNamespace), + makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION, targetNamespace), + // Duplicate signal to same namespace - should not trigger extra auth + makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION, targetNamespace), + }, + } + + sourceTarget := &CallTarget{ + Namespace: testNamespace, + Request: request, + APIName: api.WorkflowServicePrefix + "RespondWorkflowTaskCompleted", + } + + interceptor := s.newCrossNamespaceInterceptor(testNamespace, targetNamespace) + + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, sourceTarget). + Return(Result{Decision: DecisionAllow}, nil) + // Expect 3 auth checks (one per unique API type), not 4 + s.mockMetricsHandler.EXPECT().WithTags( + metrics.OperationTag(metrics.AuthorizationScope), + metrics.NamespaceTag(targetNamespace), + ).Return(s.mockMetricsHandler).Times(3) + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, &CallTarget{ + Namespace: targetNamespace, Request: request, APIName: api.WorkflowServicePrefix + "SignalWorkflowExecution", + }).Return(Result{Decision: DecisionAllow}, nil) + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, &CallTarget{ + Namespace: targetNamespace, Request: request, APIName: api.WorkflowServicePrefix + "StartWorkflowExecution", + }).Return(Result{Decision: DecisionAllow}, nil) + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, &CallTarget{ + Namespace: targetNamespace, Request: request, APIName: api.WorkflowServicePrefix + "RequestCancelWorkflowExecution", + }).Return(Result{Decision: DecisionAllow}, nil) + + res, err := interceptor.Intercept(ctx, request, respondWorkflowTaskCompletedInfo, s.handler) + s.True(res.(bool)) + s.NoError(err) +} + +func (s *authorizerInterceptorSuite) TestMultipleTargetNamespaces() { + // Test commands targeting different namespaces + request := &workflowservice.RespondWorkflowTaskCompletedRequest{ + Namespace: testNamespace, + Commands: []*commandpb.Command{ + makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION, targetNamespace), + makeCrossNamespaceCommand(enumspb.COMMAND_TYPE_START_CHILD_WORKFLOW_EXECUTION, anotherNamespace), + }, + } + + sourceTarget := &CallTarget{ + Namespace: testNamespace, + Request: request, + APIName: api.WorkflowServicePrefix + "RespondWorkflowTaskCompleted", + } + + interceptor := s.newCrossNamespaceInterceptor(testNamespace, targetNamespace, anotherNamespace) + + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, sourceTarget). + Return(Result{Decision: DecisionAllow}, nil) + s.mockMetricsHandler.EXPECT().WithTags( + metrics.OperationTag(metrics.AuthorizationScope), + metrics.NamespaceTag(targetNamespace), + ).Return(s.mockMetricsHandler) + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, &CallTarget{ + Namespace: targetNamespace, Request: request, APIName: api.WorkflowServicePrefix + "SignalWorkflowExecution", + }).Return(Result{Decision: DecisionAllow}, nil) + s.mockMetricsHandler.EXPECT().WithTags( + metrics.OperationTag(metrics.AuthorizationScope), + metrics.NamespaceTag(anotherNamespace), + ).Return(s.mockMetricsHandler) + s.mockAuthorizer.EXPECT().Authorize(ctx, nil, &CallTarget{ + Namespace: anotherNamespace, Request: request, APIName: api.WorkflowServicePrefix + "StartWorkflowExecution", + }).Return(Result{Decision: DecisionAllow}, nil) + + res, err := interceptor.Intercept(ctx, request, respondWorkflowTaskCompletedInfo, s.handler) + s.True(res.(bool)) + s.NoError(err) +}
service/frontend/fx.go+2 −0 modified@@ -163,6 +163,7 @@ func AuthorizationInterceptorProvider( authorizer authorization.Authorizer, claimMapper authorization.ClaimMapper, audienceGetter authorization.JWTAudienceMapper, + dc *dynamicconfig.Collection, ) *authorization.Interceptor { return authorization.NewInterceptor( claimMapper, @@ -174,6 +175,7 @@ func AuthorizationInterceptorProvider( cfg.Global.Authorization.AuthHeaderName, cfg.Global.Authorization.AuthExtraHeaderName, serviceConfig.ExposeAuthorizerErrors, + dynamicconfig.EnableCrossNamespaceCommands.Get(dc), ) }
service/frontend/nexus_handler_test.go+12 −1 modified@@ -117,7 +117,18 @@ func newOperationContext(options contextOptions) *operationContext { ) checker := mockNamespaceChecker(oc.namespace.Name()) - oc.auth = authorization.NewInterceptor(nil, mockAuthorizer{}, oc.metricsHandler, oc.logger, checker, nil, "", "", dynamicconfig.GetBoolPropertyFn(false)) + oc.auth = authorization.NewInterceptor( + nil, + mockAuthorizer{}, + oc.metricsHandler, + oc.logger, + checker, + nil, + "", + "", + dynamicconfig.GetBoolPropertyFn(false), // exposeAuthorizerErrors + dynamicconfig.GetBoolPropertyFn(false), // enableCrossNamespaceCommands + ) oc.namespaceConcurrencyLimitInterceptor = interceptor.NewConcurrentRequestLimitInterceptor( nil, nil,
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-hmhp-gh8m-c8xpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-14987ghsaADVISORY
- github.com/temporalio/temporal/commit/b292a32bacdfa6472affd90f0a940408d5839cfaghsaWEB
- github.com/temporalio/temporal/releases/tag/v1.27.4nvdWEB
- github.com/temporalio/temporal/releases/tag/v1.28.2nvdWEB
- github.com/temporalio/temporal/releases/tag/v1.29.2nvdWEB
News mentions
0No linked articles in our index yet.