Merge commit from fork

* Add DenyLists parsing

* Remove unneeded returned error

* Plug global denylist into Command

* app creation: apply denylist to backchannel logout URI

* Inject denylist to backchannel logout worker

* webhook config: validate against blocked URLs

* Add notificationsWebhook denylist target

* command: Add SMTP endpoint validation against blocklist

* command: Add SMS endpoint validation against blocklist

* Validate webhook endpoint against denylist on channel notification

* Remove unused tests

* handle deprecated denylists

* remove unintended denylist entry in deprecated list

* use single http client

* fix tests

* update comments

* fixes

* cleanup

* address comments

* fix merge

---------

Co-authored-by: Livio Spring <[email protected]>
This commit is contained in:
Marco A.
2026-06-15 15:36:14 +02:00
committed by GitHub
co-authored by Livio Spring
parent d184e976fc
commit 8e82ec1cb9
97 changed files with 1834 additions and 285 deletions
+5 -2
View File
@@ -3,6 +3,7 @@ package setup
import (
"context"
"fmt"
"net/http"
"os"
"strings"
@@ -47,6 +48,8 @@ type FirstInstance struct {
externalPort uint16
domain string
defaultPaths *login.DefaultPaths
httpClient *http.Client
denylist []denylist.AddressChecker
}
func (mig *FirstInstance) Execute(ctx context.Context, _ eventstore.Event) error {
@@ -89,7 +92,7 @@ func (mig *FirstInstance) Execute(ctx context.Context, _ eventstore.Event) error
nil,
nil,
oidcEncryption,
nil,
mig.httpClient,
nil,
nil,
0,
@@ -97,7 +100,7 @@ func (mig *FirstInstance) Execute(ctx context.Context, _ eventstore.Event) error
0,
nil,
mig.defaultPaths,
[]denylist.AddressChecker{},
mig.denylist,
)
if err != nil {
return err
+4
View File
@@ -19,6 +19,7 @@ import (
"github.com/zitadel/zitadel/cmd/hooks"
"github.com/zitadel/zitadel/internal/actions"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/http"
"github.com/zitadel/zitadel/internal/api/oidc"
"github.com/zitadel/zitadel/internal/api/ui/login"
"github.com/zitadel/zitadel/internal/cache/connector"
@@ -64,6 +65,7 @@ type Config struct {
WebAuthNName string
Telemetry *handlers.TelemetryPusherConfig
SystemAPIUsers map[string]*authz.SystemAPIUser
HTTPClient http.ClientConfig
}
type InitProjections struct {
@@ -114,6 +116,8 @@ func NewConfig(cmd *cobra.Command, v *viper.Viper) (*Config, instrumentation.Shu
id.Configure(config.Machine)
config.HTTPClient.MergeDeprecatedDenylists(nil, config.Executions.DenyList)
// Copy the global role permissions mappings to the instance until we allow instance-level configuration over the API.
config.DefaultInstance.RolePermissionMappings = config.InternalAuthZ.RolePermissionMappings
+1 -2
View File
@@ -7,7 +7,6 @@ import (
"github.com/zitadel/zitadel/internal/cache/connector"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/config/systemdefaults"
"github.com/zitadel/zitadel/internal/denylist"
"github.com/zitadel/zitadel/internal/eventstore"
)
@@ -61,7 +60,7 @@ func (mig *externalConfigChange) Execute(ctx context.Context, _ eventstore.Event
0,
nil,
&login.DefaultPaths{},
[]denylist.AddressChecker{},
nil,
)
if err != nil {
+9 -3
View File
@@ -170,6 +170,8 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
MaxRetries: config.Eventstore.MaxRetries,
}))
httpClient := config.HTTPClient.NewClient()
steps.s1ProjectionTable = &ProjectionTable{dbClient: dbClient.DB}
steps.s2AssetsTable = &AssetTable{dbClient: dbClient.DB}
@@ -187,6 +189,8 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.FirstInstance.externalSecure = config.ExternalSecure
steps.FirstInstance.externalPort = config.ExternalPort
steps.FirstInstance.defaultPaths = config.Login.DefaultPaths
steps.FirstInstance.httpClient = httpClient
steps.FirstInstance.denylist = config.HTTPClient.DenyList
steps.s5LastFailed = &LastFailed{dbClient: dbClient.DB}
steps.s6OwnerRemoveColumns = &OwnerRemoveColumns{dbClient: dbClient.DB}
@@ -315,7 +319,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
}
}
commands, _, _, _ := startCommandsQueries(ctx, eventstoreClient, eventstoreV4, dbClient, masterKey, config)
commands, _, _, _ := startCommandsQueries(ctx, eventstoreClient, eventstoreV4, dbClient, masterKey, config, httpClient)
steps.s59SetupWebkeys = &SetupWebkeys{eventstore: eventstoreClient, commands: commands}
repeatableSteps := []migration.RepeatableMigration{
@@ -454,6 +458,7 @@ func startCommandsQueries(
dbClient *database.DB,
masterKey string,
config *Config,
httpClient *http.Client,
) (
*command.Commands,
*query.Queries,
@@ -572,7 +577,7 @@ func startCommandsQueries(
keys.SAML,
keys.Target,
keys.OIDC,
&http.Client{},
httpClient,
permissionCheck,
sessionTokenVerifier,
config.OIDC.DefaultAccessTokenLifetime,
@@ -580,7 +585,7 @@ func startCommandsQueries(
config.OIDC.DefaultRefreshTokenIdleExpiration,
config.DefaultInstance.SecretGenerators,
config.Login.DefaultPaths,
config.Executions.DenyList,
config.HTTPClient.DenyList,
)
logging.OnError(ctx, err).Fatal("unable to start commands")
@@ -610,6 +615,7 @@ func startCommandsQueries(
keys.SMTP,
keys.SMS,
q,
httpClient,
)
return commands, queries, adminView, authView