diff --git a/cmd/defaults.yaml b/cmd/defaults.yaml
index cef9c0382..82fef4540 100644
--- a/cmd/defaults.yaml
+++ b/cmd/defaults.yaml
@@ -39,16 +39,15 @@ Telemetry:
# Port ZITADEL will listen on
Port: 8080 # ZITADEL_PORT
-# Port ZITADEL is exposed on, it can differ from port e.g. if you proxy the traffic
-# !!! Changing this after the initial setup breaks your system !!!
+# ExternalPort is the port on which end users access ZITADEL.
+# It can differ from Port e.g. if a reverse proxy forwards the traffic to ZITADEL
+# Read more about external access: https://zitadel.com/docs/self-hosting/manage/custom-domain
ExternalPort: 8080 # ZITADEL_EXTERNALPORT
-# Domain/hostname ZITADEL is exposed externally
-# !!! Changing this after the initial setup breaks your system !!!
+# ExternalPort is the domain on which end users access ZITADEL.
+# Read more about external access: https://zitadel.com/docs/self-hosting/manage/custom-domain
ExternalDomain: localhost # ZITADEL_EXTERNALDOMAIN
-# specifies if ZITADEL is exposed externally through TLS
-# this must be set to true even if TLS is not enabled on ZITADEL itself
-# but TLS traffic is terminated on a reverse proxy
-# !!! Changing this after the initial setup breaks your system !!!
+# ExternalSecure specifies if ZITADEL is exposed externally using HTTPS or HTTP.
+# Read more about external access: https://zitadel.com/docs/self-hosting/manage/custom-domain
ExternalSecure: true # ZITADEL_EXTERNALSECURE
TLS:
# If enabled, ZITADEL will serve all traffic over TLS (HTTPS and gRPC)
diff --git a/cmd/ready/config.go b/cmd/ready/config.go
index ea4c1290d..488dbe27d 100644
--- a/cmd/ready/config.go
+++ b/cmd/ready/config.go
@@ -9,12 +9,14 @@ import (
internal_authz "github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/config/hook"
+ "github.com/zitadel/zitadel/internal/config/network"
"github.com/zitadel/zitadel/internal/domain"
)
type Config struct {
Log *logging.Config
Port uint16
+ TLS network.TLS
}
func MustNewConfig(v *viper.Viper) *Config {
diff --git a/cmd/ready/ready.go b/cmd/ready/ready.go
index 679a1ac56..2b96db650 100644
--- a/cmd/ready/ready.go
+++ b/cmd/ready/ready.go
@@ -1,6 +1,7 @@
package ready
import (
+ "crypto/tls"
"net"
"net/http"
"os"
@@ -26,7 +27,13 @@ func New() *cobra.Command {
}
func ready(config *Config) bool {
- res, err := http.Get("http://" + net.JoinHostPort("localhost", strconv.Itoa(int(config.Port))) + "/debug/ready")
+ scheme := "https"
+ if !config.TLS.Enabled {
+ scheme = "http"
+ }
+ // Checking the TLS cert is not in the scope of the readiness check
+ httpClient := http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}}
+ res, err := httpClient.Get(scheme + "://" + net.JoinHostPort("localhost", strconv.Itoa(int(config.Port))) + "/debug/ready")
if err != nil {
logging.WithError(err).Warn("ready check failed")
return false
diff --git a/cmd/start/start.go b/cmd/start/start.go
index 70f19b4e1..03651dc3e 100644
--- a/cmd/start/start.go
+++ b/cmd/start/start.go
@@ -367,16 +367,16 @@ func startAPIs(
return fmt.Errorf("error starting admin repo: %w", err)
}
- if err := apis.RegisterServer(ctx, system.CreateServer(commands, queries, config.Database.DatabaseName(), config.DefaultInstance, config.ExternalDomain)); err != nil {
+ if err := apis.RegisterServer(ctx, system.CreateServer(commands, queries, config.Database.DatabaseName(), config.DefaultInstance, config.ExternalDomain), tlsConfig); err != nil {
return err
}
- if err := apis.RegisterServer(ctx, admin.CreateServer(config.Database.DatabaseName(), commands, queries, config.SystemDefaults, config.ExternalSecure, keys.User, config.AuditLogRetention)); err != nil {
+ if err := apis.RegisterServer(ctx, admin.CreateServer(config.Database.DatabaseName(), commands, queries, config.SystemDefaults, config.ExternalSecure, keys.User, config.AuditLogRetention), tlsConfig); err != nil {
return err
}
- if err := apis.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, keys.User, config.ExternalSecure)); err != nil {
+ if err := apis.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, keys.User, config.ExternalSecure), tlsConfig); err != nil {
return err
}
- if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, keys.User, config.ExternalSecure)); err != nil {
+ if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, keys.User, config.ExternalSecure), tlsConfig); err != nil {
return err
}
if err := apis.RegisterService(ctx, user_v2.CreateServer(commands, queries, keys.User, keys.IDPConfig, idp.CallbackURL(config.ExternalSecure), idp.SAMLRootURL(config.ExternalSecure))); err != nil {
diff --git a/docs/docs/self-hosting/manage/custom-domain.md b/docs/docs/self-hosting/manage/custom-domain.md
index ffff20772..57da59698 100644
--- a/docs/docs/self-hosting/manage/custom-domain.md
+++ b/docs/docs/self-hosting/manage/custom-domain.md
@@ -1,31 +1,65 @@
---
-title: Run ZITADEL on a Custom Domain
-sidebar: Custom Domain
+title: External ZITADEL Access
+sidebar_label: Instance Not Found
---
-# Run ZITADEL on a (Sub)domain of Your Choice
+## Why do I get an "Instance not found" error?
+
+Also, ZITADEL has the [concept of virtual instances](/concepts/structure/instance#multiple-virtual-instances).
+It uses a requests Host header to determine which virtual instance to use.
+This is useful for multi-tenancy and resource sharing, for example in SaaS scenarios.
+For most cases however, ZITADEL should run on exactly one domain.
This guide assumes you are already familiar with [configuring ZITADEL](./configure).
-You most probably need to configure these fields for making ZITADEL work on your custom domain.
-
## Standard Config
-For security reasons, ZITADEL only serves requests sent to the expected protocol, host and port.
-If not using localhost as ExternalDomain, ExternalSecure must be true and you need to serve the ZITADEL console over HTTPS.
+ZITADEL only serves requests sent to the expected protocol, host and port.
+For local testing purposes, you can use following configuration:
```yaml
-ExternalSecure: true
-ExternalDomain: 'zitadel.my.domain'
-ExternalPort: 443
+ExternalDomain: localhost
+ExternalPort: 8080
+ExternalSecure: false
```
-## Database Initialization Steps Config
+For productive setups however, we recommend using HTTPS and a custom domain:
-ZITADEL creates random subdomains for each instance created.
-However, for the first instance, this is most probably not the desired behavior.
-In this case the `ExternalDomain`-field of the configuration is used.
+```yaml
+ExternalDomain: 'zitadel.my.domain'
+ExternalPort: 443
+ExternalSecure: true
+```
-## Example
+## Changing ExternalDomain, ExternalPort or ExternalSecure
+
+You can change the ExternalDomain, ExternalPort and ExternalSecure configuration options at any time.
+However, for ZITADEL to be able to pick up the changes, [you need to rerun ZITADELs setup phase](/self-hosting/manage/updating_scaling#the-setup-phase).
+
+## Running ZITADEL behind a Reverse Proxy
+
+If you run ZITADEL behind a reverse proxy, you need to ensure that it sends the correct request headers to ZITADEL.
+The proxy must either ensure that
+- the original *Host* header value is assigned to the *Forwarded* headers host directive.
+- the original requests *Host* header value is unchanged by the proxy.
+
+Check out the [reverse proxy configuration examples](/self-hosting/manage/reverseproxy/reverse_proxy) for more information.
+
+## Organization Domains
+
+Note that by default, you cannot access ZITADEL at an organizations domain.
+Organization level domains [are intended for routing users by their login methods to their correct organization](http://localhost:3000/docs/guides/solution-scenarios/domain-discovery).
+
+However, if you want to access ZITADEL at an organization domain, [you can add additional domains using the System API](/apis/resources/system/system-service-add-domain#adds-a-domain-to-an-instance).
+Be aware that you won't automatically have the organizations context when you access ZITADEL like this.
+
+## Generated Subdomains
+
+ZITADEL creates random subdomains for [each new virtual instance](/concepts/structure/instance#multiple-virtual-instances).
+You can immediately access the ZITADEL Console an APIs using these subdomains without further actions.
+
+## More Information
+
+- [Check out the production-near loadbalancing example with Traefik](/self-hosting/deploy/loadbalancing-example)
+- [Explore some concrete proxy configuration examples for ZITADEL using the domain 127.0.0.1.sslip.io](/self-hosting/manage/reverseproxy/reverse_proxy)
-Go to the [loadbalancing example with Traefik](/docs/self-hosting/deploy/loadbalancing-example) for seeing a working example configuration.
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_cloudflare_tunnel.mdx b/docs/docs/self-hosting/manage/reverseproxy/_cloudflare_tunnel.mdx
deleted file mode 100644
index ea810b119..000000000
--- a/docs/docs/self-hosting/manage/reverseproxy/_cloudflare_tunnel.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-:::caution
-
-[The Cloudflare tunnel client currently has an issue which allows it not to force HTTP/2 usage towards the origin.](https://github.com/cloudflare/cloudflared/issues/682)
\ No newline at end of file
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_httpd.mdx b/docs/docs/self-hosting/manage/reverseproxy/_httpd.mdx
deleted file mode 100644
index b30d5494b..000000000
--- a/docs/docs/self-hosting/manage/reverseproxy/_httpd.mdx
+++ /dev/null
@@ -1,166 +0,0 @@
-## TLS mode external
-
-```
-LoadModule mpm_event_module modules/mod_mpm_event.so
-LoadModule authn_file_module modules/mod_authn_file.so
-LoadModule authn_core_module modules/mod_authn_core.so
-LoadModule authz_host_module modules/mod_authz_host.so
-LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
-LoadModule authz_user_module modules/mod_authz_user.so
-LoadModule authz_core_module modules/mod_authz_core.so
-LoadModule access_compat_module modules/mod_access_compat.so
-LoadModule auth_basic_module modules/mod_auth_basic.so
-LoadModule reqtimeout_module modules/mod_reqtimeout.so
-LoadModule filter_module modules/mod_filter.so
-LoadModule mime_module modules/mod_mime.so
-LoadModule log_config_module modules/mod_log_config.so
-LoadModule env_module modules/mod_env.so
-LoadModule headers_module modules/mod_headers.so
-LoadModule setenvif_module modules/mod_setenvif.so
-LoadModule version_module modules/mod_version.so
-LoadModule proxy_module modules/mod_proxy.so
-LoadModule proxy_http_module modules/mod_proxy_http.so
-LoadModule ssl_module modules/mod_ssl.so
-LoadModule proxy_http2_module modules/mod_proxy_http2.so
-LoadModule unixd_module modules/mod_unixd.so
-LoadModule status_module modules/mod_status.so
-LoadModule autoindex_module modules/mod_autoindex.so
-LoadModule dir_module modules/mod_dir.so
-LoadModule alias_module modules/mod_alias.so
-LoadModule rewrite_module modules/mod_rewrite.so
-
-ServerRoot "/usr/local/apache2"
-LogLevel warn
-ErrorLog /proc/self/fd/2
-CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
-
-ServerName my.domain
-Listen 80
-Listen 443
-
-SSLRandomSeed startup builtin
-SSLRandomSeed connect builtin
-
-
- ServerName my.domain
- RewriteEngine On
- RewriteCond %{HTTPS} off
- RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
-
-
-
- ServerName my.domain
- ProxyPreserveHost On
- SSLCertificateFile /certs/server.crt
- SSLCertificateKeyFile /certs/server.key
- ProxyPass / h2c://localhost:8080/
- ProxyPassReverse / h2c://localhost:8080/
-
-```
-
-## TLS mode enabled
-
-```
-LoadModule mpm_event_module modules/mod_mpm_event.so
-LoadModule authn_file_module modules/mod_authn_file.so
-LoadModule authn_core_module modules/mod_authn_core.so
-LoadModule authz_host_module modules/mod_authz_host.so
-LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
-LoadModule authz_user_module modules/mod_authz_user.so
-LoadModule authz_core_module modules/mod_authz_core.so
-LoadModule access_compat_module modules/mod_access_compat.so
-LoadModule auth_basic_module modules/mod_auth_basic.so
-LoadModule reqtimeout_module modules/mod_reqtimeout.so
-LoadModule filter_module modules/mod_filter.so
-LoadModule mime_module modules/mod_mime.so
-LoadModule log_config_module modules/mod_log_config.so
-LoadModule env_module modules/mod_env.so
-LoadModule headers_module modules/mod_headers.so
-LoadModule setenvif_module modules/mod_setenvif.so
-LoadModule version_module modules/mod_version.so
-LoadModule proxy_module modules/mod_proxy.so
-LoadModule proxy_http_module modules/mod_proxy_http.so
-LoadModule ssl_module modules/mod_ssl.so
-LoadModule proxy_http2_module modules/mod_proxy_http2.so
-LoadModule unixd_module modules/mod_unixd.so
-LoadModule status_module modules/mod_status.so
-LoadModule autoindex_module modules/mod_autoindex.so
-LoadModule dir_module modules/mod_dir.so
-LoadModule alias_module modules/mod_alias.so
-LoadModule rewrite_module modules/mod_rewrite.so
-LoadModule http2_module modules/mod_http2.so
-
-ServerRoot "/usr/local/apache2"
-LogLevel debug
-ErrorLog /proc/self/fd/2
-CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
-
-ServerName my.domain
-Listen 80
-Listen 443
-
-SSLRandomSeed startup builtin
-SSLRandomSeed connect builtin
-
-
- RewriteEngine On
- RewriteCond %{HTTPS} off
- RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
-
-
-
- ProxyPreserveHost On
- SSLEngine on
- SSLProxyEngine on
- SSLCertificateFile /certs/server.crt
- SSLCertificateKeyFile /certs/server.key
- ProxyPass / h2://localhost:8080/
-
-```
-
-## TLS mode disabled
-
-```
-LoadModule mpm_event_module modules/mod_mpm_event.so
-LoadModule authn_file_module modules/mod_authn_file.so
-LoadModule authn_core_module modules/mod_authn_core.so
-LoadModule authz_host_module modules/mod_authz_host.so
-LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
-LoadModule authz_user_module modules/mod_authz_user.so
-LoadModule authz_core_module modules/mod_authz_core.so
-LoadModule access_compat_module modules/mod_access_compat.so
-LoadModule auth_basic_module modules/mod_auth_basic.so
-LoadModule reqtimeout_module modules/mod_reqtimeout.so
-LoadModule filter_module modules/mod_filter.so
-LoadModule mime_module modules/mod_mime.so
-LoadModule log_config_module modules/mod_log_config.so
-LoadModule env_module modules/mod_env.so
-LoadModule headers_module modules/mod_headers.so
-LoadModule setenvif_module modules/mod_setenvif.so
-LoadModule version_module modules/mod_version.so
-LoadModule proxy_module modules/mod_proxy.so
-LoadModule proxy_http_module modules/mod_proxy_http.so
-LoadModule ssl_module modules/mod_ssl.so
-LoadModule proxy_http2_module modules/mod_proxy_http2.so
-LoadModule unixd_module modules/mod_unixd.so
-LoadModule status_module modules/mod_status.so
-LoadModule autoindex_module modules/mod_autoindex.so
-LoadModule dir_module modules/mod_dir.so
-LoadModule alias_module modules/mod_alias.so
-LoadModule rewrite_module modules/mod_rewrite.so
-
-ServerRoot "/usr/local/apache2"
-LogLevel warn
-ErrorLog /proc/self/fd/2
-CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
-
-ServerName my.domain
-Listen 80
-
-
- ServerName my.domain
- ProxyPreserveHost On
- ProxyPass / h2c://localhost:8080/
- ProxyPassReverse / h2c://localhost:8080/
-
-```
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_more.mdx b/docs/docs/self-hosting/manage/reverseproxy/_more.mdx
deleted file mode 100644
index d88d76c23..000000000
--- a/docs/docs/self-hosting/manage/reverseproxy/_more.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
-## More information
-
-- [You can read here about the TLS Modes](/self-hosting/manage/tls_modes)
-- [And here about how ZITADEL makes use of HTTP/2](/self-hosting/manage/http2)
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_nginx.mdx b/docs/docs/self-hosting/manage/reverseproxy/_nginx.mdx
deleted file mode 100644
index aa738ffc6..000000000
--- a/docs/docs/self-hosting/manage/reverseproxy/_nginx.mdx
+++ /dev/null
@@ -1,95 +0,0 @@
-## TLS mode external
-
-```
-worker_processes 1;
-events {
- worker_connections 1024;
-}
-
-http {
- server {
- listen 443;
-
- ssl_certificate ssl/certificate.pem;
- ssl_certificate_key ssl/key.pem;
-
- location / {
- grpc_pass grpc://localhost:8080;
- grpc_set_header Host $host;
- }
- }
-}
-```
-
-:::info
-If another port than the default HTTPS port 443 is used replace
-
-` grpc_set_header Host $host;`
-
-with
-
-` grpc_set_header Host $host:$server_port;`
-:::
-
-## TLS mode enabled
-
-```
-worker_processes 1;
-events {
- worker_connections 1024;
-}
-
-http {
- server {
- listen 443;
-
- ssl_certificate ssl/certificate.pem;
- ssl_certificate_key ssl/key.pem;
-
- location / {
- grpc_pass grpcs://localhost:8080;
- grpc_set_header Host $host;
- }
- }
-}
-```
-
-:::info
-If another port than the default HTTPS port 443 is used replace
-
-` grpc_set_header Host $host;`
-
-with
-
-` grpc_set_header Host $host:$server_port;`
-:::
-
-## TLS mode disabled
-
-```
-worker_processes 1;
-events {
- worker_connections 1024;
-}
-
-http {
- server {
- listen 80;
-
- location / {
- grpc_pass grpc://localhost:8080;
- grpc_set_header Host $host;
- }
- }
-}
-```
-
-:::info
-If another port than the default HTTP port 80 is used replace
-
-` grpc_set_header Host $host;`
-
-with
-
-` grpc_set_header Host $host:$server_port;`
-:::
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx
new file mode 100644
index 000000000..e3e2a9940
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx
@@ -0,0 +1,2 @@
+- [Read more about ZITADELs TLS Modes](/self-hosting/manage/tls_modes)
+- [Read more about how ZITADEL uses HTTP/2](/self-hosting/manage/http2)
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx
new file mode 100644
index 000000000..3200ddf37
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx
@@ -0,0 +1,16 @@
+import CodeBlock from '@theme/CodeBlock';
+import ComposeYaml from "!!raw-loader!./docker-compose.yaml";
+
+<>With these examples, you create and run a minimal {props.link} configuration for ZITADEL with Docker Compose.
+Whereas the guide focuses on the configuration for {props.link}, you can inspect the configurations for ZITADEL and the database in the base Docker Compose file.>
+
+ base docker-compose.yaml
+ {ComposeYaml}
+
+
+<>For running {props.link}, you will extend the base Docker Compose file with the {props.link} specific Docker Compose file.>
+
+
+ specific docker-compose.yaml
+ {props.compose}
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_tls_mode.mdx b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_tls_mode.mdx
new file mode 100644
index 000000000..f4a780473
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_tls_mode.mdx
@@ -0,0 +1,90 @@
+import CodeBlock from '@theme/CodeBlock';
+
+export const Description = ({mode, link}) => {
+ let desc
+ switch (mode) {
+ case "disabled":
+ desc = <>Neither {link} nor ZITADEL terminates TLS.
+ Nevertheless, {link} forwards unencrypted HTTP/2 traffic, aka h2c, to ZITADEL.>;
+ break;
+ case "external":
+ desc = <>{link} terminates TLS and forwards the requests to ZITADEL via unencrypted h2c.
+ This example uses an unsafe self-signed certificate for {link}>;
+ break;
+ case "enabled":
+ desc = <>{link} terminates TLS and forwards the requests to ZITADEL via encrypted HTTP/2.
+ This example uses an unsafe self-signed certificate for {link} and the same for ZITADEL.>;
+ break;
+ }
+ return (
+ <>
+ {desc}
+ <>By executing the commands below, you will download the files necessary to run ZITADEL behind {link} with the following config:>
+ >)
+}
+
+export const Commands = ({mode, name, lower, configfilename}) => {
+ let genCert = '# Generate a self signed certificate and key.\nopenssl req -x509 -batch -subj "/CN=127.0.0.1.sslip.io/O=ZITADEL Demo" -nodes -newkey rsa:2048 -keyout ./selfsigned.key -out ./selfsigned.crt\n\n';
+ let connPort = "443"
+ let connInsecureFlag = "--insecure "
+ let connScheme = "https"
+ let grpcPlainTextFlag = ""
+ if (mode === "disabled") {
+ genCert = ''
+ connPort = "80"
+ grpcPlainTextFlag = "--plaintext "
+ connScheme = "http"
+ // We only need that flag for TLS connections with the self-signed cert
+ connInsecureFlag = ""
+ }
+ return (
+
+
+ {'# Download the configuration files.'}{'\n'}
+ {'export ZITADEL_CONFIG_FILES=https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/manage/reverseproxy\n'}
+ {`wget $\{ZITADEL_CONFIG_FILES\}/docker-compose.yaml -O docker-compose-base.yaml`}{'\n'}
+ {'wget $\{ZITADEL_CONFIG_FILES\}/'}{lower}{'/docker-compose.yaml -O docker-compose-'}{lower}{'.yaml'}{'\n'}
+ {'wget $\{ZITADEL_CONFIG_FILES\}/'}{lower}{'/'}{configfilename}{' -O '}{configfilename}{'\n'}
+ {'\n'}
+ {genCert}
+ {'# Run the database, ZITADEL and '}{name}{'.'}{'\n'}
+ {'docker compose --file docker-compose-base.yaml --file docker-compose-'}{lower}{'.yaml up --detach proxy-'}{mode}{'-tls'}{'\n'}
+ {'\n'}
+ {'# Test that gRPC and HTTP APIs work. Empty brackets like {} means success.\n'}
+ {'sleep 3\n'}
+ {'grpcurl '}{connInsecureFlag}{grpcPlainTextFlag}{'127.0.0.1.sslip.io:'}{connPort}{' zitadel.admin.v1.AdminService/Healthz\n'}
+ {'curl '}{connInsecureFlag}{connScheme}{'://127.0.0.1.sslip.io:'}{connPort}{'/admin/v1/healthz\n'}
+
+
+ )
+}
+
+export const LoginURL = ({mode}) => {
+ let scheme = "https";
+ if (mode === "disabled") {
+ scheme = "http"
+ }
+ const url = scheme + "://127.0.0.1.sslip.io/ui/console";
+ return {url}
+}
+
+
+
+
+ {props.configfilename}
+ {props.configfilecontent}
+
+
+
+
+<>When the docker compose command exits successfully, go to and log in:>
+
+- **username**: *zitadel-admin@zitadel.127.0.0.1.sslip.io*
+- **password**: *Password1!*
+
+If the console loads normally, you know that the HTTP and gRPC-Web and gRPC APIs are working correctly.
+
+
+ {'# You can now stop the database, ZITADEL and '}{props.providername}{'.'}{'\n'}
+ {'docker compose --file docker-compose-base.yaml --file docker-compose-'}{props.lower}{'.yaml down'}{'\n'}
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_traefik.mdx b/docs/docs/self-hosting/manage/reverseproxy/_traefik.mdx
deleted file mode 100644
index f519e4523..000000000
--- a/docs/docs/self-hosting/manage/reverseproxy/_traefik.mdx
+++ /dev/null
@@ -1,150 +0,0 @@
-## TLS mode external
-
-```yaml
-entrypoints:
- web:
- address: ":80"
- websecure:
- address: ":443"
-tls:
- stores:
- default:
- defaultCertificate:
-providers:
- file:
- filename: /etc/traefik/traefik.yaml
-http:
- middlewares:
- zitadel:
- headers:
- isDevelopment: false
- allowedHosts:
- - 'localhost'
- customRequestHeaders:
- :authority: 'localhost'
- redirect-to-https:
- redirectScheme:
- scheme: https
- port: 443
- permanent: true
- routers:
- router0:
- entryPoints:
- - web
- middlewares:
- - redirect-to-https
- rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)'
- service: zitadel
- router1:
- entryPoints:
- - websecure
- service: zitadel
- middlewares:
- - zitadel
- rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)'
- tls:
- domains:
- - main: "localhost"
- sans:
- - "*.localhost"
- - "localhost"
- services:
- zitadel:
- loadBalancer:
- servers:
- - url: h2c://localhost:8080
- passHostHeader: true
-```
-
-## TLS mode enabled
-
-```yaml
-entrypoints:
- web:
- address: ":80"
- websecure:
- address: ":443"
-tls:
- stores:
- default:
- defaultCertificate:
-providers:
- file:
- filename: /etc/traefik/traefik.yaml
-http:
- middlewares:
- zitadel:
- headers:
- isDevelopment: false
- allowedHosts:
- - 'localhost'
- customRequestHeaders:
- :authority: 'localhost'
- redirect-to-https:
- redirectScheme:
- scheme: https
- port: 443
- permanent: true
- routers:
- router0:
- entryPoints:
- - web
- middlewares:
- - redirect-to-https
- rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)'
- service: zitadel
- # The actual ZITADEL router
- router1:
- entryPoints:
- - websecure
- service: zitadel
- middlewares:
- - zitadel
- rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)'
- tls:
- domains:
- - main: "localhost"
- sans:
- - "*.localhost"
- - "localhost"
- services:
- zitadel:
- loadBalancer:
- servers:
- - url: https://localhost:8080
- passHostHeader: true
-```
-
-## TLS mode disabled
-
-```yaml
-entrypoints:
- web:
- address: ":80"
-providers:
- file:
- filename: /etc/traefik/traefik.yaml
-http:
- middlewares:
- zitadel:
- headers:
- isDevelopment: false
- allowedHosts:
- - 'localhost'
- customRequestHeaders:
- :authority: 'localhost'
- routers:
- router0:
- entryPoints:
- - web
- middlewares:
- - redirect-to-https
- rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)'
- service: zitadel
- services:
- zitadel:
- loadBalancer:
- servers:
- - url: h2c://localhost:8080
- passHostHeader: true
-```
diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx b/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx
new file mode 100644
index 000000000..20a00dae9
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx
@@ -0,0 +1,38 @@
+---
+title: Configure ZITADEL with Caddy
+sidebar_label: Caddy
+---
+
+import ProxyGuideOverview from '../_proxy_guide_overview.mdx';
+import ProxyGuideTLSMode from '../_proxy_guide_tls_mode.mdx';
+import ProxyGuideMore from '../_proxy_guide_more.mdx';
+import Compose from "!!raw-loader!./docker-compose.yaml";
+import ConfigDisabled from "!!raw-loader!./disabled-tls.Caddyfile";
+import ConfigExternal from "!!raw-loader!./external-tls.Caddyfile";
+import ConfigEnabled from "!!raw-loader!./enabled-tls.Caddyfile";
+
+export const providername = 'Caddy';
+export const lower = "caddy";
+export const link = {providername}
+
+
+
+You can either setup your environment for TLS mode external or TLS mode enabled.
+
+
+
+## TLS mode external
+
+
+
+## TLS mode enabled
+
+
+
+## More Information
+
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/disabled-tls.Caddyfile b/docs/docs/self-hosting/manage/reverseproxy/caddy/disabled-tls.Caddyfile
new file mode 100644
index 000000000..db5b3eb94
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/disabled-tls.Caddyfile
@@ -0,0 +1,3 @@
+http://127.0.0.1.sslip.io {
+ reverse_proxy h2c://zitadel-disabled-tls:8080
+}
diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/caddy/docker-compose.yaml
new file mode 100644
index 000000000..f3a724053
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/docker-compose.yaml
@@ -0,0 +1,37 @@
+version: '3.8'
+
+services:
+
+ proxy-disabled-tls:
+ image: "caddy:2.7.5-alpine"
+ volumes:
+ - "./disabled-tls.Caddyfile:/etc/caddy/Caddyfile:ro"
+ ports:
+ - "80:80"
+ depends_on:
+ zitadel-disabled-tls:
+ condition: 'service_healthy'
+
+ proxy-external-tls:
+ image: "caddy:2.7.5-alpine"
+ volumes:
+ - "./external-tls.Caddyfile:/etc/caddy/Caddyfile:ro"
+ - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro"
+ - "./selfsigned.key:/etc/certs/selfsigned.key:ro"
+ ports:
+ - "443:443"
+ depends_on:
+ zitadel-external-tls:
+ condition: 'service_healthy'
+
+ proxy-enabled-tls:
+ image: "caddy:2.7.5-alpine"
+ volumes:
+ - "./enabled-tls.Caddyfile:/etc/caddy/Caddyfile:ro"
+ - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro"
+ - "./selfsigned.key:/etc/certs/selfsigned.key:ro"
+ ports:
+ - "443:443"
+ depends_on:
+ zitadel-enabled-tls:
+ condition: 'service_healthy'
diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/enabled-tls.Caddyfile b/docs/docs/self-hosting/manage/reverseproxy/caddy/enabled-tls.Caddyfile
new file mode 100644
index 000000000..5040b1daa
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/enabled-tls.Caddyfile
@@ -0,0 +1,8 @@
+https://127.0.0.1.sslip.io {
+ tls /etc/certs/selfsigned.crt /etc/certs/selfsigned.key
+ reverse_proxy https://zitadel-enabled-tls:8080 {
+ transport http {
+ tls_insecure_skip_verify
+ }
+ }
+}
diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/external-tls.Caddyfile b/docs/docs/self-hosting/manage/reverseproxy/caddy/external-tls.Caddyfile
new file mode 100644
index 000000000..867b9f95b
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/external-tls.Caddyfile
@@ -0,0 +1,4 @@
+https://127.0.0.1.sslip.io {
+ tls /etc/certs/selfsigned.crt /etc/certs/selfsigned.key
+ reverse_proxy h2c://zitadel-external-tls:8080
+}
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_cloudflare.mdx b/docs/docs/self-hosting/manage/reverseproxy/cloudflare/cloudflare.mdx
similarity index 92%
rename from docs/docs/self-hosting/manage/reverseproxy/_cloudflare.mdx
rename to docs/docs/self-hosting/manage/reverseproxy/cloudflare/cloudflare.mdx
index d18431107..7810b909c 100644
--- a/docs/docs/self-hosting/manage/reverseproxy/_cloudflare.mdx
+++ b/docs/docs/self-hosting/manage/reverseproxy/cloudflare/cloudflare.mdx
@@ -1,3 +1,8 @@
+---
+title: Configure ZITADEL with Cloudflare
+sidebar_label: Cloudflare
+---
+
## Settings
- [Make sure HTTP/2 is enabled](https://support.cloudflare.com/hc/en-us/articles/200168076-Understanding-Cloudflare-HTTP-2-and-HTTP-3-Support)
diff --git a/docs/docs/self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel.mdx b/docs/docs/self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel.mdx
new file mode 100644
index 000000000..829123637
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel.mdx
@@ -0,0 +1,8 @@
+---
+title: Configure ZITADEL with Cloudflare Tunnel
+sidebar_label: Cloudflare Tunnel
+---
+
+:::caution
+
+[The Cloudflare tunnel client currently has an issue which disallows it to force HTTP/2 usage towards the origin.](https://github.com/cloudflare/cloudflared/issues/682)
diff --git a/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml
new file mode 100644
index 000000000..885713731
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml
@@ -0,0 +1,90 @@
+version: '3.8'
+
+services:
+
+ zitadel-disabled-tls:
+ extends:
+ service: zitadel-init
+ command: 'start-from-setup --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml'
+ environment:
+ - ZITADEL_EXTERNALPORT=80
+ - ZITADEL_EXTERNALSECURE=false
+ - ZITADEL_TLS_ENABLED=false
+ depends_on:
+ zitadel-init:
+ condition: 'service_completed_successfully'
+ db:
+ condition: 'service_healthy'
+
+ zitadel-external-tls:
+ extends:
+ service: zitadel-init
+ command: 'start-from-setup --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml'
+ environment:
+ - ZITADEL_EXTERNALPORT=443
+ - ZITADEL_EXTERNALSECURE=true
+ - ZITADEL_TLS_ENABLED=false
+ depends_on:
+ zitadel-init:
+ condition: 'service_completed_successfully'
+ db:
+ condition: 'service_healthy'
+
+ zitadel-enabled-tls:
+ extends:
+ service: zitadel-init
+ command: 'start-from-setup --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml'
+ environment:
+ - ZITADEL_EXTERNALPORT=443
+ - ZITADEL_EXTERNALSECURE=true
+ - ZITADEL_TLS_ENABLED=true
+ - ZITADEL_TLS_CERTPATH=/etc/certs/selfsigned.crt
+ - ZITADEL_TLS_KEYPATH=/etc/certs/selfsigned.key
+ volumes:
+ - ./selfsigned.crt:/etc/certs/selfsigned.crt
+ - ./selfsigned.key:/etc/certs/selfsigned.key
+ depends_on:
+ zitadel-init:
+ condition: 'service_completed_successfully'
+ db:
+ condition: 'service_healthy'
+
+ zitadel-init:
+ user: '$UID'
+ image: '${ZITADEL_IMAGE:-ghcr.io/zitadel/zitadel:latest}'
+ command: 'init --config /zitadel.yaml'
+ depends_on:
+ db:
+ condition: 'service_healthy'
+ environment:
+ # Using an external domain other than localhost proofs, that the proxy configuration works.
+ # If ZITADEL can't resolve a requests original host to this domain,
+ # it will return a 404 Instance not found error.
+ - ZITADEL_EXTERNALDOMAIN=127.0.0.1.sslip.io
+ # ZITADEL accesses the database via the docker network.
+ - ZITADEL_DATABASE_COCKROACH_HOST=db
+ # In case something doesn't work as expected,
+ # it can be handy to be able to read the access logs.
+ - ZITADEL_LOGSTORE_ACCESS_STDOUT_ENABLED=true
+ # For convenience, ZITADEL should not ask to change the initial admin users password.
+ - ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED=false
+ healthcheck:
+ test: ["CMD", "/app/zitadel", "ready"]
+ interval: '10s'
+ timeout: '5s'
+ retries: 5
+ start_period: '10s'
+
+ db:
+ restart: 'always'
+ image: 'cockroachdb/cockroach:latest'
+ command: 'start-single-node --insecure --http-addr :9090'
+ healthcheck:
+ test: ['CMD', 'curl', '-f', 'http://localhost:9090/health?ready=1']
+ interval: '10s'
+ timeout: '30s'
+ retries: 5
+ start_period: '20s'
+ ports:
+ - "26257:26257"
+ - "9090:9090"
diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/httpd/docker-compose.yaml
new file mode 100644
index 000000000..72e06b976
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/docker-compose.yaml
@@ -0,0 +1,37 @@
+version: '3.8'
+
+services:
+
+ proxy-disabled-tls:
+ image: "httpd:2.4.58-alpine"
+ volumes:
+ - "./httpd-disabled-tls.conf:/usr/local/apache2/conf/httpd.conf"
+ ports:
+ - "80:80"
+ depends_on:
+ zitadel-disabled-tls:
+ condition: 'service_healthy'
+
+ proxy-external-tls:
+ image: "httpd:2.4.58-alpine"
+ volumes:
+ - "./httpd-external-tls.conf:/usr/local/apache2/conf/httpd.conf"
+ - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro"
+ - "./selfsigned.key:/etc/certs/selfsigned.key:ro"
+ ports:
+ - "443:443"
+ depends_on:
+ zitadel-external-tls:
+ condition: 'service_healthy'
+
+ proxy-enabled-tls:
+ image: "httpd:2.4.58-alpine"
+ volumes:
+ - "./httpd-enabled-tls.conf:/usr/local/apache2/conf/httpd.conf"
+ - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro"
+ - "./selfsigned.key:/etc/certs/selfsigned.key:ro"
+ ports:
+ - "443:443"
+ depends_on:
+ zitadel-enabled-tls:
+ condition: 'service_healthy'
diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-disabled-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-disabled-tls.conf
new file mode 100644
index 000000000..6d745f34e
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-disabled-tls.conf
@@ -0,0 +1,39 @@
+LoadModule mpm_event_module modules/mod_mpm_event.so
+LoadModule authn_file_module modules/mod_authn_file.so
+LoadModule authn_core_module modules/mod_authn_core.so
+LoadModule authz_host_module modules/mod_authz_host.so
+LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
+LoadModule authz_user_module modules/mod_authz_user.so
+LoadModule authz_core_module modules/mod_authz_core.so
+LoadModule access_compat_module modules/mod_access_compat.so
+LoadModule auth_basic_module modules/mod_auth_basic.so
+LoadModule reqtimeout_module modules/mod_reqtimeout.so
+LoadModule filter_module modules/mod_filter.so
+LoadModule mime_module modules/mod_mime.so
+LoadModule log_config_module modules/mod_log_config.so
+LoadModule env_module modules/mod_env.so
+LoadModule headers_module modules/mod_headers.so
+LoadModule setenvif_module modules/mod_setenvif.so
+LoadModule version_module modules/mod_version.so
+LoadModule proxy_module modules/mod_proxy.so
+LoadModule proxy_http_module modules/mod_proxy_http.so
+LoadModule ssl_module modules/mod_ssl.so
+LoadModule proxy_http2_module modules/mod_proxy_http2.so
+LoadModule unixd_module modules/mod_unixd.so
+LoadModule status_module modules/mod_status.so
+LoadModule autoindex_module modules/mod_autoindex.so
+LoadModule dir_module modules/mod_dir.so
+LoadModule alias_module modules/mod_alias.so
+LoadModule rewrite_module modules/mod_rewrite.so
+
+ServerRoot "/usr/local/apache2"
+LogLevel debug
+ErrorLog /proc/self/fd/2
+CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
+
+Listen 80
+
+
+ ProxyPass / h2c://zitadel-disabled-tls:8080/
+ ProxyPreserveHost on
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-enabled-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-enabled-tls.conf
new file mode 100644
index 000000000..c398d52f4
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-enabled-tls.conf
@@ -0,0 +1,47 @@
+LoadModule mpm_event_module modules/mod_mpm_event.so
+LoadModule authn_file_module modules/mod_authn_file.so
+LoadModule authn_core_module modules/mod_authn_core.so
+LoadModule authz_host_module modules/mod_authz_host.so
+LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
+LoadModule authz_user_module modules/mod_authz_user.so
+LoadModule authz_core_module modules/mod_authz_core.so
+LoadModule access_compat_module modules/mod_access_compat.so
+LoadModule auth_basic_module modules/mod_auth_basic.so
+LoadModule reqtimeout_module modules/mod_reqtimeout.so
+LoadModule filter_module modules/mod_filter.so
+LoadModule mime_module modules/mod_mime.so
+LoadModule log_config_module modules/mod_log_config.so
+LoadModule env_module modules/mod_env.so
+LoadModule headers_module modules/mod_headers.so
+LoadModule setenvif_module modules/mod_setenvif.so
+LoadModule version_module modules/mod_version.so
+LoadModule proxy_module modules/mod_proxy.so
+LoadModule proxy_http_module modules/mod_proxy_http.so
+LoadModule ssl_module modules/mod_ssl.so
+LoadModule proxy_http2_module modules/mod_proxy_http2.so
+LoadModule unixd_module modules/mod_unixd.so
+LoadModule status_module modules/mod_status.so
+LoadModule autoindex_module modules/mod_autoindex.so
+LoadModule dir_module modules/mod_dir.so
+LoadModule alias_module modules/mod_alias.so
+LoadModule rewrite_module modules/mod_rewrite.so
+LoadModule http2_module modules/mod_http2.so
+
+ServerRoot "/usr/local/apache2"
+LogLevel debug
+ErrorLog /proc/self/fd/2
+CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
+
+Listen 443
+
+SSLRandomSeed startup builtin
+SSLRandomSeed connect builtin
+
+
+ ProxyPass / h2://zitadel-enabled-tls:8080/
+ ProxyPreserveHost on
+ SSLEngine on
+ SSLProxyEngine on
+ SSLCertificateFile /etc/certs/selfsigned.crt
+ SSLCertificateKeyFile /etc/certs/selfsigned.key
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-external-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-external-tls.conf
new file mode 100644
index 000000000..7bcd6c3d9
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-external-tls.conf
@@ -0,0 +1,43 @@
+LoadModule mpm_event_module modules/mod_mpm_event.so
+LoadModule authn_file_module modules/mod_authn_file.so
+LoadModule authn_core_module modules/mod_authn_core.so
+LoadModule authz_host_module modules/mod_authz_host.so
+LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
+LoadModule authz_user_module modules/mod_authz_user.so
+LoadModule authz_core_module modules/mod_authz_core.so
+LoadModule access_compat_module modules/mod_access_compat.so
+LoadModule auth_basic_module modules/mod_auth_basic.so
+LoadModule reqtimeout_module modules/mod_reqtimeout.so
+LoadModule filter_module modules/mod_filter.so
+LoadModule mime_module modules/mod_mime.so
+LoadModule log_config_module modules/mod_log_config.so
+LoadModule env_module modules/mod_env.so
+LoadModule headers_module modules/mod_headers.so
+LoadModule setenvif_module modules/mod_setenvif.so
+LoadModule version_module modules/mod_version.so
+LoadModule proxy_module modules/mod_proxy.so
+LoadModule proxy_http_module modules/mod_proxy_http.so
+LoadModule ssl_module modules/mod_ssl.so
+LoadModule proxy_http2_module modules/mod_proxy_http2.so
+LoadModule unixd_module modules/mod_unixd.so
+LoadModule status_module modules/mod_status.so
+LoadModule autoindex_module modules/mod_autoindex.so
+LoadModule dir_module modules/mod_dir.so
+LoadModule alias_module modules/mod_alias.so
+LoadModule rewrite_module modules/mod_rewrite.so
+LoadModule http2_module modules/mod_http2.so
+
+LogLevel debug
+ErrorLog /proc/self/fd/2
+CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
+
+Listen 443
+
+
+ ProxyPass / h2c://zitadel-external-tls:8080/
+ ProxyPassReverse / h2c://zitadel-external-tls:8080/
+ ProxyPreserveHost on
+ SSLEngine on
+ SSLCertificateFile /etc/certs/selfsigned.crt
+ SSLCertificateKeyFile /etc/certs/selfsigned.key
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd.mdx b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd.mdx
new file mode 100644
index 000000000..dc17e9387
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd.mdx
@@ -0,0 +1,38 @@
+---
+title: Configure ZITADEL with Apache httpd
+sidebar_label: Apache httpd
+---
+
+import ProxyGuideOverview from '../_proxy_guide_overview.mdx';
+import ProxyGuideTLSMode from '../_proxy_guide_tls_mode.mdx';
+import Compose from "!!raw-loader!./docker-compose.yaml";
+import ConfigDisabled from "!!raw-loader!./httpd-disabled-tls.conf";
+import ConfigExternal from "!!raw-loader!./httpd-external-tls.conf";
+import ConfigEnabled from "!!raw-loader!./httpd-enabled-tls.conf";
+
+export const providername = "Apache httpd";
+export const lower = "httpd";
+export const link = {providername}
+
+
+
+You can either setup your environment for TLS mode disabled, TLS mode external or TLS mode enabled.
+
+## TLS mode disabled
+
+
+
+
+## TLS mode external
+
+
+
+
+## TLS mode enabled
+
+
+
+
+## More Information
+
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/nginx/docker-compose.yaml
new file mode 100644
index 000000000..99b47219c
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/docker-compose.yaml
@@ -0,0 +1,37 @@
+version: '3.8'
+
+services:
+
+ proxy-disabled-tls:
+ image: "nginx:1.25.3-alpine"
+ volumes:
+ - "./nginx-disabled-tls.conf:/etc/nginx/nginx.conf:ro"
+ ports:
+ - "80:80"
+ depends_on:
+ zitadel-disabled-tls:
+ condition: 'service_healthy'
+
+ proxy-external-tls:
+ image: "nginx:1.25.3-alpine"
+ volumes:
+ - "./nginx-external-tls.conf:/etc/nginx/nginx.conf:ro"
+ - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro"
+ - "./selfsigned.key:/etc/certs/selfsigned.key:ro"
+ ports:
+ - "443:443"
+ depends_on:
+ zitadel-external-tls:
+ condition: 'service_healthy'
+
+ proxy-enabled-tls:
+ image: "nginx:1.25.3-alpine"
+ volumes:
+ - "./nginx-enabled-tls.conf:/etc/nginx/nginx.conf:ro"
+ - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro"
+ - "./selfsigned.key:/etc/certs/selfsigned.key:ro"
+ ports:
+ - "443:443"
+ depends_on:
+ zitadel-enabled-tls:
+ condition: 'service_healthy'
diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-disabled-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-disabled-tls.conf
new file mode 100644
index 000000000..1ea55b990
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-disabled-tls.conf
@@ -0,0 +1,13 @@
+events {
+ worker_connections 1024;
+}
+http {
+ server {
+ listen 80;
+ http2 on;
+ location / {
+ grpc_pass grpc://zitadel-disabled-tls:8080;
+ grpc_set_header Host $host:$server_port;
+ }
+ }
+}
diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-enabled-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-enabled-tls.conf
new file mode 100644
index 000000000..00e83f74a
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-enabled-tls.conf
@@ -0,0 +1,15 @@
+events {
+ worker_connections 1024;
+}
+http {
+ server {
+ listen 443 ssl;
+ http2 on;
+ ssl_certificate /etc/certs/selfsigned.crt;
+ ssl_certificate_key /etc/certs/selfsigned.key;
+ location / {
+ grpc_pass grpcs://zitadel-enabled-tls:8080;
+ grpc_set_header Host $host:$server_port;
+ }
+ }
+}
diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-external-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-external-tls.conf
new file mode 100644
index 000000000..c2f34062c
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-external-tls.conf
@@ -0,0 +1,15 @@
+events {
+ worker_connections 1024;
+}
+http {
+ server {
+ listen 443 ssl;
+ http2 on;
+ ssl_certificate /etc/certs/selfsigned.crt;
+ ssl_certificate_key /etc/certs/selfsigned.key;
+ location / {
+ grpc_pass grpc://zitadel-external-tls:8080;
+ grpc_set_header Host $host:$server_port;
+ }
+ }
+}
diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx
new file mode 100644
index 000000000..d05296a95
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx
@@ -0,0 +1,35 @@
+---
+title: Configure ZITADEL with NGINX
+sidebar_label: NGINX
+---
+
+import ProxyGuideOverview from '../_proxy_guide_overview.mdx';
+import ProxyGuideTLSMode from '../_proxy_guide_tls_mode.mdx';
+import Compose from "!!raw-loader!./docker-compose.yaml";
+import ConfigDisabled from "!!raw-loader!./nginx-disabled-tls.conf";
+import ConfigExternal from "!!raw-loader!./nginx-external-tls.conf";
+import ConfigEnabled from "!!raw-loader!./nginx-enabled-tls.conf";
+
+export const providername = 'NGINX';
+export const lower = "nginx";
+export const link = {providername};
+
+
+
+You can either setup your environment for TLS mode disabled, TLS mode external or TLS mode enabled.
+
+## TLS mode disabled
+
+
+
+## TLS mode external
+
+
+
+## TLS mode enabled
+
+
+
+## More Information
+
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx b/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx
index c94c4cdcd..b37ef3123 100644
--- a/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx
+++ b/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx
@@ -2,58 +2,13 @@
title: Reverse Proxy Configuration
---
-import Tabs from "@theme/Tabs";
-import TabItem from "@theme/TabItem";
-import Zcloud from "./_zitadel_cloud.mdx";
-import Nginx from "./_nginx.mdx";
-import Traefik from "./_traefik.mdx";
-import Caddy from "./_caddy.mdx";
-import Httpd from "./_httpd.mdx";
-import Cftunnel from "./_cloudflare_tunnel.mdx";
-import Cloudflare from "./_cloudflare.mdx";
-import More from "./_more.mdx";
+Check out one of the following guides to configure your favorite reverse proxy:
-# Proxy Configuration
+- [Traefik](/self-hosting/manage/reverseproxy/traefik)
+- [NGINX](/self-hosting/manage/reverseproxy/nginx)
+- [Caddy](/self-hosting/manage/reverseproxy/caddy)
+
+- [Cloudflare](/self-hosting/manage/reverseproxy/cloudflare)
+- [Cloudflare Tunnel](/self-hosting/manage/reverseproxy/cloudflare_tunnel)
+- [Fronting ZITADEL Cloud](/self-hosting/manage/reverseproxy/zitadel_cloud)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml
new file mode 100644
index 000000000..3082e95d2
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml
@@ -0,0 +1,37 @@
+version: '3.8'
+
+services:
+
+ proxy-disabled-tls:
+ image: "traefik:v2.10.5"
+ volumes:
+ - "./traefik-disabled-tls.yaml:/etc/traefik/traefik.yaml:ro"
+ ports:
+ - "80:80"
+ depends_on:
+ zitadel-disabled-tls:
+ condition: 'service_healthy'
+
+ proxy-external-tls:
+ image: "traefik:v2.10.5"
+ volumes:
+ - "./traefik-external-tls.yaml:/etc/traefik/traefik.yaml:ro"
+ - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro"
+ - "./selfsigned.key:/etc/certs/selfsigned.key:ro"
+ ports:
+ - "443:443"
+ depends_on:
+ zitadel-external-tls:
+ condition: 'service_healthy'
+
+ proxy-enabled-tls:
+ image: "traefik:v2.10.5"
+ volumes:
+ - "./traefik-enabled-tls.yaml:/etc/traefik/traefik.yaml:ro"
+ - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro"
+ - "./selfsigned.key:/etc/certs/selfsigned.key:ro"
+ ports:
+ - "443:443"
+ depends_on:
+ zitadel-enabled-tls:
+ condition: 'service_healthy'
diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-disabled-tls.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-disabled-tls.yaml
new file mode 100644
index 000000000..0dbf906fa
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-disabled-tls.yaml
@@ -0,0 +1,20 @@
+log:
+ level: "DEBUG"
+providers:
+ file:
+ filename: "/etc/traefik/traefik.yaml"
+entrypoints:
+ web:
+ address: ":80"
+http:
+ routers:
+ router:
+ entryPoints:
+ - "web"
+ service: "zitadel"
+ rule: 'PathPrefix(`/`)'
+ services:
+ zitadel:
+ loadBalancer:
+ servers:
+ - url: "h2c://zitadel-disabled-tls:8080"
diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-enabled-tls.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-enabled-tls.yaml
new file mode 100644
index 000000000..b175d53a8
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-enabled-tls.yaml
@@ -0,0 +1,31 @@
+log:
+ level: "DEBUG"
+providers:
+ file:
+ filename: "/etc/traefik/traefik.yaml"
+entrypoints:
+ web:
+ address: ":443"
+http:
+ routers:
+ router:
+ entryPoints:
+ - "web"
+ service: "zitadel"
+ rule: 'PathPrefix(`/`)'
+ tls: {}
+ services:
+ zitadel:
+ loadBalancer:
+ serversTransport: "zitadel"
+ servers:
+ - url: "https://zitadel-enabled-tls:8080"
+ serversTransports:
+ zitadel:
+ insecureSkipVerify: true
+tls:
+ stores:
+ default:
+ defaultCertificate:
+ certFile: /etc/certs/selfsigned.crt
+ keyFile: /etc/certs/selfsigned.key
diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-external-tls.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-external-tls.yaml
new file mode 100644
index 000000000..e91059036
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-external-tls.yaml
@@ -0,0 +1,27 @@
+log:
+ level: "DEBUG"
+providers:
+ file:
+ filename: "/etc/traefik/traefik.yaml"
+entrypoints:
+ web:
+ address: ":443"
+http:
+ routers:
+ router:
+ entryPoints:
+ - "web"
+ service: "zitadel"
+ rule: 'PathPrefix(`/`)'
+ tls: {}
+ services:
+ zitadel:
+ loadBalancer:
+ servers:
+ - url: "h2c://zitadel-external-tls:8080"
+tls:
+ stores:
+ default:
+ defaultCertificate:
+ certFile: /etc/certs/selfsigned.crt
+ keyFile: /etc/certs/selfsigned.key
diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx
new file mode 100644
index 000000000..d9d1d78f5
--- /dev/null
+++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx
@@ -0,0 +1,35 @@
+---
+title: Configure ZITADEL with Traefik
+sidebar_label: Traefik
+---
+
+import ProxyGuideOverview from '../_proxy_guide_overview.mdx';
+import ProxyGuideTLSMode from '../_proxy_guide_tls_mode.mdx';
+import Compose from "!!raw-loader!./docker-compose.yaml";
+import ConfigDisabled from "!!raw-loader!./traefik-disabled-tls.yaml";
+import ConfigExternal from "!!raw-loader!./traefik-external-tls.yaml";
+import ConfigEnabled from "!!raw-loader!./traefik-enabled-tls.yaml";
+
+export const providername = 'Traefik';
+export const lower = "traefik";
+export const link = {providername};
+
+
+
+You can either setup your environment for TLS mode disabled, TLS mode external or TLS mode enabled.
+
+## TLS mode disabled
+
+
+
+## TLS mode external
+
+
+
+## TLS mode enabled
+
+
+
+## More Information
+
+
diff --git a/docs/docs/self-hosting/manage/reverseproxy/_zitadel_cloud.mdx b/docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx
similarity index 85%
rename from docs/docs/self-hosting/manage/reverseproxy/_zitadel_cloud.mdx
rename to docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx
index 706393651..1cbba5b3b 100644
--- a/docs/docs/self-hosting/manage/reverseproxy/_zitadel_cloud.mdx
+++ b/docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx
@@ -1,3 +1,8 @@
+---
+title: Front ZITADEL Cloud with a CDN, WAF or Reverse Proxy
+sidebar_label: Fronting ZITADEL Cloud
+---
+
## Fronting ZITADEL Cloud
You can use your reverseproxy, content delivery network (CDN) or web application firewall (WAF) to front ZITADEL Cloud.
diff --git a/docs/docs/self-hosting/manage/tls_modes.mdx b/docs/docs/self-hosting/manage/tls_modes.mdx
index dc34dca07..c77b02272 100644
--- a/docs/docs/self-hosting/manage/tls_modes.mdx
+++ b/docs/docs/self-hosting/manage/tls_modes.mdx
@@ -2,8 +2,8 @@
title: TLS Modes
---
-To allow ZITADEL to be run on any kind of infrastructure it allows to configure on how tho handle TLS connections.
-There are three mode of operation: `external`, `enabled`, `disabled`.
+To run ZITADEL on any kind of infrastructure, you can configure on how to handle TLS connections.
+There are three modes of operation: `disabled`, `external`, `enabled`.
Generally this command is set as argument while starting ZITADEL. For example like this:
@@ -11,6 +11,16 @@ Generally this command is set as argument while starting ZITADEL. For example li
zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
```
+## Disabled
+
+With the mode `disabled`, you instruct ZITADEL to await all connections with plain http without TLS.
+
+:::caution
+
+Be aware this is not a secure setup and should only be used for test systems!
+
+:::
+
## External
The mode `external` allows you to configure ZITADEL in such a way that it will instruct its clients to use https.
@@ -19,8 +29,8 @@ However ZITADEL delegates the management of TLS connections to a reverseproxy, w
## Enabled
When using the mode `enabled` ZITADEL is setup to await incoming connections in an encrypted fashion.
-Wether it is from a client directly, a reverseproxy or web application firewall.
-This allows http connections to be secured at the transport level the whole way.
+Whether it is from a client directly, a reverse proxy or web application firewall.
+This allows HTTP connections to be secured at the transport level the whole way.
If you use the mode `enabled` you need to configure ZITADEL with the necessary TLS settings.
@@ -42,17 +52,10 @@ TLS:
Cert: #
```
-## Disabled
+## More Information
-With the mode `disabled` ZITADEL is instructed to await all connections with plain http without TLS.
+Beware that ZITADEL uses HTTP/2 for all its connections.
+If you are using the mode `external` or `disabled` make sure to verify h2c compatibility.
-:::caution
-
-Be aware this is not a secure setup and should only be used for test systems!
-
-:::
-
-## HTTP/2
-
-To allow ZITADEL to function properly please make sure that HTTP/2 is enabled. If you are using the mode `external` or `disabled` make sure to verify h2c compatibilty.
-You can read more about how ZITADEL utilizes in our [HTTP/2 docs](/self-hosting/manage/http2).
+- [Read more abouth how ZITADEL utilizes HTTP/2](/self-hosting/manage/http2).
+- [Explore some concrete proxy configuration examples for ZITADEL](/self-hosting/manage/reverseproxy/reverse_proxy).
diff --git a/docs/docs/self-hosting/manage/updating_scaling.md b/docs/docs/self-hosting/manage/updating_scaling.md
index 66cd502f3..7addca0b0 100644
--- a/docs/docs/self-hosting/manage/updating_scaling.md
+++ b/docs/docs/self-hosting/manage/updating_scaling.md
@@ -61,6 +61,8 @@ ZITADEL uses the privileged and preexisting database user configured in `Databas
- If not already done, it grants the necessary permissions ZITADEL needs to the non privileged user.
- If they don’t exist already, it creates all schemas and some basic tables.
+The init phase is idempotent if executed with the same binary version.
+
### The Setup Phase
During `zitadel setup`, ZITADEL creates projection tables and migrates existing data.
@@ -70,7 +72,10 @@ When deploying a new ZITADEL version,
make sure the setup phase runs before you roll out the new `zitadel start` processes.
The setup phase is executed in subsequent steps
whereas a new version's execution takes over where the last execution stopped.
-Therefore, configuration changes relevant for the setup phase won’t take effect in regard to the setup execution.
+
+Some configuration changes are only applied during the setup phase, like ExternalDomain, ExternalPort and ExternalSecure.
+
+The setup phase is idempotent if executed with the same binary version.
### The Runtime Phase
diff --git a/docs/sidebars.js b/docs/sidebars.js
index 10c5e8796..14775e216 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -658,7 +658,24 @@ module.exports = {
"self-hosting/manage/production",
"self-hosting/manage/productionchecklist",
"self-hosting/manage/configure/configure",
- "self-hosting/manage/reverseproxy/reverse_proxy",
+ {
+ type: "category",
+ collapsed: false,
+ label: "Reverse Proxy",
+ link: {
+ type: "doc",
+ id: "self-hosting/manage/reverseproxy/reverse_proxy",
+ },
+ items: [
+ "self-hosting/manage/reverseproxy/traefik/traefik",
+ "self-hosting/manage/reverseproxy/nginx/nginx",
+ "self-hosting/manage/reverseproxy/caddy/caddy",
+// "self-hosting/manage/reverseproxy/httpd/httpd", grpc NOT WORKING
+ "self-hosting/manage/reverseproxy/cloudflare/cloudflare",
+ "self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel",
+ "self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud",
+ ],
+ },
"self-hosting/manage/custom-domain",
"self-hosting/manage/http2",
"self-hosting/manage/tls_modes",
diff --git a/e2e/config/localhost/docker-compose.yaml b/e2e/config/localhost/docker-compose.yaml
index 7001cfb32..7ec0f28c5 100644
--- a/e2e/config/localhost/docker-compose.yaml
+++ b/e2e/config/localhost/docker-compose.yaml
@@ -22,7 +22,7 @@ services:
ports:
- "8080:8080"
healthcheck:
- test: ["CMD", "/app/zitadel", "ready"]
+ test: ["CMD", "/app/zitadel", "ready", "--config", "/zitadel.yaml" ]
interval: '10s'
timeout: '5s'
retries: 5
diff --git a/internal/api/api.go b/internal/api/api.go
index aaa3cd66d..82d574fe0 100644
--- a/internal/api/api.go
+++ b/internal/api/api.go
@@ -63,7 +63,7 @@ func New(
}
api.grpcServer = server.CreateServer(api.verifier, authZ, queries, http2HostName, tlsConfig, accessInterceptor.AccessService())
- api.grpcGateway, err = server.CreateGateway(ctx, port, http1HostName, accessInterceptor)
+ api.grpcGateway, err = server.CreateGateway(ctx, port, http1HostName, accessInterceptor, tlsConfig)
if err != nil {
return nil, err
}
@@ -80,7 +80,7 @@ func New(
// creates a new grpc gateway and registers it as a separate http handler
//
// used for v1 api (system, admin, mgmt, auth)
-func (a *API) RegisterServer(ctx context.Context, grpcServer server.WithGatewayPrefix) error {
+func (a *API) RegisterServer(ctx context.Context, grpcServer server.WithGatewayPrefix, tlsConfig *tls.Config) error {
grpcServer.RegisterServer(a.grpcServer)
handler, prefix, err := server.CreateGatewayWithPrefix(
ctx,
@@ -89,6 +89,7 @@ func (a *API) RegisterServer(ctx context.Context, grpcServer server.WithGatewayP
a.http1HostName,
a.accessInterceptor,
a.queries,
+ tlsConfig,
)
if err != nil {
return err
diff --git a/internal/api/grpc/server/gateway.go b/internal/api/grpc/server/gateway.go
index dc69ec75e..6c506ea34 100644
--- a/internal/api/grpc/server/gateway.go
+++ b/internal/api/grpc/server/gateway.go
@@ -2,6 +2,7 @@ package server
import (
"context"
+ "crypto/tls"
"fmt"
"net/http"
"strings"
@@ -9,6 +10,7 @@ import (
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/zitadel/logging"
"google.golang.org/grpc"
+ "google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/protobuf/encoding/protojson"
@@ -89,10 +91,11 @@ func CreateGatewayWithPrefix(
http1HostName string,
accessInterceptor *http_mw.AccessInterceptor,
queries *query.Queries,
+ tlsConfig *tls.Config,
) (http.Handler, string, error) {
runtimeMux := runtime.NewServeMux(serveMuxOptions...)
opts := []grpc.DialOption{
- grpc.WithTransportCredentials(insecure.NewCredentials()),
+ grpc.WithTransportCredentials(grpcCredentials(tlsConfig)),
grpc.WithUnaryInterceptor(client_middleware.DefaultTracingClient()),
}
connection, err := dial(ctx, port, opts)
@@ -106,11 +109,17 @@ func CreateGatewayWithPrefix(
return addInterceptors(runtimeMux, http1HostName, accessInterceptor, queries), g.GatewayPathPrefix(), nil
}
-func CreateGateway(ctx context.Context, port uint16, http1HostName string, accessInterceptor *http_mw.AccessInterceptor) (*Gateway, error) {
+func CreateGateway(
+ ctx context.Context,
+ port uint16,
+ http1HostName string,
+ accessInterceptor *http_mw.AccessInterceptor,
+ tlsConfig *tls.Config,
+) (*Gateway, error) {
connection, err := dial(ctx,
port,
[]grpc.DialOption{
- grpc.WithTransportCredentials(insecure.NewCredentials()),
+ grpc.WithTransportCredentials(grpcCredentials(tlsConfig)),
grpc.WithUnaryInterceptor(client_middleware.DefaultTracingClient()),
})
if err != nil {
@@ -217,3 +226,15 @@ func (r *cookieResponseWriter) WriteHeader(status int) {
}
r.ResponseWriter.WriteHeader(status)
}
+
+func grpcCredentials(tlsConfig *tls.Config) credentials.TransportCredentials {
+ creds := insecure.NewCredentials()
+ if tlsConfig != nil {
+ tlsConfigClone := tlsConfig.Clone()
+ // We don't want to verify the certificate of the internal grpc server
+ // That's up to the client who called the gRPC gateway
+ tlsConfigClone.InsecureSkipVerify = true
+ creds = credentials.NewTLS(tlsConfigClone)
+ }
+ return creds
+}
diff --git a/internal/static/i18n/bg.yaml b/internal/static/i18n/bg.yaml
index 46eda0c4d..835abf24d 100644
--- a/internal/static/i18n/bg.yaml
+++ b/internal/static/i18n/bg.yaml
@@ -319,7 +319,7 @@ Errors:
NotActive: Грантът по проекта не е активен
NotInactive: Грантът по проекта не е неактивен
IAM:
- NotFound: Екземплярът не е намерен
+ NotFound: Екземплярът не е намерен. Вижте https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: Ролите не са сменени
MemberInvalid: Членът е невалиден
diff --git a/internal/static/i18n/cs.yaml b/internal/static/i18n/cs.yaml
index ffa77c00f..f18148b7b 100644
--- a/internal/static/i18n/cs.yaml
+++ b/internal/static/i18n/cs.yaml
@@ -317,7 +317,7 @@ Errors:
NotActive: Grant projektu není aktivní
NotInactive: Grant projektu není neaktivní
IAM:
- NotFound: Instance nenalezena
+ NotFound: Instance nenalezena. Podívejte se na https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: Role nebyly změněny
MemberInvalid: Člen je neplatný
diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml
index 0b902da86..051a925e5 100644
--- a/internal/static/i18n/de.yaml
+++ b/internal/static/i18n/de.yaml
@@ -317,7 +317,7 @@ Errors:
NotActive: Projekt Grant ist nicht aktiv
NotInactive: Projekt Grant ist nicht inaktiv
IAM:
- NotFound: Instanz nicht gefunden
+ NotFound: Instanz nicht gefunden. Schau dir https://zitadel.com/docs/self-hosting/manage/custom-domain an
Member:
RolesNotChanged: Rollen wurden nicht verändert
MemberInvalid: Member ist ungültig
diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml
index ed881e22a..63aa8a8fb 100644
--- a/internal/static/i18n/en.yaml
+++ b/internal/static/i18n/en.yaml
@@ -317,7 +317,7 @@ Errors:
NotActive: Project grant is not active
NotInactive: Project grant is not inactive
IAM:
- NotFound: Instance not found
+ NotFound: Instance not found. Check out https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: Roles have not been changed
MemberInvalid: Member is invalid
diff --git a/internal/static/i18n/es.yaml b/internal/static/i18n/es.yaml
index ff4410cb0..9a1a1ff82 100644
--- a/internal/static/i18n/es.yaml
+++ b/internal/static/i18n/es.yaml
@@ -317,7 +317,7 @@ Errors:
NotActive: La concesión del proyecto no está activa
NotInactive: La concesión del proyecto no está inactiva
IAM:
- NotFound: Instancia no encontrada
+ NotFound: Instancia no encontrada. Consulta https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: Los roles no han cambiado
MemberInvalid: El miembro no es válido
diff --git a/internal/static/i18n/fr.yaml b/internal/static/i18n/fr.yaml
index 3a14c5226..fbd6c2c13 100644
--- a/internal/static/i18n/fr.yaml
+++ b/internal/static/i18n/fr.yaml
@@ -317,7 +317,7 @@ Errors:
NotActive: La subvention de projet n'est pas active
NotInactive: La subvention du projet n'est pas inactive
IAM:
- NotFound: Instance non trouvée
+ NotFound: Instance non trouvée. Consultez https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: Les rôles n'ont pas été modifiés
MemberInvalid: Le membre n'est pas valide
diff --git a/internal/static/i18n/it.yaml b/internal/static/i18n/it.yaml
index fe56c424e..b451d370b 100644
--- a/internal/static/i18n/it.yaml
+++ b/internal/static/i18n/it.yaml
@@ -318,7 +318,7 @@ Errors:
NotActive: Grant del progetto non è attivo
NotInactive: Grant del progetto non è inattivo
IAM:
- NotFound: Istanza non trovata
+ NotFound: Istanza non trovata. Controlla https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: I ruoli non sono stati cambiati
MemberInvalid: Il membro non è valido
diff --git a/internal/static/i18n/ja.yaml b/internal/static/i18n/ja.yaml
index 9180e41d5..ec037a7a8 100644
--- a/internal/static/i18n/ja.yaml
+++ b/internal/static/i18n/ja.yaml
@@ -306,7 +306,7 @@ Errors:
NotActive: プロジェクトグラントはアクティブではありません
NotInactive: プロジェクトグラントは非アクティブではありません
IAM:
- NotFound: インスタンスが見つかりません
+ NotFound: インスタンスが見つかりません https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: ロールは変更されていません
MemberInvalid: 無効なメンバーです
diff --git a/internal/static/i18n/mk.yaml b/internal/static/i18n/mk.yaml
index 085daec0d..51dde7467 100644
--- a/internal/static/i18n/mk.yaml
+++ b/internal/static/i18n/mk.yaml
@@ -317,7 +317,7 @@ Errors:
NotActive: Овластувањето за проектот не е активно
NotInactive: Овластувањето за проектот не е неактивно
IAM:
- NotFound: Инстанцата не е пронајдена
+ NotFound: Инстанцата не е пронајдена. Проверете https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: Улогите не се променети
MemberInvalid: Членот е невалиден
diff --git a/internal/static/i18n/pl.yaml b/internal/static/i18n/pl.yaml
index 3a54a6fcb..bb7dc3442 100644
--- a/internal/static/i18n/pl.yaml
+++ b/internal/static/i18n/pl.yaml
@@ -317,7 +317,7 @@ Errors:
NotActive: Grant projektu jest nieaktywny
NotInactive: Grant projektu nie jest nieaktywny
IAM:
- NotFound: Instancja nie znaleziona
+ NotFound: Instancja nie znaleziona. Sprawdź https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: Role nie zmienione
MemberInvalid: Członek jest nieprawidłowy
diff --git a/internal/static/i18n/pt.yaml b/internal/static/i18n/pt.yaml
index 90ff628a1..472a7b5bd 100644
--- a/internal/static/i18n/pt.yaml
+++ b/internal/static/i18n/pt.yaml
@@ -315,7 +315,7 @@ Errors:
NotActive: A concessão do projeto não está ativa
NotInactive: A concessão do projeto não está inativa
IAM:
- NotFound: Instância não encontrada
+ NotFound: Instância não encontrada. Confira https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: As funções não foram alteradas
MemberInvalid: O membro é inválido
diff --git a/internal/static/i18n/ru.yaml b/internal/static/i18n/ru.yaml
index fa053b319..2b89e5cbe 100644
--- a/internal/static/i18n/ru.yaml
+++ b/internal/static/i18n/ru.yaml
@@ -308,7 +308,7 @@ Errors:
NotActive: Грант проекта не активен
NotInactive: Грант проекта не неактивен
IAM:
- NotFound: Экземпляр не найден
+ NotFound: Экземпляр не найден. Проверьте https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: Роли не изменились
MemberInvalid: Участник недействителен
diff --git a/internal/static/i18n/zh.yaml b/internal/static/i18n/zh.yaml
index a44de5485..4a2379823 100644
--- a/internal/static/i18n/zh.yaml
+++ b/internal/static/i18n/zh.yaml
@@ -317,7 +317,7 @@ Errors:
NotActive: 项目授权不是启用状态
NotInactive: 项目授权不是停用状态
IAM:
- NotFound: 实例未找到
+ NotFound: 实例未找到。查看 https://zitadel.com/docs/self-hosting/manage/custom-domain
Member:
RolesNotChanged: 角色没有改变
MemberInvalid: 成员无效