Rename the dynamic config components.callbacks.allowedAddresses to callback.allowedAddresses. (#10234)

## What changed?

Use the new dynamic config instead of leaving it as a placeholder and
update its documentation.

Also bumps the server version constant to `1.32.0`. This was supposed to
be done after the `1.31.0` release and was missed.

## Why?

Remove duplication as we migrate the code to the CHASM backed
implementation.

## Potential risks

This config is only relevant for external endpoints which are
experimental or older server versions, needs to be called out in the
release notes.
This commit is contained in:
Roey Berman
2026-05-16 19:32:02 -07:00
committed by GitHub
parent 2e69aedd67
commit 453df8f1a2
16 changed files with 38 additions and 57 deletions
+7 -5
View File
@@ -59,15 +59,17 @@ func configProvider(dc *dynamicconfig.Collection) *Config {
}
var AllowedAddresses = dynamicconfig.NewNamespaceTypedSettingWithConverter(
"chasm.callback.allowedAddresses",
"callback.allowedAddresses",
allowedAddressConverter,
AddressMatchRules{},
`The per-namespace list of addresses that are allowed for callbacks and whether secure connections (https) are required.
URL: "temporal://system" is always allowed for worker callbacks. The default is no address rules.
URLs are checked against each in order when starting a workflow with attached callbacks and only need to match one to pass validation.
This configuration is required for external endpoint targets; any invalid entries are ignored. Each entry is a map with possible values:
URLs: "temporal://system" and "temporal://internal" are always allowed. The default is no address rules.
URLs are checked against each in order when starting a workflow or activitiy with attached callbacks or a standalone
callback and only need to match one to pass validation. This configuration is required for external endpoint targets;
any invalid entries are ignored. Each entry is a map with possible values:
- "Pattern":string (required) the host:port pattern to which this config applies.
Wildcards, '*', are supported and can match any number of characters (e.g. '*' matches everything, 'prefix.*.domain' matches 'prefix.a.domain' as well as 'prefix.a.b.domain').
Wildcards, '*', are supported and can match any number of characters (e.g. '*' matches everything,
'prefix.*.domain' matches 'prefix.a.domain' as well as 'prefix.a.b.domain').
- "AllowInsecure":bool (optional, default=false) indicates whether https is required`)
type AddressMatchRules struct {
+1 -1
View File
@@ -23,7 +23,7 @@ const (
// ServerVersion value can be changed by the create-tag Github workflow.
// If you change the var name or move it, be sure to update the workflow.
ServerVersion = "1.31.0"
ServerVersion = "1.32.0"
// SupportedServerVersions is used by CLI and inter role communication.
SupportedServerVersions = ">=1.0.0 <2.0.0"
-12
View File
@@ -52,18 +52,6 @@ func ConfigProvider(dc *dynamicconfig.Collection) *Config {
}
}
var AllowedAddresses = dynamicconfig.NewNamespaceTypedSettingWithConverter(
"component.callbacks.allowedAddresses",
allowedAddressConverter,
AddressMatchRules{},
`The per-namespace list of addresses that are allowed for callbacks and whether secure connections (https) are required.
URL: "temporal://system" is always allowed for worker callbacks. The default is no address rules.
URLs are checked against each in order when starting a workflow with attached callbacks and only need to match one to pass validation.
This configuration is required for external endpoint targets; any invalid entries are ignored. Each entry is a map with possible values:
- "Pattern":string (required) the host:port pattern to which this config applies.
Wildcards, '*', are supported and can match any number of characters (e.g. '*' matches everything, 'prefix.*.domain' matches 'prefix.a.domain' as well as 'prefix.a.b.domain').
- "AllowInsecure":bool (optional, default=false) indicates whether https is required`)
type AddressMatchRules struct {
Rules []AddressMatchRule
}
+1 -1
View File
@@ -39,7 +39,7 @@ frontend.workerVersioningRuleAPIs:
- value: true
component.nexusoperations.callback.endpoint.template:
- value: http://localhost:7243/namespaces/{{.NamespaceName}}/nexus/callback
component.callbacks.allowedAddresses:
callback.allowedAddresses:
- value:
- Pattern: "*"
AllowInsecure: true
+1 -1
View File
@@ -57,7 +57,7 @@ system.enableDeployments:
- value: true
component.nexusoperations.callback.endpoint.template:
- value: http://localhost:7243/namespaces/{{.NamespaceName}}/nexus/callback
component.callbacks.allowedAddresses:
callback.allowedAddresses:
- value:
- Pattern: "*"
AllowInsecure: true
+1 -1
View File
@@ -33,7 +33,7 @@ frontend.workerVersioningWorkflowAPIs:
- value: true
component.nexusoperations.callback.endpoint.template:
- value: http://localhost:7243/namespaces/{{.NamespaceName}}/nexus/callback
component.callbacks.allowedAddresses:
callback.allowedAddresses:
- value:
- Pattern: "*"
AllowInsecure: true
+4 -1
View File
@@ -82,7 +82,10 @@ the 1.31.0 release and will be made the default.
# When using Nexus for cross namespace calls, the URL's host is irrelevant as the address is resolved using
# membership. The URL is a Go template that interpolates the `NamepaceName` and `NamespaceID` variables.
- value: https://$PUBLIC_URL:7243/namespaces/{{.NamespaceName}}/nexus/callback
component.callbacks.allowedAddresses:
# From version 1.32.x
callback.allowedAddresses:
# Uncomment versions older than 1.32.x
# component.callbacks.allowedAddresses:
# Limits which callback URLs are accepted by the server.
# Wildcard patterns (*) and insecure (HTTP) callbacks are intended for development only.
# For production, restrict allowed hosts and set AllowInsecure to false
+2 -12
View File
@@ -43,7 +43,6 @@ import (
"go.temporal.io/server/common/sdk"
"go.temporal.io/server/common/searchattribute"
"go.temporal.io/server/common/telemetry"
hsmcallbacks "go.temporal.io/server/components/callbacks"
"go.temporal.io/server/service"
"go.temporal.io/server/service/frontend/configs"
"go.temporal.io/server/service/history/tasks"
@@ -843,22 +842,13 @@ func OperatorHandlerProvider(
}
// callbackValidatorProvider creates a callback Validator using the production dynamic config keys
// so that existing operator configurations (component.callbacks.allowedAddresses) are honored.
// TODO: Once HSM callbacks (components/callbacks) are removed, move this provider into
// chasm/lib/callback/fx.go and read directly from callback.AllowedAddresses.
// so that existing operator configurations (callback.allowedAddresses) are honored.
func callbackValidatorProvider(dc *dynamicconfig.Collection) callback.Validator {
return callback.NewValidator(
callback.MaxPerExecution.Get(dc),
dynamicconfig.FrontendCallbackURLMaxLength.Get(dc),
dynamicconfig.FrontendCallbackHeaderMaxSize.Get(dc),
func(ns string) callback.AddressMatchRules {
hsmRules := hsmcallbacks.AllowedAddresses.Get(dc)(ns)
chasmRules := make([]callback.AddressMatchRule, len(hsmRules.Rules))
for i, r := range hsmRules.Rules {
chasmRules[i] = callback.AddressMatchRule{Regexp: r.Regexp, AllowInsecure: r.AllowInsecure}
}
return callback.AddressMatchRules{Rules: chasmRules}
},
callback.AllowedAddresses.Get(dc),
)
}
+3 -3
View File
@@ -10,6 +10,7 @@ import (
"go.temporal.io/api/workflowservice/v1"
"go.temporal.io/server/api/adminservice/v1"
"go.temporal.io/server/chasm/lib/activity"
"go.temporal.io/server/chasm/lib/callback"
chasmnexus "go.temporal.io/server/chasm/lib/nexusoperation"
"go.temporal.io/server/common/dynamicconfig"
"go.temporal.io/server/common/log"
@@ -18,7 +19,6 @@ import (
"go.temporal.io/server/common/metrics"
"go.temporal.io/server/common/persistence/visibility/manager"
"go.temporal.io/server/common/retrypolicy"
"go.temporal.io/server/components/callbacks"
"go.temporal.io/server/components/nexusoperations"
"google.golang.org/grpc"
"google.golang.org/grpc/health"
@@ -200,7 +200,7 @@ type Config struct {
CallbackURLMaxLength dynamicconfig.IntPropertyFnWithNamespaceFilter
CallbackHeaderMaxSize dynamicconfig.IntPropertyFnWithNamespaceFilter
MaxCallbacksPerWorkflow dynamicconfig.IntPropertyFnWithNamespaceFilter
CallbackEndpointConfigs dynamicconfig.TypedPropertyFnWithNamespaceFilter[callbacks.AddressMatchRules]
CallbackEndpointConfigs dynamicconfig.TypedPropertyFnWithNamespaceFilter[callback.AddressMatchRules]
MaxNexusOperationTokenLength dynamicconfig.IntPropertyFnWithNamespaceFilter
NexusRequestHeadersBlacklist dynamicconfig.TypedPropertyFn[*regexp.Regexp]
@@ -384,7 +384,7 @@ func NewConfig(
LinkMaxSize: dynamicconfig.FrontendLinkMaxSize.Get(dc),
MaxLinksPerRequest: dynamicconfig.FrontendMaxLinksPerRequest.Get(dc),
CallbackEndpointConfigs: callbacks.AllowedAddresses.Get(dc),
CallbackEndpointConfigs: callback.AllowedAddresses.Get(dc),
AdminEnableListHistoryTasks: dynamicconfig.AdminEnableListHistoryTasks.Get(dc),
MaskInternalErrorDetails: dynamicconfig.FrontendMaskInternalErrorDetails.Get(dc),
+2 -3
View File
@@ -64,7 +64,6 @@ import (
"go.temporal.io/server/common/testing/protoassert"
"go.temporal.io/server/common/testing/protorequire"
"go.temporal.io/server/common/tqid"
"go.temporal.io/server/components/callbacks"
"go.temporal.io/server/service/history/api"
"go.temporal.io/server/service/history/tests"
"go.temporal.io/server/service/worker/batcher"
@@ -876,8 +875,8 @@ func (s *WorkflowHandlerSuite) TestStartWorkflowExecution_Failed_InvalidAggregat
s.mockSearchAttributesMapperProvider.EXPECT().GetMapper(gomock.Any()).AnyTimes().Return(nil, nil)
config := s.newConfig()
config.MaxLinksPerRequest = dc.GetIntPropertyFnFilteredByNamespace(10)
config.CallbackEndpointConfigs = dc.GetTypedPropertyFnFilteredByNamespace(callbacks.AddressMatchRules{
Rules: []callbacks.AddressMatchRule{
config.CallbackEndpointConfigs = dc.GetTypedPropertyFnFilteredByNamespace(callback.AddressMatchRules{
Rules: []callback.AddressMatchRule{
{
Regexp: regexp.MustCompile(`.*`),
AllowInsecure: true,
+4 -4
View File
@@ -18,10 +18,10 @@ import (
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
"go.temporal.io/sdk/workflow"
"go.temporal.io/server/chasm/lib/callback"
"go.temporal.io/server/common/dynamicconfig"
"go.temporal.io/server/common/nexus/nexusrpc"
"go.temporal.io/server/common/testing/testvars"
"go.temporal.io/server/components/callbacks"
"go.temporal.io/server/tests/testcore"
"google.golang.org/protobuf/types/known/durationpb"
)
@@ -52,7 +52,7 @@ func (s *CallbacksMigrationSuite) TestWorkflowCallbacks_CHASM_Enabled_Mid_WF() {
// 5. Verify callback is invoked successfully
s.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
@@ -185,7 +185,7 @@ func (s *CallbacksMigrationSuite) TestWorkflowCallbacks_CHASM_Disabled_Mid_WF()
// 6. Verify callback is invoked successfully despite EnableCHASMCallbacks being disabled
s.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
@@ -319,7 +319,7 @@ func (s *CallbacksMigrationSuite) TestWorkflowCallbacks_MixedCallbacks() {
// 6. Verify both callbacks (HSM and CHASM) are invoked successfully
s.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
+4 -5
View File
@@ -27,7 +27,6 @@ import (
"go.temporal.io/server/common/testing/protoassert"
"go.temporal.io/server/common/testing/protorequire"
"go.temporal.io/server/common/testing/testvars"
"go.temporal.io/server/components/callbacks"
"go.temporal.io/server/tests/testcore"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/durationpb"
@@ -126,7 +125,7 @@ func (s *CallbacksSuite) TestWorkflowCallbacks_InvalidArgument() {
s.OverrideDynamicConfig(dynamicconfig.MaxCallbacksPerWorkflow, 2)
s.OverrideDynamicConfig(callback.MaxPerExecution, 2)
s.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "some-ignored-address", "AllowInsecure": true}, map[string]any{"Pattern": "some-secure-address", "AllowInsecure": false}},
)
@@ -165,7 +164,7 @@ func (s *CallbacksSuite) TestWorkflowCallbacks_InvalidArgument() {
func (s *CallbacksSuite) TestWorkflowNexusCallbacks_CarriedOver() {
s.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
@@ -421,7 +420,7 @@ func (s *CallbacksSuite) TestWorkflowNexusCallbacks_CarriedOver() {
func (s *CallbacksSuite) TestNexusResetWorkflowWithCallback() {
s.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
@@ -611,7 +610,7 @@ func blockingWorkflow(ctx workflow.Context) error {
func (s *CallbacksSuite) TestNexusResetWorkflowWithCallback_ResetToNotBaseRun() {
s.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
+2 -2
View File
@@ -25,6 +25,7 @@ import (
"go.temporal.io/sdk/temporal"
"go.temporal.io/sdk/workflow"
schedulespb "go.temporal.io/server/api/schedule/v1"
"go.temporal.io/server/chasm/lib/callback"
schedulerpb "go.temporal.io/server/chasm/lib/scheduler/gen/schedulerpb/v1"
"go.temporal.io/server/common/dynamicconfig"
"go.temporal.io/server/common/headers"
@@ -34,7 +35,6 @@ import (
"go.temporal.io/server/common/primitives"
"go.temporal.io/server/common/searchattribute/sadefs"
"go.temporal.io/server/common/testing/protorequire"
"go.temporal.io/server/components/callbacks"
"go.temporal.io/server/service/worker/dummy"
"go.temporal.io/server/service/worker/scheduler"
"go.temporal.io/server/tests/testcore"
@@ -1711,7 +1711,7 @@ func testResetWithAdditionalCallback(t *testing.T, newContext contextFactory, en
s := testcore.NewEnv(t, scheduleCommonOpts()...)
s.OverrideDynamicConfig(dynamicconfig.EnableCHASMCallbacks, enableCHASMCallbacks)
s.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
+2 -3
View File
@@ -32,7 +32,6 @@ import (
"go.temporal.io/server/common/tasktoken"
"go.temporal.io/server/common/testing/parallelsuite"
"go.temporal.io/server/common/testing/protorequire"
"go.temporal.io/server/components/callbacks"
"go.temporal.io/server/tests/testcore"
"google.golang.org/grpc/codes"
"google.golang.org/protobuf/types/known/durationpb"
@@ -272,7 +271,7 @@ func (s *standaloneActivityTestSuite) TestIDConflictPolicy() {
t.Run("OnConflictOptions", func(t *testing.T) {
env.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
@@ -5840,7 +5839,7 @@ func (s *standaloneActivityTestSuite) TestCallbacks() {
defer cancel()
env.OverrideDynamicConfig(
callbacks.AllowedAddresses,
callback.AllowedAddresses,
[]any{map[string]any{"Pattern": "*", "AllowInsecure": true}},
)
+2 -2
View File
@@ -21,6 +21,7 @@ import (
updatepb "go.temporal.io/api/update/v1"
workflowpb "go.temporal.io/api/workflow/v1"
"go.temporal.io/api/workflowservice/v1"
"go.temporal.io/server/chasm/lib/callback"
"go.temporal.io/server/common/dynamicconfig"
"go.temporal.io/server/common/failure"
"go.temporal.io/server/common/headers"
@@ -31,7 +32,6 @@ import (
"go.temporal.io/server/common/primitives/timestamp"
"go.temporal.io/server/common/searchattribute/sadefs"
"go.temporal.io/server/common/testing/testvars"
"go.temporal.io/server/components/callbacks"
"go.temporal.io/server/tests/testcore"
"google.golang.org/protobuf/types/known/durationpb"
)
@@ -202,7 +202,7 @@ func (s *WorkflowTestSuite) TestStartWorkflowExecution_UseExisting() {
}
func (s *WorkflowTestSuite) TestStartWorkflowExecution_UseExisting_OnConflictOptions() {
s.OverrideDynamicConfig(callbacks.AllowedAddresses, []any{
s.OverrideDynamicConfig(callback.AllowedAddresses, []any{
map[string]any{"Pattern": "some-secure-address", "AllowInsecure": false},
map[string]any{"Pattern": "some-random-address", "AllowInsecure": false},
})
+2 -1
View File
@@ -26,6 +26,7 @@ import (
workflowpb "go.temporal.io/api/workflow/v1"
"go.temporal.io/api/workflowservice/v1"
sdkclient "go.temporal.io/sdk/client"
"go.temporal.io/server/chasm/lib/callback"
"go.temporal.io/server/common/dynamicconfig"
commonnexus "go.temporal.io/server/common/nexus"
"go.temporal.io/server/common/nexus/nexusrpc"
@@ -70,7 +71,7 @@ func (s *NexusStateReplicationSuite) SetupSuite() {
dynamicconfig.FrontendGlobalNamespaceNamespaceReplicationInducingAPIsRPS.Key(): 1000,
dynamicconfig.RefreshNexusEndpointsMinWait.Key(): 1 * time.Millisecond,
// tests use external endpoints so we need to allow them
callbacks.AllowedAddresses.Key(): []any{map[string]any{
callback.AllowedAddresses.Key(): []any{map[string]any{
"Pattern": "*", "AllowInsecure": true,
}},
// Cap callback retry backoff to avoid long waits after failover.