From 02d91d658727e55e4dcb62801725ab8ef57b128f Mon Sep 17 00:00:00 2001 From: Dimitrij Drus Date: Thu, 9 Jan 2025 15:12:29 +0100 Subject: [PATCH] refactor!: Configuration settings for services exposed by heimdall simplified (#2089) --- .github/ISSUE_TEMPLATE/BUG-REPORT.yaml | 3 +- DockerHub-README.md | 10 +- charts/heimdall/Chart.yaml | 2 +- charts/heimdall/README.adoc | 26 +-- charts/heimdall/templates/NOTES.txt | 2 +- charts/heimdall/templates/configmap.yaml | 5 + charts/heimdall/templates/deployment.yaml | 12 +- charts/heimdall/templates/service.yaml | 13 +- charts/heimdall/tests/configmap_test.yaml | 153 +++++++------- charts/heimdall/tests/container_test.yaml | 30 +-- charts/heimdall/tests/service_test.yaml | 40 ++-- charts/heimdall/values.yaml | 22 +- cmd/serve/decision_test.go | 8 +- cmd/serve/proxy_test.go | 4 +- .../docs/concepts/operating_modes.adoc | 6 +- .../content/docs/configuration/reference.adoc | 164 +++++++-------- .../docs/getting_started/protect_an_app.adoc | 4 +- .../docs/mechanisms/evaluation_objects.adoc | 2 +- .../docs/operations/configuration.adoc | 15 +- .../docs/operations/observability.adoc | 4 +- docs/content/docs/operations/security.adoc | 4 +- docs/content/docs/services/decision.adoc | 101 --------- .../docs/services/{proxy.adoc => main.adoc} | 20 +- docs/content/docs/services/management.adoc | 2 +- docs/content/guides/proxies/contour.adoc | 17 +- docs/content/guides/proxies/emissary.adoc | 4 +- docs/content/guides/proxies/envoy.adoc | 8 +- .../content/guides/proxies/envoy_gateway.adoc | 6 +- docs/content/guides/proxies/haproxy.adoc | 6 +- docs/content/guides/proxies/istio.adoc | 6 +- docs/content/guides/proxies/nginx.adoc | 16 +- docs/content/guides/proxies/traefik.adoc | 8 +- example_config.yaml | 48 ++--- examples/docker-compose/quickstarts/README.md | 4 +- .../quickstarts/docker-compose-traefik.yaml | 2 +- .../quickstarts/envoy-config-grpc.yaml | 2 +- .../quickstarts/envoy-config-http.yaml | 4 +- .../quickstarts/heimdall-config.yaml | 3 +- examples/kubernetes/haproxy/helm-values.yaml | 2 +- examples/kubernetes/istio/envoy-filter.yaml | 2 +- examples/kubernetes/istio/istio-values.yaml | 4 +- examples/kubernetes/metallb/configure.sh | 2 +- .../kubernetes/nginx/global-helm-values.yaml | 2 +- .../demo-app/overlays/haproxy/ingress.yaml | 2 +- .../overlays/nginx-route-based/ingress.yaml | 2 +- .../heimdall/backend-tls-policy.yaml | 2 +- .../quickstarts/heimdall/config.yaml | 13 +- .../heimdall/contour-extension-service.yaml | 2 +- .../heimdall/emissary-auth-service.yaml | 2 +- .../heimdall/envoygw-security-policy.yaml | 2 +- .../heimdall/heimdall-middleware.yaml | 2 +- .../quickstarts/heimdall/helm-values.yaml | 3 +- internal/config/configuration.go | 1 + internal/config/default_configuration.go | 63 +++--- internal/config/management.go | 14 ++ internal/config/serve.go | 34 ++-- internal/config/test_data/test_config.yaml | 190 ++++++++--------- internal/handler/decision/module.go | 2 +- internal/handler/decision/service.go | 2 +- internal/handler/decision/service_test.go | 16 +- .../handler/envoyextauth/grpcv3/module.go | 2 +- .../handler/envoyextauth/grpcv3/service.go | 2 +- internal/handler/listener/listener_test.go | 12 +- internal/handler/management/module.go | 2 +- internal/handler/management/service.go | 2 +- internal/handler/management/service_test.go | 12 +- internal/handler/proxy/module.go | 2 +- internal/handler/proxy/request_context.go | 2 +- .../handler/proxy/request_context_test.go | 2 +- internal/handler/proxy/service.go | 2 +- internal/handler/proxy/service_test.go | 56 +++-- release-please-config.json | 3 +- schema/config.schema.json | 191 +++++++----------- 73 files changed, 589 insertions(+), 851 deletions(-) delete mode 100644 docs/content/docs/services/decision.adoc rename docs/content/docs/services/{proxy.adoc => main.adoc} (77%) create mode 100644 internal/config/management.go diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yaml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yaml index a202ba35e..42e02410b 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT.yaml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yaml @@ -62,8 +62,7 @@ body: render: yml placeholder: | serve: - decision: - port: 1234 + port: 1234 - id: version type: input diff --git a/DockerHub-README.md b/DockerHub-README.md index f1d760cee..19ade6281 100644 --- a/DockerHub-README.md +++ b/DockerHub-README.md @@ -37,23 +37,23 @@ default_rule: Start heimdall: ```bash -docker run -t -p 4456:4456 -v $PWD:/heimdall/conf \ +docker run -t -p 4455:4455 -v $PWD:/heimdall/conf \ dadrus/heimdall:latest serve decision -c /heimdall/conf/heimdall.yaml ``` Call the decision service endpoint to emulate behavior of an API-Gateway: ```bash -curl -v 127.0.0.1:4456/foobar +curl -v 127.0.0.1:4455/foobar ``` You should now see similar output to the following snippet: ```bash -* Trying 127.0.0.1:4456... -* Connected to 127.0.0.1 (127.0.0.1) port 4456 (#0) +* Trying 127.0.0.1:4455... +* Connected to 127.0.0.1 (127.0.0.1) port 4455 (#0) > GET /foobar HTTP/1.1 -> Host: 127.0.0.1:4456 +> Host: 127.0.0.1:4455 > User-Agent: curl/7.74.0 > Accept: */* > diff --git a/charts/heimdall/Chart.yaml b/charts/heimdall/Chart.yaml index 139414417..dcc6a88c5 100644 --- a/charts/heimdall/Chart.yaml +++ b/charts/heimdall/Chart.yaml @@ -17,7 +17,7 @@ apiVersion: v2 name: heimdall description: A cloud native Identity Aware Proxy and Access Control Decision Service -version: 0.14.4 +version: 0.15.0 appVersion: latest kubeVersion: ^1.27.0 type: application diff --git a/charts/heimdall/README.adoc b/charts/heimdall/README.adoc index 2b2165395..4e46c5d0a 100644 --- a/charts/heimdall/README.adoc +++ b/charts/heimdall/README.adoc @@ -333,30 +333,20 @@ a| `service.annotations` Enables you to set additional annotations for the created services a| `{}` (empty map) -a| `service.decision.port` +a| `service.main.port` -The port exposed by the k8s Service created for heimdall's decision endpoint. Only used if the `operationMode` is set to `decision`. -a| `4456` +The main port exposed by the k8s Service created for heimdall. +a| `4455` -a| `service.decision.name` +a| `service.main.name` -The name of the port exposed by the k8s Service created for heimdall's decision endpoint. Only used if the `operationMode` is set to `decision`. -a| `decision` - -a| `service.proxy.port` - -The port exposed by the k8s Service created for heimdall's proxy endpoint. Only used if the `operationMode` is set to `proxy`. -a| `4456` - -a| `service.proxy.name` - -The name of the port exposed by the k8s Service created for heimdall's proxy endpoint. Only used if the `operationMode` is set to `proxy`. -a| `proxy` +The name of the port exposed by the k8s Service created for heimdall. +a| `main` a| `service.management.port` -The port exposed by the k8s Service created for heimdall's proxy endpoint. Only used if the `operationMode` is set to `proxy`. -a| `4456` +The port exposed by the k8s Service created for heimdall's management endpoint. +a| `4457` a| `service.management.name` diff --git a/charts/heimdall/templates/NOTES.txt b/charts/heimdall/templates/NOTES.txt index c18df6e49..6c4d84dfb 100644 --- a/charts/heimdall/templates/NOTES.txt +++ b/charts/heimdall/templates/NOTES.txt @@ -4,7 +4,7 @@ Heimdall is installed and configured to operate in decision mode. To integrate heimdall with your Ingress Controller, you have to annotate the corresponding Ingress resources to use it as authentication middleware and forward the requests to -"http://{{ include "heimdall.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.decision.port }}". +"http://{{ include "heimdall.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.main.port }}". as well as forward the HTTP headers and/or cookies from heimdall responses to the upstream services. Consult the Ingress Controller documentation of your choice on how to achieve this. diff --git a/charts/heimdall/templates/configmap.yaml b/charts/heimdall/templates/configmap.yaml index 0d9e5d234..dab048af6 100644 --- a/charts/heimdall/templates/configmap.yaml +++ b/charts/heimdall/templates/configmap.yaml @@ -28,6 +28,11 @@ data: {{- toYaml . | nindent 6 }} {{- end }} + {{- with .Values.management }} + management: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.log }} log: {{- toYaml . | nindent 6 }} diff --git a/charts/heimdall/templates/deployment.yaml b/charts/heimdall/templates/deployment.yaml index 0b25cd4f0..98fd6999b 100644 --- a/charts/heimdall/templates/deployment.yaml +++ b/charts/heimdall/templates/deployment.yaml @@ -78,18 +78,12 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} ports: - {{- if eq .Values.operationMode "decision" }} - - name: http-decision - containerPort: {{ .Values.serve.decision.port }} + - name: http-main + containerPort: {{ .Values.serve.port }} protocol: TCP - {{- else }} - - name: http-proxy - containerPort: {{ .Values.serve.proxy.port }} - protocol: TCP - {{- end }} - name: http-management protocol: TCP - containerPort: {{ .Values.serve.management.port }} + containerPort: {{ .Values.management.port }} {{- if contains "prometheus" ( .Values.env.OTEL_METRICS_EXPORTER | default "") }} - name: http-metrics protocol: TCP diff --git a/charts/heimdall/templates/service.yaml b/charts/heimdall/templates/service.yaml index 261d50fac..5048e4041 100644 --- a/charts/heimdall/templates/service.yaml +++ b/charts/heimdall/templates/service.yaml @@ -31,17 +31,10 @@ spec: targetPort: http-management protocol: TCP name: {{ .Values.service.management.name }} - {{- if eq .Values.operationMode "decision" }} - - port: {{ .Values.service.decision.port }} - targetPort: http-decision + - port: {{ .Values.service.main.port }} + targetPort: http-main protocol: TCP - name: {{ .Values.service.decision.name }} - {{- else }} - - port: {{ .Values.service.proxy.port }} - targetPort: http-proxy - protocol: TCP - name: {{ .Values.service.proxy.name }} - {{- end }} + name: {{ .Values.service.main.name }} {{- $providers := default dict .Values.providers }} {{- $kubernetes := default dict $providers.kubernetes }} {{- if $kubernetes.tls }} diff --git a/charts/heimdall/tests/configmap_test.yaml b/charts/heimdall/tests/configmap_test.yaml index a12c46833..8aaf9f5f0 100644 --- a/charts/heimdall/tests/configmap_test.yaml +++ b/charts/heimdall/tests/configmap_test.yaml @@ -58,12 +58,9 @@ tests: value: |- serve: - decision: - port: 4456 - management: - port: 4457 - proxy: - port: 4455 + port: 4455 + management: + port: 4457 profiling: enabled: false host: 0.0.0.0 @@ -72,41 +69,40 @@ tests: - it: should allow configuration of any heimdall setting set: serve: - decision: - host: 127.0.0.1 - tls: - key_store: - path: /path/to/keystore.pem - password: VerySecure! - timeout: - read: 1s - write: 2s - idle: 30s - buffer_limit: - read: 4KB - write: 10KB - trusted_proxies: - - 192.168.1.0/24 - respond: - verbose: true - with: - authentication_error: - code: 404 - authorization_error: - code: 404 - management: - host: 127.0.0.1 - tls: - key_store: - path: /path/to/keystore.pem - password: VerySecure! - timeout: - read: 1s - write: 2s - idle: 30s - buffer_limit: - read: 4KB - write: 10KB + host: 127.0.0.1 + tls: + key_store: + path: /path/to/keystore.pem + password: VerySecure! + timeout: + read: 1s + write: 2s + idle: 30s + buffer_limit: + read: 4KB + write: 10KB + trusted_proxies: + - 192.168.1.0/24 + respond: + verbose: true + with: + authentication_error: + code: 404 + authorization_error: + code: 404 + management: + host: 127.0.0.1 + tls: + key_store: + path: /path/to/keystore.pem + password: VerySecure! + timeout: + read: 1s + write: 2s + idle: 30s + buffer_limit: + read: 4KB + write: 10KB metrics: enabled: true profiling: @@ -174,45 +170,42 @@ tests: value: |- serve: - decision: - buffer_limit: - read: 4KB - write: 10KB - host: 127.0.0.1 - port: 4456 - respond: - verbose: true - with: - authentication_error: - code: 404 - authorization_error: - code: 404 - timeout: - idle: 30s - read: 1s - write: 2s - tls: - key_store: - password: VerySecure! - path: /path/to/keystore.pem - trusted_proxies: - - 192.168.1.0/24 - management: - buffer_limit: - read: 4KB - write: 10KB - host: 127.0.0.1 - port: 4457 - timeout: - idle: 30s - read: 1s - write: 2s - tls: - key_store: - password: VerySecure! - path: /path/to/keystore.pem - proxy: - port: 4455 + buffer_limit: + read: 4KB + write: 10KB + host: 127.0.0.1 + port: 4455 + respond: + verbose: true + with: + authentication_error: + code: 404 + authorization_error: + code: 404 + timeout: + idle: 30s + read: 1s + write: 2s + tls: + key_store: + password: VerySecure! + path: /path/to/keystore.pem + trusted_proxies: + - 192.168.1.0/24 + management: + buffer_limit: + read: 4KB + write: 10KB + host: 127.0.0.1 + port: 4457 + timeout: + idle: 30s + read: 1s + write: 2s + tls: + key_store: + password: VerySecure! + path: /path/to/keystore.pem log: format: gelf level: debug diff --git a/charts/heimdall/tests/container_test.yaml b/charts/heimdall/tests/container_test.yaml index 10c01e253..38c4131aa 100644 --- a/charts/heimdall/tests/container_test.yaml +++ b/charts/heimdall/tests/container_test.yaml @@ -241,8 +241,8 @@ tests: - equal: path: spec.template.spec.containers[0].ports value: - - containerPort: 4456 - name: http-decision + - containerPort: 4455 + name: http-main protocol: TCP - containerPort: 4457 name: http-management @@ -257,7 +257,7 @@ tests: path: spec.template.spec.containers[0].ports value: - containerPort: 4455 - name: http-proxy + name: http-main protocol: TCP - containerPort: 4457 name: http-management @@ -272,8 +272,8 @@ tests: - equal: path: spec.template.spec.containers[0].ports value: - - containerPort: 4456 - name: http-decision + - containerPort: 4455 + name: http-main protocol: TCP - containerPort: 4457 name: http-management @@ -292,8 +292,8 @@ tests: - equal: path: spec.template.spec.containers[0].ports value: - - containerPort: 4456 - name: http-decision + - containerPort: 4455 + name: http-main protocol: TCP - containerPort: 4457 name: http-management @@ -310,8 +310,8 @@ tests: - equal: path: spec.template.spec.containers[0].ports value: - - containerPort: 4456 - name: http-decision + - containerPort: 4455 + name: http-main protocol: TCP - containerPort: 4457 name: http-management @@ -329,8 +329,8 @@ tests: - equal: path: spec.template.spec.containers[0].ports value: - - containerPort: 4456 - name: http-decision + - containerPort: 4455 + name: http-main protocol: TCP - containerPort: 4457 name: http-management @@ -350,8 +350,8 @@ tests: - equal: path: spec.template.spec.containers[0].ports value: - - containerPort: 4456 - name: http-decision + - containerPort: 4455 + name: http-main protocol: TCP - containerPort: 4457 name: http-management @@ -374,8 +374,8 @@ tests: - equal: path: spec.template.spec.containers[0].ports value: - - containerPort: 4456 - name: http-decision + - containerPort: 4455 + name: http-main protocol: TCP - containerPort: 4457 name: http-management diff --git a/charts/heimdall/tests/service_test.yaml b/charts/heimdall/tests/service_test.yaml index 8b2884762..e6078ef84 100644 --- a/charts/heimdall/tests/service_test.yaml +++ b/charts/heimdall/tests/service_test.yaml @@ -114,7 +114,7 @@ tests: app.kubernetes.io/instance: test-release app.kubernetes.io/name: foo - - it: should expose management and decision ports by default + - it: should expose management and main ports by default asserts: - equal: path: spec.ports @@ -123,12 +123,12 @@ tests: port: 4457 protocol: TCP targetPort: http-management - - name: decision - port: 4456 + - name: main + port: 4455 protocol: TCP - targetPort: http-decision + targetPort: http-main - - it: should expose management and proxy ports if operated in proxy mode + - it: should expose management and main ports if operated in proxy mode set: operationMode: proxy asserts: @@ -139,10 +139,10 @@ tests: port: 4457 protocol: TCP targetPort: http-management - - name: proxy + - name: main port: 4455 protocol: TCP - targetPort: http-proxy + targetPort: http-main - it: should not expose metrics port in addition to the standard ports although it is configured set: @@ -156,10 +156,10 @@ tests: port: 4457 protocol: TCP targetPort: http-management - - name: decision - port: 4456 + - name: main + port: 4455 protocol: TCP - targetPort: http-decision + targetPort: http-main - it: should not expose profiling port in addition to the standard ports although it is configured set: @@ -172,10 +172,10 @@ tests: port: 4457 protocol: TCP targetPort: http-management - - name: decision - port: 4456 + - name: main + port: 4455 protocol: TCP - targetPort: http-decision + targetPort: http-main - it: should expose admission controller web hook port if configured set: @@ -191,10 +191,10 @@ tests: port: 4457 protocol: TCP targetPort: http-management - - name: decision - port: 4456 + - name: main + port: 4455 protocol: TCP - targetPort: http-decision + targetPort: http-main - name: admission-controller port: 4458 protocol: TCP @@ -209,7 +209,7 @@ tests: service.management: port: 1111 name: man - service.decision: + service.main: port: 2222 name: dec service.admissionController: @@ -226,7 +226,7 @@ tests: - name: dec port: 2222 protocol: TCP - targetPort: http-decision + targetPort: http-main - name: adm port: 3333 protocol: TCP @@ -242,7 +242,7 @@ tests: service.management: port: 1111 name: man - service.proxy: + service.main: port: 2222 name: prox service.admissionController: @@ -259,7 +259,7 @@ tests: - name: prox port: 2222 protocol: TCP - targetPort: http-proxy + targetPort: http-main - name: adm port: 3333 protocol: TCP diff --git a/charts/heimdall/values.yaml b/charts/heimdall/values.yaml index 7b5674b48..b282422a5 100644 --- a/charts/heimdall/values.yaml +++ b/charts/heimdall/values.yaml @@ -96,18 +96,13 @@ service: # Remove the curly braces after 'annotations:' if you want to specify annotations annotations: { } - # Only used if "operationMode" is set to "decision" - decision: - # Service port - port: 4456 - # Service port name - name: decision - # Only used if "operationMode" is set to "proxy" - proxy: + # Main service + main: # Service port port: 4455 # Service port name - name: proxy + name: main + # Management service management: # Service port port: 4457 @@ -159,12 +154,9 @@ extraArgs: [] # heimdall config defaults # DO NOT OVERRIDE the values here. Use heimdall config yaml file instead! serve: - decision: - port: 4456 - proxy: - port: 4455 - management: - port: 4457 + port: 4455 +management: + port: 4457 profiling: enabled: false port: 10251 diff --git a/cmd/serve/decision_test.go b/cmd/serve/decision_test.go index 8d8dad62a..7f387b2e8 100644 --- a/cmd/serve/decision_test.go +++ b/cmd/serve/decision_test.go @@ -34,8 +34,8 @@ func TestCreateDecisionAppForHTTPRequests(t *testing.T) { port2, err := testsupport.GetFreePort() require.NoError(t, err) - t.Setenv("SERVE_DECISION_PORT", strconv.Itoa(port1)) - t.Setenv("SERVE_MANAGEMENT_PORT", strconv.Itoa(port2)) + t.Setenv("SERVE_PORT", strconv.Itoa(port1)) + t.Setenv("MANAGEMENT_PORT", strconv.Itoa(port2)) _, err = createDecisionApp(NewDecisionCommand()) require.NoError(t, err) @@ -50,8 +50,8 @@ func TestCreateDecisionAppForEnvoyGRPCRequests(t *testing.T) { port2, err := testsupport.GetFreePort() require.NoError(t, err) - t.Setenv("SERVE_DECISION_PORT", strconv.Itoa(port1)) - t.Setenv("SERVE_MANAGEMENT_PORT", strconv.Itoa(port2)) + t.Setenv("SERVE_PORT", strconv.Itoa(port1)) + t.Setenv("MANAGEMENT_PORT", strconv.Itoa(port2)) cmd := NewDecisionCommand() err = cmd.ParseFlags([]string{"--envoy-grpc"}) diff --git a/cmd/serve/proxy_test.go b/cmd/serve/proxy_test.go index 7678743ca..a4b545f87 100644 --- a/cmd/serve/proxy_test.go +++ b/cmd/serve/proxy_test.go @@ -34,8 +34,8 @@ func TestCreateProxyApp(t *testing.T) { port2, err := testsupport.GetFreePort() require.NoError(t, err) - t.Setenv("SERVE_PROXY_PORT", strconv.Itoa(port1)) - t.Setenv("SERVE_MANAGEMENT_PORT", strconv.Itoa(port2)) + t.Setenv("SERVE_PORT", strconv.Itoa(port1)) + t.Setenv("MANAGEMENT_PORT", strconv.Itoa(port2)) _, err = createProxyApp(NewProxyCommand()) require.NoError(t, err) diff --git a/docs/content/docs/concepts/operating_modes.adoc b/docs/content/docs/concepts/operating_modes.adoc index 1af801798..286e135fd 100644 --- a/docs/content/docs/concepts/operating_modes.adoc +++ b/docs/content/docs/concepts/operating_modes.adoc @@ -53,9 +53,9 @@ In this mode you can integrate heimdall with existing reverse proxies, or API ga +----------------+ .... -In this mode heimdall can be integrated with most probably all modern API gateways and reverse proxies as a so-called "authentication middleware". Here the reverse proxy, respectively API gateway integrating with heimdall, will forward requests to heimdall by making use of its decision service endpoint for authentication and authorization purposes. As in the link:{{< relref "#_proxy_mode" >}}[Reverse Proxy] mode, heimdall will check if these requests match and satisfy the conditions defined in the available rules. If not, heimdall returns an error to its client (here API gateway/reverse proxy). If the rule execution was successful, it also responds to the API gateway/reverse proxy with `200 OK` (can be overridden if required) and sets headers/cookies, specified in the matched rule, which are then forwarded to the upstream service. +In this mode heimdall can be integrated with most probably all modern API gateways and reverse proxies as a so-called "authentication middleware". Here the reverse proxy, respectively API gateway integrating with heimdall, will forward requests to heimdall by making use of its main service endpoint for authentication and authorization purposes. As in the link:{{< relref "#_proxy_mode" >}}[Reverse Proxy] mode, heimdall will check if these requests match and satisfy the conditions defined in the available rules. If not, heimdall returns an error to its client (here API gateway/reverse proxy). If the rule execution was successful, it also responds to the API gateway/reverse proxy with `200 OK` (can be overridden if required) and sets headers/cookies, specified in the matched rule, which are then forwarded to the upstream service. -Starting heimdall in this mode happens via the `serve decision` command. Head over to the description of link:{{< relref "/docs/operations/cli.adoc" >}}[CLI] as well as to link:{{< relref "/docs/services/decision.adoc" >}}[decision service configuration options] for more details. +Starting heimdall in this mode happens via the `serve decision` command. Head over to the description of link:{{< relref "/docs/operations/cli.adoc" >}}[CLI] as well as to link:{{< relref "/docs/services/main.adoc" >}}[corresponding configuration options] for more details. .Decision Service Example ==== @@ -129,7 +129,7 @@ In this operation mode you can use heimdall as a reverse proxy in front of your In this mode heimdall forwards requests to the upstream service if these satisfy the conditions defined in matched rules. Otherwise, heimdall returns an error to the client. If the execution of the rule was successful, it also forwards additional headers, specified in the rule to the upstream service. -Starting heimdall in this mode happens via the `serve proxy` command. Head over to the description of link:{{< relref "/docs/operations/cli.adoc" >}}[CLI] as well as to link:{{< relref "/docs/services/proxy.adoc" >}}[proxy service configuration options] for more details. +Starting heimdall in this mode happens via the `serve proxy` command. Head over to the description of link:{{< relref "/docs/operations/cli.adoc" >}}[CLI] as well as to link:{{< relref "/docs/services/main.adoc" >}}[main service configuration options] for more details. .Reverse Proxy Example ==== diff --git a/docs/content/docs/configuration/reference.adoc b/docs/content/docs/configuration/reference.adoc index 003571bbe..2236de2fe 100644 --- a/docs/content/docs/configuration/reference.adoc +++ b/docs/content/docs/configuration/reference.adoc @@ -16,103 +16,75 @@ Below you can find possible contents (not exhaustive) for Heimdall's `config.yam [source, yaml] ---- serve: - decision: - host: 127.0.0.1 - port: 4468 - respond: - verbose: true - with: - accepted: - code: 201 - authorization_error: - code: 404 - authentication_error: - code: 404 - timeout: - read: 2s - write: 5s - idle: 2m - buffer_limit: - read: 10KB - write: 10KB - tls: - key_store: - path: /path/to/key/store.pem - password: VerySecure! - trusted_proxies: - - 192.168.1.0/24 - - proxy: - host: 127.0.0.1 - port: 4469 - respond: - verbose: true - with: - authorization_error: - code: 404 - authentication_error: - code: 404 - timeout: - read: 2s - write: 5s - idle: 2m - connections_limit: - max_per_host: 10 - max_idle: 100 - max_idle_per_host: 50 - buffer_limit: - read: 10KB - write: 10KB - cors: - allowed_origins: - - example.org - allowed_methods: - - GET - - POST - allowed_headers: - - Authorization - exposed_headers: - - X-My-Header - allow_credentials: true - max_age: 1m - tls: - key_store: - path: /path/to/key/store.pem - password: VerySecure! - key_id: first_entry - min_version: TLS1.2 - cipher_suites: - - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 - trusted_proxies: - - 192.168.1.0/24 + host: 127.0.0.1 + port: 4469 + respond: + verbose: true + with: + authorization_error: + code: 404 + authentication_error: + code: 404 + timeout: + read: 2s + write: 5s + idle: 2m + connections_limit: + max_per_host: 10 + max_idle: 100 + max_idle_per_host: 50 + buffer_limit: + read: 10KB + write: 10KB + cors: + allowed_origins: + - example.org + allowed_methods: + - GET + - POST + allowed_headers: + - Authorization + exposed_headers: + - X-My-Header + allow_credentials: true + max_age: 1m + tls: + key_store: + path: /path/to/key/store.pem + password: VerySecure! + key_id: first_entry + min_version: TLS1.2 + cipher_suites: + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + trusted_proxies: + - 192.168.1.0/24 - management: - host: 127.0.0.1 - port: 4457 - verbose_errors: false - timeout: - read: 2s - write: 5s - idle: 2m - cors: - allowed_origins: - - example.org - allowed_methods: - - GET - - POST - allowed_headers: - - Authorization - exposed_headers: - - X-My-Header - allow_credentials: true - max_age: 1m - tls: - key_store: - path: /path/to/key/store.pem - min_version: TLS1.2 +management: + host: 127.0.0.1 + port: 4457 + timeout: + read: 2s + write: 5s + idle: 2m + cors: + allowed_origins: + - example.org + allowed_methods: + - GET + - POST + allowed_headers: + - Authorization + exposed_headers: + - X-My-Header + allow_credentials: true + max_age: 1m + tls: + key_store: + path: /path/to/key/store.pem + min_version: TLS1.2 cache: type: redis-sentinel diff --git a/docs/content/docs/getting_started/protect_an_app.adoc b/docs/content/docs/getting_started/protect_an_app.adoc index 640a80bdc..6bd010ac9 100644 --- a/docs/content/docs/getting_started/protect_an_app.adoc +++ b/docs/content/docs/getting_started/protect_an_app.adoc @@ -104,7 +104,7 @@ providers: watch: true ---- <1> Since heimdall emits logs on `error` level by default, and we would like to see what is going on, we are setting the log level to `debug`. This way, we'll see not only the results of a particular rule execution (which is what you would see if we set the log level to `info`), but also what is going in a rule. In addition, we disable tracing and metrics collection as these are pulled by default to an OTEL agent to avoid error statements related to unavailability of the agent. You can find more information about available observability options in the link:{{< relref "/docs/operations/observability.adoc#_logging" >}}[Observability] chapter. -<2> This configuration instructs heimdall to trust `X-Forwarded-*` headers from any sources. We need it here for integration purposes with Traefik, which uses these headers while forwarding requests to heimdall and which IP depends on your local docker configuration. Never do this in production and use allowed IPs instead! Please take also a look at the documentation of link:{{< relref "/docs/services/decision.adoc#_trusted_proxies" >}}[trusted_proxies] property and link:{{< relref "/docs/operations/security.adoc#_http_header_security_considerations" >}}[Security Considerations] for more details. +<2> This configuration instructs heimdall to trust `X-Forwarded-*` headers from any sources. We need it here for integration purposes with Traefik, which uses these headers while forwarding requests to heimdall and which IP depends on your local docker configuration. Never do this in production and use allowed IPs instead! Please take also a look at the documentation of link:{{< relref "/docs/services/main.adoc#_trusted_proxies" >}}[trusted_proxies] property and link:{{< relref "/docs/operations/security.adoc#_http_header_security_considerations" >}}[Security Considerations] for more details. <3> Here we define our link:{{< relref "/docs/mechanisms/catalogue.adoc" >}}[catalogue of mechanisms] to be used in link:{{< relref "/docs/rules/regular_rule.adoc" >}}[upstream service specific rules]. In this case we define authenticators, authorizer and finalizers <4> These two lines define the `link:{{< relref "/docs/mechanisms/authenticators.adoc#_unauthorized" >}}[unauthorized]` authenticator named `deny_all`. It rejects all requests. <5> These two lines define the `link:{{< relref "/docs/mechanisms/authenticators.adoc#_anonymous" >}}[anonymous]` authenticator named `anon`. It allows any request passing through and creates a subject with ID set to `anonymous`. You can find more information about the subject and other objects link:{{< relref "/docs/mechanisms/evaluation_objects.adoc#_subject" >}}[here]. @@ -294,7 +294,7 @@ services: - traefik.enable=true - traefik.http.routers.traefik_http.service=api@internal - traefik.http.routers.traefik_http.entrypoints=http - - traefik.http.middlewares.heimdall.forwardauth.address=http://heimdall:4456 # <2> + - traefik.http.middlewares.heimdall.forwardauth.address=http://heimdall:4455 # <2> - traefik.http.middlewares.heimdall.forwardauth.authResponseHeaders=Authorization heimdall: # <3> diff --git a/docs/content/docs/mechanisms/evaluation_objects.adoc b/docs/content/docs/mechanisms/evaluation_objects.adoc index 152225d44..9749e6717 100644 --- a/docs/content/docs/mechanisms/evaluation_objects.adoc +++ b/docs/content/docs/mechanisms/evaluation_objects.adoc @@ -115,7 +115,7 @@ This method returns the URL as valid URL string of a form `scheme:host/path?quer * *`ClientIPAddresses`*: _string array_ + -The list of IP addresses the request passed through with the first entry being the ultimate client of the request. Only available if heimdall is configured to trust the client, sending this information, e.g. in the `X-Forwarded-From` header (see e.g. Decision Service link:{{< relref "/docs/services/decision.adoc#_trusted_proxies" >}}[trusted_proxies] configuration for more details). +The list of IP addresses the request passed through with the first entry being the ultimate client of the request. Only available if heimdall is configured to trust the client, sending this information, e.g. in the `X-Forwarded-From` header (see also link:{{< relref "/docs/services/main.adoc#_trusted_proxies" >}}[trusted_proxies] configuration for more details). * *`Header(name)`*: _method_, + diff --git a/docs/content/docs/operations/configuration.adoc b/docs/content/docs/operations/configuration.adoc index d347bc783..0006531f6 100644 --- a/docs/content/docs/operations/configuration.adoc +++ b/docs/content/docs/operations/configuration.adoc @@ -17,7 +17,7 @@ Configuration in heimdall can refer to two different things: * the static startup configuration, which is the scope of this document and * the configuration of rules, respectively rule sets, which you can find link:{{< relref "/docs/rules/rule_sets.adoc" >}}[here]. -Elements in the static configuration set up the services, like link:{{< relref "/docs/services/decision.adoc" >}}[decision service], which basically define the entry points, heimdall will listen to, the observability capabilities, like link:{{< relref "/docs/operations/observability.adoc#_logging" >}}[logging], the link:{{< relref "/docs/concepts/mechanisms.adoc" >}}[mechanism catalogue], the link:{{< relref "/docs/rules/default_rule.adoc" >}}[default rule], as well as the link:{{< relref "/docs/rules/providers.adoc" >}}[rule providers] (these elements are not expected to change often). +Elements in the static configuration set up the services, like the link:{{< relref "/docs/services/main.adoc" >}}[main service], which basically defines the main entry point, heimdall will listen to for the actual access control decision purposes, the observability capabilities, like link:{{< relref "/docs/operations/observability.adoc#_logging" >}}[logging], the link:{{< relref "/docs/concepts/mechanisms.adoc" >}}[mechanism catalogue], the link:{{< relref "/docs/rules/default_rule.adoc" >}}[default rule], as well as the link:{{< relref "/docs/rules/providers.adoc" >}}[rule providers] (these elements are not expected to change often). The rule set contains everything that defines how the requests are handled by heimdall for your system. This configuration can change and is seamlessly hot-reloaded, without any request interruption or connection loss. @@ -138,23 +138,22 @@ HEIMDALLCFG_LOG_LEVEL=info * Array entries must be defined using `\_[_]`, with `IDX` being the index of the array starting with `0` and `_` in brackets being only required, if the value of the configured element has a structure/hierarchy. + -E.g. the `trusted_proxies` property of the link:{{< relref "/docs/services/decision.adoc" >}}[decision service] can be configured in a config file as +E.g. the `trusted_proxies` property of the link:{{< relref "/docs/services/main.adoc" >}}[main service] can be configured in a config file as + [source,yaml] ---- serve: - decision: - trusted_proxies: - - 192.168.1.0/24 - - 192.168.2.0/24 + trusted_proxies: + - 192.168.1.0/24 + - 192.168.2.0/24 ---- + and using environment variables with + [source,bash] ---- -HEIMDALLCFG_SERVE_DECISION_TRUSTED__PROXIES_0=192.168.1.0/24 -HEIMDALLCFG_SERVE_DECISION_TRUSTED__PROXIES_0=192.168.2.0/24 +HEIMDALLCFG_SERVE_TRUSTED__PROXIES_0=192.168.1.0/24 +HEIMDALLCFG_SERVE_TRUSTED__PROXIES_0=192.168.2.0/24 ---- + For structured configuration, like the definition of the authenticators in the example above diff --git a/docs/content/docs/operations/observability.adoc b/docs/content/docs/operations/observability.adoc index 9469e974e..50bf66621 100644 --- a/docs/content/docs/operations/observability.adoc +++ b/docs/content/docs/operations/observability.adoc @@ -147,7 +147,7 @@ If the event has been emitted for a GRPC request, following fields are set: * `_grpc_method` - The full GRPC method used. -If the request comes from an intermediary, like e.g. an API Gateway and heimdall is configured to trust that "proxy" (see link:{{< relref "/docs/services/decision.adoc#_trusted_proxies" >}}[`trusted_proxies` configuration] of the Decision service, as well as the link:{{< relref "/docs/services/proxy.adoc#_trusted_proxies" >}}[`trusted_proxies` configuration] of the Proxy service), then following fields will be part of the events as well if the corresponding HTTP headers were sent. +If the request comes from an intermediary, like e.g. an API Gateway and heimdall is configured to trust that "proxy" (see link:{{< relref "/docs/services/main.adoc#_trusted_proxies" >}}[`trusted_proxies` configuration]), then following fields will be part of the events as well if the corresponding HTTP headers were sent. * `_http_x_forwarded_proto` - The value of the "X-Forwarded-Proto" header. * `_http_x_forwarded_host` - The value of the "X-Forwarded-Host" header. @@ -345,7 +345,7 @@ You can also disable metrics export by setting the `OTEL_METRICS_EXPORTER` envir All, but custom metrics adhere to the https://opentelemetry.io/docs/specs/otel/metrics/semantic_conventions/[OpenTelementry semantic conventions]. For that reason, only the custom metrics are listed in the table below. ==== Metric: `certificate.expiry` -Number of seconds until a certificate used by a particular service (decision, proxy, management), or mechanism (e.g. jwt finalizer) expires. The metric type is UpDownCounter und the unit is s. +Number of seconds until a certificate used by a particular service (main, management), or mechanism (e.g. jwt finalizer) expires. The metric type is UpDownCounter und the unit is s. [cols="2,1,5"] |=== diff --git a/docs/content/docs/operations/security.adoc b/docs/content/docs/operations/security.adoc index ad9fd68e6..66de298d0 100644 --- a/docs/content/docs/operations/security.adoc +++ b/docs/content/docs/operations/security.adoc @@ -14,7 +14,7 @@ description: To operate heimdall in a secure way, you should configure heimdall == HTTP Header Security Considerations -If `trusted_proxies` property is configured (see also the corresponding link:{{< relref "/docs/services/decision.adoc#_trusted_proxies" >}}[Decision] and link:{{< relref "/docs/services/proxy.adoc#_trusted_proxies" >}}[Proxy] service configuration options) to let heimdall make use of different HTTP headers to build the URL for rule and HTTP method matching purposes, following logic apply: +If `trusted_proxies` property is configured (see also the corresponding link:{{< relref "/docs/services/main.adoc#_trusted_proxies" >}}[configuration options]) to let heimdall make use of different HTTP headers to build the URL for rule and HTTP method matching purposes, following logic apply: * The value for the used HTTP scheme is taken from the `X-Forwarded-Proto` header. * The value for the used HTTP host and port is taken from the `X-Forwarded-Host` header. @@ -53,7 +53,7 @@ heimdall container image is shipped without any certificates by intention to ens E.g. [source, bash] ---- -docker run -t -p 4456:4456 \ +docker run -t -p 4455:4455 \ -v $PWD:/heimdall/conf \ -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro \ dadrus/heimdall:dev serve decision \ diff --git a/docs/content/docs/services/decision.adoc b/docs/content/docs/services/decision.adoc deleted file mode 100644 index 3cb8b16f6..000000000 --- a/docs/content/docs/services/decision.adoc +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: "Decision Service" -date: 2022-06-09T18:55:36+02:00 -draft: false -weight: 41 -menu: - docs: - weight: 1 - parent: "Services" -description: Decision service implements the decision operating mode using which you can integrate heimdall with existing reverse proxies, or API gateways. ---- - -:toc: - -To make use of this service you have to start heimdall with `heimdall serve decision` or `heimdall serve decision --envoy-grpc`. By default, heimdall listens on `0.0.0.0:4456` endpoint for incoming requests in this mode of operation and also configures useful default timeouts, as well as buffer limits. No other options are configured. You can, and should however adjust the configuration for your needs. - -== Configuration - -The configuration of the Decision service can be adjusted in the `decision` property, which lives in the `serve` property of heimdall's configuration and supports the following properties. - -* *`host`*: _string_ (optional) -+ -By making use of this property, you can specify the TCP/IP address on which heimdall should listen for connections from client applications. The entry `0.0.0.0` allows listening for all IPv4 addresses. `0.0.0.0` is also the default setting. - -* *`port`*: _integer_ (optional) -+ -By making use of this property, you can specify the TCP port the heimdall should listen on. Defaults to `4456`. - -* *`timeout`*: _Timeout_ (optional) -+ -By using this property you can override the default timeouts used by heimdall. Following properties are supported: - -** *`idle`*: _link:{{< relref "/docs/configuration/types.adoc#_duration" >}}[Duration]_ (optional) -+ -The maximum amount of time to wait for the next request when keep-alive is enabled. If set to 0, the value of the `read` timeout is used. Defaults to 2 minutes. - -** *`read`*: _link:{{< relref "/docs/configuration/types.adoc#_duration" >}}[Duration]_ (optional) -+ -The absolute amount of time allowed to read the entire request, including body. Defaults to 5 seconds. Setting this property to 0s will disable the timeout. - -** *`write`*: _link:{{< relref "/docs/configuration/types.adoc#_duration" >}}[Duration]_ (optional) -+ -The maximum duration before timing out writes of the response. Defaults to 10 seconds. Setting this property to 0s will disable the timeout. - -* *`buffer_limit`*: _BufferLimit_ (optional) -+ -Buffer limits for inbound requests and outbound responses. Following configuration properties are supported: - -** *`read`*: _link:{{< relref "/docs/configuration/types.adoc#_bytesize" >}}[ByteSize]_ (optional) -+ -The maximum size for the read buffer allowed to read the full request including body. Defaults to 4KB. - -** *`write`*: _link:{{< relref "/docs/configuration/types.adoc#_bytesize" >}}[ByteSize]_ (optional) -+ -The maximum size for the write buffer of the response. Defaults to 4KB. - -* *`tls`*: _link:{{< relref "/docs/configuration/types.adoc#_tls" >}}[TLS]_ (optional) -+ -By default, the Decision service accepts HTTP requests. Depending on your deployment scenario, you could require Heimdall to accept HTTPs requests only (which is highly recommended). You can do so by making use of this option. - -[#_trusted_proxies] -* *`trusted_proxies`*: _string array_ (optional) -+ -The usage of the Decision service makes only sense, if operated behind some sort of proxy, like API Gateway, etc. In such cases certain header information may be sent to Heimdall using e.g. special `X-Forwarded-*` headers or the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded[Forwarded] header. For example, the `Host` HTTP header is usually used to set the requested host. But when you’re behind a proxy, the actual host may be stored in an `X-Forwarded-Host` header, which could, however, also be spoofed. -+ -Depending on the integration options offered by those systems, which are used to integrate heimdall with, you may need to rely on the aforesaid headers. In such cases, you have to configure the `trusted_proxies` option and list the IPs, or IP ranges (CIDR notation) of your proxies, which integrate with heimdall. If not configured, heimdall will not accept those headers from any client to prevent spoofing as it might result in privilege escalation. -+ -CAUTION: Please consider link:{{< relref "/docs/operations/security.adoc#_http_header_security_considerations" >}}[security implications] when making use of this property. - -* *`respond`*: _link:{{< relref "/docs/configuration/types.adoc#_respond" >}}[Respond]_ (optional) -+ -By making use of this property you can instruct heimdall to preserve error information and provide it in the response body to the caller, as well as to use HTTP status codes deviating from those heimdall would usually use. - -.Complex decision service configuration. -==== -[source, yaml] ----- -decision: - host: 127.0.0.1 - tls: - key_store: - path: /path/to/keystore.pem - password: VerySecure! - timeout: - read: 1s - write: 2s - idle: 30s - buffer_limit: - read: 4KB - write: 10KB - trusted_proxies: - - 192.168.1.0/24 - respond: - verbose: true - with: - authentication_error: - code: 404 - authorization_error: - code: 404 ----- -==== diff --git a/docs/content/docs/services/proxy.adoc b/docs/content/docs/services/main.adoc similarity index 77% rename from docs/content/docs/services/proxy.adoc rename to docs/content/docs/services/main.adoc index e0551e60a..d3a5d1948 100644 --- a/docs/content/docs/services/proxy.adoc +++ b/docs/content/docs/services/main.adoc @@ -1,22 +1,22 @@ --- -title: "Proxy Service" +title: "Main Service" date: 2022-06-09T18:55:45+02:00 draft: false -weight: 42 +weight: 41 menu: docs: weight: 2 parent: "Services" -description: When heimdall is started exposing this service, you can make use of heimdall's proxy operating mode and use it as a proxy in front of your upstream API or web server +description: This is heimdalls' main service responsible for driving the actual access control decision process. --- :toc: -To make use of this service you have to start Heimdall with `heimdall serve proxy`. By default, Heimdall listens on `0.0.0.0:4455` endpoint for incoming requests in this mode of operation and also configures useful default timeouts, amount of possible upstream connections is active and idle state, as well as buffer limits. No other options are configured. You can, and should however adjust the configuration for your needs. +To make use of this service you have to start Heimdall with either `heimdall serve proxy` or `heimdall serve decision`. By default, Heimdall listens on `0.0.0.0:4455` endpoint for incoming requests and also configures useful defaults. You can, and should however adjust the configuration for your needs. == Configuration -The configuration of the Proxy endpoint can be adjusted in the `proxy` property, which lives in the `serve` property of heimdall's configuration and supports the following properties. +The configuration of the Main endpoint can be adjusted in the `serve` property, which lives on the top level of heimdall's configuration and supports the following properties. * *`host`*: _string_ (optional) + @@ -32,17 +32,17 @@ By using this property you can override the default timeouts used by heimdall. F ** *`idle`*: _link:{{< relref "/docs/configuration/types.adoc#_duration" >}}[Duration]_ (optional) + -The maximum amount of time to wait for the next request when keep-alive is enabled. If set to 0, the value of the `read` timeout is used. Defaults to 2 minutes. This value is also used for the maximum amount of time an idle (keep-alive) connection to the upstream will remain idle before closing itself. +The maximum amount of time to wait for the next request when keep-alive is enabled. If set to 0, the value of the `read` timeout is used. Defaults to 2 minutes. If heimdall is operated in proxy mode, this value is also used for the maximum amount of time an idle (keep-alive) connection to the upstream will remain idle before closing itself. ** *`read`*: _link:{{< relref "/docs/configuration/types.adoc#_duration" >}}[Duration]_ (optional) + -The absolute amount of time allowed to read the entire request, including body. Defaults to 5 seconds. The `read` timeout is also used while waiting for the responses from the upstream service. Here it specifies the amount of time to wait for a server's response headers after fully writing the request (including its body, if any). Upon successful upgrade responses from the upstream service, this timeout is disabled, allowing e.g. for WebSockets proxying. Setting this property to 0s will disable the timeout. +The absolute amount of time allowed to read the entire request, including body. Defaults to 5 seconds. If heimdall is operated in proxy mode, the `read` timeout is also used while waiting for the responses from the upstream service. Here it specifies the amount of time to wait for a server's response headers after fully writing the request (including its body, if any). Upon successful upgrade responses from the upstream service, this timeout is disabled, allowing e.g. for WebSockets proxying. Setting this property to 0s will disable the timeout. + CAUTION: Setting this timout to 0 will make heimdall vulnerable to https://en.wikipedia.org/wiki/Slowloris_(computer_security[Slowloris attacks]. ** *`write`*: _link:{{< relref "/docs/configuration/types.adoc#_duration" >}}[Duration]_ (optional) + -The maximum duration before timing out writes of the response. Defaults to 10 seconds. Setting this property to 0s will disable the timeout. Compared to the `read` timeout, the `write` timeout is not absolute and reset each time data is written to the output stream. This allows Server-Sent-Events and other unidirectional communication without the need to extend the timeout. As with the `read` timeout, this timeout is disabled upon successful upgrade responses from the upstream service, allowing e.g. for WebSockets proxying. +The maximum duration before timing out writes of the response. Defaults to 10 seconds. Setting this property to 0s will disable the timeout. Compared to the `read` timeout, the `write` timeout is not absolute and reset each time data is written to the output stream if heimdall is operated in proxy mode. This allows Server-Sent-Events and other unidirectional communication without the need to extend the timeout. As with the `read` timeout, this timeout is disabled upon successful upgrade responses from the upstream service, allowing e.g. for WebSockets proxying. * *`buffer_limit`*: _BufferLimit_ (optional) + @@ -58,7 +58,7 @@ The maximum size for the write buffer of the response. Defaults to 4KB. * *`connections_limit`*: _ConnectionsLimit_ (optional) + -Allowed connections limit per upstream service. Following limits can be configured: +If heimdall is operated in proxy mode, this property configures allowed connections limit per upstream service (ignored in decision mode). Following limits can be configured: ** *`max_per_host`*: _integer_ (optional) + @@ -99,7 +99,7 @@ NOTE: This mapping is only applicable if the HTTP status code is set by heimdall ==== [source, yaml] ---- -proxy: +serve: host: 172.17.0.2 tls: key_store: diff --git a/docs/content/docs/services/management.adoc b/docs/content/docs/services/management.adoc index 81c8f2b42..7beed13b4 100644 --- a/docs/content/docs/services/management.adoc +++ b/docs/content/docs/services/management.adoc @@ -2,7 +2,7 @@ title: "Management Service" date: 2022-06-09T18:55:36+02:00 draft: false -weight: 43 +weight: 42 menu: docs: weight: 3 diff --git a/docs/content/guides/proxies/contour.adoc b/docs/content/guides/proxies/contour.adoc index 5d0cbebf3..40f133d79 100644 --- a/docs/content/guides/proxies/contour.adoc +++ b/docs/content/guides/proxies/contour.adoc @@ -38,19 +38,18 @@ spec: # ... ---- -* If TLS is enabled, which, as said above, is required for integration with Contour, by default heimdall is configured to support TLS v1.3 only. However, it looks like Contour does not configure Envoy to support TLS v1.3 so that the communication with heimdall happens via TLS v1.2 and below. For that reason you have to configure the decision service of heimdall to TLS v1.2 being the minimum supported version. Otherwise, Envoy will not be able communicating with heimdall, resulting in `403` responses for any request. The following snippet shows the relevant parts in the heimdall configuration file: +* If TLS is enabled, which, as said above, is required for integration with Contour, by default heimdall is configured to support TLS v1.3 only. However, it looks like Contour does not configure Envoy to support TLS v1.3 so that the communication with heimdall happens via TLS v1.2 and below. For that reason you have to configure the main service of heimdall to TLS v1.2 being the minimum supported version. Otherwise, Envoy will not be able communicating with heimdall, resulting in `403` responses for any request. The following snippet shows the relevant parts in the heimdall configuration file: + [source, yaml] ---- # ... serve: - decision: - tls: - # important! see explanations above - min_version: TLS1.2 - key_store: - # path to the pem file with key and certificates - path: /certs/tls-combined.pem + tls: + # important! see explanations above + min_version: TLS1.2 + key_store: + # path to the pem file with key and certificates + path: /certs/tls-combined.pem # ... ---- @@ -84,7 +83,7 @@ spec: protocol: h2 services: - name: heimdall - port: 4456 + port: 4455 ---- + The `ExtensionService` resource definition tells Contour to program Envoy with an upstream cluster directing traffic to heimdall. That way, as also described in the link:{{< relref "envoy.adoc" >}}[Envoy Integration Guide], Envoy will delegate authentication and authorization to heimdall. If heimdall answers with a `200 OK` HTTP code, Envoy grants access and forwards the original request to the upstream service. Otherwise, the response from heimdall is treated as an error and is returned to the client. diff --git a/docs/content/guides/proxies/emissary.adoc b/docs/content/guides/proxies/emissary.adoc index 01a4d745c..dee87da85 100644 --- a/docs/content/guides/proxies/emissary.adoc +++ b/docs/content/guides/proxies/emissary.adoc @@ -34,11 +34,11 @@ metadata: name: heimdall namespace: heimdall spec: - auth_service: "https://..svc.cluster.local:" <1> + auth_service: "https://..svc.cluster.local:" <1> proto: grpc protocol_version: v3 <2> ---- -<1> Configures the controller to use heimdall's decision service endpoint with ``, `` and `` depending on your configuration. If heimdall is not operated in the same namespace as the ingress controller, it is important to configure the full DNS, otherwise Envoy will not be able to resolve the IP of heimdall. +<1> Configures the controller to use heimdall's main service endpoint with ``, `` and `` depending on your configuration. If heimdall is not operated in the same namespace as the ingress controller, it is important to configure the full DNS, otherwise Envoy will not be able to resolve the IP of heimdall. <2> Sets the used Envoy's ExtAuth GRPC protocol version to v3, as this is the only version supported by heimdall. If not set, Emissary will default to v2. NOTE: The integration option shown above requires usage of the `--envoy-grpc` flag when starting heimdall. Unlike e.g. Contour, Emissary-Ingress allows however the usage of both, the https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto[Envoy's external authorization GRPC] protocol (used here), and the plain HTTP protocol. diff --git a/docs/content/guides/proxies/envoy.adoc b/docs/content/guides/proxies/envoy.adoc index f98938717..8e60e2732 100644 --- a/docs/content/guides/proxies/envoy.adoc +++ b/docs/content/guides/proxies/envoy.adoc @@ -56,7 +56,7 @@ clusters: address: socket_address: address: heimdall - port_value: 4456 + port_value: 4455 # other cluster entries ---- <1> The name of our cluster @@ -79,7 +79,7 @@ http_filters: transport_api_version: V3 # <2> http_service: server_uri: # <3> - uri: heimdall:4456 + uri: heimdall:4455 cluster: ext-authz timeout: 0.25s authorization_request: @@ -175,7 +175,7 @@ static_resources: transport_api_version: V3 http_service: server_uri: - uri: heimdall:4456 + uri: heimdall:4455 cluster: ext-authz timeout: 0.25s authorization_request: @@ -212,7 +212,7 @@ static_resources: address: socket_address: address: heimdall - port_value: 4456 + port_value: 4455 - name: services connect_timeout: 5s type: strict_dns diff --git a/docs/content/guides/proxies/envoy_gateway.adoc b/docs/content/guides/proxies/envoy_gateway.adoc index f33db00c5..dbc52db89 100644 --- a/docs/content/guides/proxies/envoy_gateway.adoc +++ b/docs/content/guides/proxies/envoy_gateway.adoc @@ -54,7 +54,7 @@ spec: grpc: backendRef: # <4> name: heimdall - port: 4456 + port: 4455 namespace: heimdall ---- <1> The name of the `SecurityPolicy`. You can change it to any other value if you like. @@ -82,7 +82,7 @@ spec: grpc: backendRef: # <4> name: heimdall - port: 4456 + port: 4455 namespace: heimdall ---- <1> The name of the `SecurityPolicy`. You can change it to any other value if you like. @@ -107,7 +107,7 @@ spec: kind: Service namespace: heimdall name: heimdall - sectionName: "4456" + sectionName: "4455" tls: # <3> caCertRefs: - name: demo-ca # <4> diff --git a/docs/content/guides/proxies/haproxy.adoc b/docs/content/guides/proxies/haproxy.adoc index 8a462980e..f4f1542a3 100644 --- a/docs/content/guides/proxies/haproxy.adoc +++ b/docs/content/guides/proxies/haproxy.adoc @@ -36,14 +36,14 @@ To have the integration configured globally and used for all workloads, you have apiVersion: v1 kind: ConfigMap data: - auth-url: "https://..svc.cluster.local:" # <1> + auth-url: "https://..svc.cluster.local:" # <1> auth-headers-succeed: "authorization" # <2> headers: | # <3> X-Forwarded-Uri: %[pathq] X-Forwarded-Method: %[method] X-Forwarded-Host: %[req.hdr(host)] ---- -<1> Configures the controller to use heimdall's decision service endpoint with ``, `` and `` depending on your configuration. +<1> Configures the controller to use heimdall's main service endpoint with ``, `` and `` depending on your configuration. <2> Let HAProxy forward the `Authorization` header set by heimdall to the upstream service upon successful response. This configuration depends on your link:{{< relref "/docs/mechanisms/contextualizers.adoc" >}}[Contextualizers] and link:{{< relref "/docs/mechanisms/finalizers.adoc" >}}[Finalizers] configuration. + @@ -60,7 +60,7 @@ The code snipped below shows the required annotations on the ingress rule. It us [source, yaml] ---- annotations: - haproxy-ingress.github.io/auth-url: "https://..svc.cluster.local:" + haproxy-ingress.github.io/auth-url: "https://..svc.cluster.local:" haproxy-ingress.github.io/auth-headers-succeed: "authorization" haproxy-ingress.github.io/headers: | X-Forwarded-Uri: %[pathq] diff --git a/docs/content/guides/proxies/istio.adoc b/docs/content/guides/proxies/istio.adoc index fba43a7b3..869ac795a 100644 --- a/docs/content/guides/proxies/istio.adoc +++ b/docs/content/guides/proxies/istio.adoc @@ -57,7 +57,7 @@ data: - name: heimdall-ext-auth # <1> envoyExtAuthzGrpc: # <2> service: heimdall.heimdall.svc.cluster.local # <3> - port: "4456" + port: "4455" ---- <1> `heimdall-ext-auth` is the name of our extension provider, which will be referenced later in the https://istio.io/latest/docs/reference/config/security/authorization-policy/[`AuthorizationPolicy`] configuration. <2> We're using a gRPC based implementation here. However, since Istio does not automatically configure Envoy to use HTTP/2 for gRPC calls, it requires an additional https://istio.io/latest/docs/reference/config/networking/envoy-filter/[`EnvoyFilter`] resource. This appears to be a bug in Istio's implementation. @@ -77,7 +77,7 @@ data: - name: heimdall-ext-auth envoyExtAuthzHttp: service: heimdall.heimdall.svc.cluster.local - port: "4456" + port: "4455" includeRequestHeadersInCheck: [ "authorization", "cookie", "accept", "x-forwarded-for", "x-forwarded-proto", "x-forwarded-host" ] # <1> headersToUpstreamOnAllow: [ "authorization" ] # <2> ---- @@ -102,7 +102,7 @@ spec: match: # <3> context: GATEWAY cluster: - name: outbound|4456||heimdall.heimdall.svc.cluster.local + name: outbound|4455||heimdall.heimdall.svc.cluster.local patch: operation: MERGE value: diff --git a/docs/content/guides/proxies/nginx.adoc b/docs/content/guides/proxies/nginx.adoc index 4c77a126e..49834f577 100644 --- a/docs/content/guides/proxies/nginx.adoc +++ b/docs/content/guides/proxies/nginx.adoc @@ -47,7 +47,7 @@ location @error401 { Since NGINX is highly configurable and heimdall supports different integration options, you can use any of the configuration examples given below. All of these enable heimdall to build the URL of the protected backend server for rule matching purposes. -In most cases you must configure heimdall to trust your NGINX instances by setting link:{{< relref "/docs/services/decision.adoc#_trusted_proxies" >}}[`trusted_proxies`] for the Decision, respectively Proxy service. Exceptions are described in the sections below. +In most cases you must configure heimdall to trust your NGINX instances by setting link:{{< relref "/docs/services/main.adoc#_trusted_proxies" >}}[`trusted_proxies`]. Exceptions are described in the sections below. [#_first_option] === Forward only the path and query information @@ -75,7 +75,7 @@ location = /_auth { <4> internal; access_log off; proxy_method $request_method; <5> - proxy_pass http://heimdall:4456$request_uri; <6> + proxy_pass http://heimdall:4455$request_uri; <6> proxy_pass_request_body off; <7> proxy_set_header Content-Length ""; proxy_set_header Host $http_host; <8> @@ -106,7 +106,7 @@ NOTE: Proper configuration of `trusted_proxies` is mandatory if using this optio location = /_auth { internal; - proxy_pass http://heimdall:4456; <1> + proxy_pass http://heimdall:4455; <1> proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Forwarded-Method $request_method; <2> @@ -134,7 +134,7 @@ Global configuration can be achieved by setting the following properties in cont [source, yaml] ---- -global-auth-url: "http://..svc.cluster.local:" # <1> +global-auth-url: "http://..svc.cluster.local:" # <1> global-auth-response-headers: Authorization # <2> global-auth-snippet: | # <3> proxy_set_header X-Forwarded-Method $request_method; @@ -142,7 +142,7 @@ global-auth-snippet: | # <3> proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Uri $request_uri; ---- -<1> Configures the controller to use heimdall's decision service endpoint with ``, `` and `` depending on your configuration. +<1> Configures the controller to use heimdall's main service endpoint with ``, `` and `` depending on your configuration. <2> Let NGINX forward the `Authorization` header set by heimdall to the upstream service upon successful response. This configuration depends on your link:{{< relref "/docs/mechanisms/contextualizers.adoc" >}}[Contextualizers] and link:{{< relref "/docs/mechanisms/finalizers.adoc" >}}[Finalizers] configuration. If not configured, NGINX will only react on `Set-Cookie` headers in responses from heimdall by default. <3> Configures the required headers to pass the information about the used HTTP scheme, host and port, request path and used query parameters to be forwarded to heimdall. @@ -173,7 +173,7 @@ server-snippet: | internal; access_log off; proxy_method $request_method; - proxy_pass http://..svc.cluster.local:$request_uri; + proxy_pass http://..svc.cluster.local:$request_uri; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header Host $http_host; @@ -190,7 +190,7 @@ One option to integrate heimdall with the NGINX Ingress Controller on the `Ingre [source, yaml] ---- -nginx.ingress.kubernetes.io/auth-url: "http://..svc.cluster.local:" +nginx.ingress.kubernetes.io/auth-url: "http://..svc.cluster.local:" nginx.ingress.kubernetes.io/auth-response-headers: Authorization nginx.ingress.kubernetes.io/auth-snippet: | proxy_set_header X-Forwarded-Method $request_method; @@ -220,7 +220,7 @@ nginx.ingress.kubernetes.io/server-snippet: | internal; access_log off; proxy_method $request_method; - proxy_pass http://..svc.cluster.local:$request_uri; + proxy_pass http://..svc.cluster.local:$request_uri; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header Host $http_host; diff --git a/docs/content/guides/proxies/traefik.adoc b/docs/content/guides/proxies/traefik.adoc index 5077ee236..550bf4222 100644 --- a/docs/content/guides/proxies/traefik.adoc +++ b/docs/content/guides/proxies/traefik.adoc @@ -19,7 +19,7 @@ https://doc.traefik.io/traefik/[Traefik Proxy] is a modern HTTP proxy and load b [CAUTION] ==== -Traefik makes use of `X-Forwarded-*` HTTP headers to forward the HTTP method, protocol, host, etc. to the ForwardAuth middleware. By default, heimdall does not trust those. To allow heimdall making use of such headers, you must configure link:{{< relref "/docs/services/decision.adoc#_trusted_proxies" >}}[trusted proxies] in heimdall's decision service configuration to contain the IPs or networks of your traefik instances. For test purposes, you can set it to "0.0.0.0/0", which would basically disable the check and let heimdall trust requests from any source. +Traefik makes use of `X-Forwarded-*` HTTP headers to forward the HTTP method, protocol, host, etc. to the ForwardAuth middleware. By default, heimdall does not trust those. To allow heimdall making use of such headers, you must configure link:{{< relref "/docs/services/main.adoc#_trusted_proxies" >}}[trusted proxies] in heimdall's main service configuration to contain the IPs or networks of your traefik instances. For test purposes, you can set it to "0.0.0.0/0", which would basically disable the check and let heimdall trust requests from any source. ==== Traefik can be configured statically, but also load dynamic configuration from many sources managed by so-called providers. The following sections describe how to integrate with heimdall using some of them. @@ -47,7 +47,7 @@ http: middlewares: heimdall: # <2> forwardAuth: # <3> - address: "https://heimdall:4456" # <4> + address: "https://heimdall:4455" # <4> authResponseHeaders: - Authorization # <5> @@ -73,7 +73,7 @@ metadata: # <1> namespace: heimdall spec: forwardAuth: # <2> - address: "http://heimdall.heimdall.svc.cluster.local:4456" # <3> + address: "http://heimdall.heimdall.svc.cluster.local:4455" # <3> authResponseHeaders: # <4> - Authorization ---- @@ -125,7 +125,7 @@ services: # other config options labels: # other labels - - traefik.http.middlewares.heimdall.forwardauth.address=http://heimdall:4456 # <3> + - traefik.http.middlewares.heimdall.forwardauth.address=http://heimdall:4455 # <3> - traefik.http.middlewares.heimdall.forwardauth.authResponseHeaders=Authorization # <4> heimdall: diff --git a/example_config.yaml b/example_config.yaml index 74c6924ab..12f3d6c00 100644 --- a/example_config.yaml +++ b/example_config.yaml @@ -1,31 +1,25 @@ serve: - decision: - port: 4468 - trusted_proxies: - - 0.0.0.0/0 - respond: - verbose: true - with: - accepted: - code: 200 - authorization_error: - code: 404 - authentication_error: - code: 404 - - proxy: - port: 4469 - tls: - key_store: - path: /path/to/file.pem - min_version: TLS1.2 - cipher_suites: - - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 - trusted_proxies: - - 0.0.0.0/0 + port: 4468 + tls: + key_store: + path: /path/to/file.pem + min_version: TLS1.2 + cipher_suites: + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + trusted_proxies: + - 0.0.0.0/0 + respond: + verbose: true + with: + accepted: + code: 200 + authorization_error: + code: 404 + authentication_error: + code: 404 log: level: debug diff --git a/examples/docker-compose/quickstarts/README.md b/examples/docker-compose/quickstarts/README.md index f803442a2..74462d34f 100644 --- a/examples/docker-compose/quickstarts/README.md +++ b/examples/docker-compose/quickstarts/README.md @@ -62,13 +62,13 @@ In that setup heimdall is integrated with Envoy Proxy. All requests are sent to docker compose -f docker-compose.yaml -f docker-compose-envoy-http.yaml up ``` - to see integration using the HTTP decision service in action, or + to see integration over HTTP in action, or ```bash docker compose -f docker-compose.yaml -f docker-compose-envoy-grpc.yaml up ``` - to see integration using the envoy GRPC extauthz decision service in action (not available before v0.7.0-alpha). + to see the envoy GRPC extauthz integration in action (not available before v0.7.0-alpha). 2. Play with it diff --git a/examples/docker-compose/quickstarts/docker-compose-traefik.yaml b/examples/docker-compose/quickstarts/docker-compose-traefik.yaml index def814378..4b0676b7f 100644 --- a/examples/docker-compose/quickstarts/docker-compose-traefik.yaml +++ b/examples/docker-compose/quickstarts/docker-compose-traefik.yaml @@ -14,7 +14,7 @@ services: - traefik.enable=true - traefik.http.routers.traefik_http.service=api@internal - traefik.http.routers.traefik_http.entrypoints=http - - traefik.http.middlewares.heimdall.forwardauth.address=http://heimdall:4456 + - traefik.http.middlewares.heimdall.forwardauth.address=http://heimdall:4455 - traefik.http.middlewares.heimdall.forwardauth.authResponseHeaders=Authorization heimdall: diff --git a/examples/docker-compose/quickstarts/envoy-config-grpc.yaml b/examples/docker-compose/quickstarts/envoy-config-grpc.yaml index 1b411b7ba..f20bcd1fc 100644 --- a/examples/docker-compose/quickstarts/envoy-config-grpc.yaml +++ b/examples/docker-compose/quickstarts/envoy-config-grpc.yaml @@ -48,7 +48,7 @@ static_resources: address: socket_address: address: heimdall - port_value: 4456 + port_value: 4455 - name: services connect_timeout: 5s type: strict_dns diff --git a/examples/docker-compose/quickstarts/envoy-config-http.yaml b/examples/docker-compose/quickstarts/envoy-config-http.yaml index 0f4ade171..3b7de1132 100644 --- a/examples/docker-compose/quickstarts/envoy-config-http.yaml +++ b/examples/docker-compose/quickstarts/envoy-config-http.yaml @@ -18,7 +18,7 @@ static_resources: transport_api_version: V3 http_service: server_uri: - uri: heimdall:4456 + uri: heimdall:4455 cluster: ext-authz timeout: 0.25s authorization_request: @@ -55,7 +55,7 @@ static_resources: address: socket_address: address: heimdall - port_value: 4456 + port_value: 4455 - name: services connect_timeout: 5s type: strict_dns diff --git a/examples/docker-compose/quickstarts/heimdall-config.yaml b/examples/docker-compose/quickstarts/heimdall-config.yaml index 0ec56160e..722d50dc0 100644 --- a/examples/docker-compose/quickstarts/heimdall-config.yaml +++ b/examples/docker-compose/quickstarts/heimdall-config.yaml @@ -8,8 +8,7 @@ metrics: enabled: false serve: - decision: - trusted_proxies: + trusted_proxies: - 0.0.0.0/0 mechanisms: diff --git a/examples/kubernetes/haproxy/helm-values.yaml b/examples/kubernetes/haproxy/helm-values.yaml index 20f3d4059..4339d724f 100644 --- a/examples/kubernetes/haproxy/helm-values.yaml +++ b/examples/kubernetes/haproxy/helm-values.yaml @@ -5,7 +5,7 @@ controller: # Uncomment the below lines for a global configuration.metrics: # See also https://github.com/jcmoraisjr/haproxy-ingress/issues/1105 # config: -# auth-url: "https://heimdall.heimdall.svc.cluster.local:4456" +# auth-url: "https://heimdall.heimdall.svc.cluster.local:4455" # auth-headers-succeed: "authorization" # headers: | # X-Forwarded-Uri: %[baseq] diff --git a/examples/kubernetes/istio/envoy-filter.yaml b/examples/kubernetes/istio/envoy-filter.yaml index d8160e5c5..d8203284e 100644 --- a/examples/kubernetes/istio/envoy-filter.yaml +++ b/examples/kubernetes/istio/envoy-filter.yaml @@ -12,7 +12,7 @@ spec: match: context: GATEWAY cluster: - name: outbound|4456||heimdall.heimdall.svc.cluster.local + name: outbound|4455||heimdall.heimdall.svc.cluster.local patch: operation: MERGE value: diff --git a/examples/kubernetes/istio/istio-values.yaml b/examples/kubernetes/istio/istio-values.yaml index 940ccfade..93e9b77d2 100644 --- a/examples/kubernetes/istio/istio-values.yaml +++ b/examples/kubernetes/istio/istio-values.yaml @@ -20,10 +20,10 @@ meshConfig: # Istio doesn't configure HTTP 2 for GRPC communication. EnvoyFilter is required envoyExtAuthzGrpc: service: heimdall.heimdall.svc.cluster.local - port: "4456" + port: "4455" # alternatively, one can use the config from below. In that case EnvoyFilter is not needed #envoyExtAuthzHttp: # service: heimdall.heimdall.svc.cluster.local - # port: "4456" + # port: "4455" # includeRequestHeadersInCheck: [ "authorization", "cookie", "accept", "x-forwarded-for", "x-forwarded-proto", "x-forwarded-host" ] # headersToUpstreamOnAllow: [ "authorization" ] \ No newline at end of file diff --git a/examples/kubernetes/metallb/configure.sh b/examples/kubernetes/metallb/configure.sh index f61b73d2c..f4ca67d98 100755 --- a/examples/kubernetes/metallb/configure.sh +++ b/examples/kubernetes/metallb/configure.sh @@ -1,6 +1,6 @@ #!/bin/bash -KIND_SUBNET=$(docker network inspect kind -f "{{(index .IPAM.Config 0).Subnet}}") +KIND_SUBNET=$(docker network inspect kind -f "{{(index .IPAM.Config 1).Subnet}}") METALLB_IP_START=$(echo ${KIND_SUBNET} | sed "s@0.0/16@255.200@") METALLB_IP_END=$(echo ${KIND_SUBNET} | sed "s@0.0/16@255.250@") METALLB_IP_RANGE="${METALLB_IP_START}-${METALLB_IP_END}" diff --git a/examples/kubernetes/nginx/global-helm-values.yaml b/examples/kubernetes/nginx/global-helm-values.yaml index b95ecfeac..ccd8f41ba 100644 --- a/examples/kubernetes/nginx/global-helm-values.yaml +++ b/examples/kubernetes/nginx/global-helm-values.yaml @@ -1,6 +1,6 @@ controller: config: - global-auth-url: https://heimdall.heimdall.svc.cluster.local:4456 + global-auth-url: https://heimdall.heimdall.svc.cluster.local:4455 global-auth-response-headers: "Authorization" global-auth-snippet: | proxy_set_header X-Forwarded-Method $request_method; diff --git a/examples/kubernetes/quickstarts/demo-app/overlays/haproxy/ingress.yaml b/examples/kubernetes/quickstarts/demo-app/overlays/haproxy/ingress.yaml index 16fd58d53..623f6e1c9 100644 --- a/examples/kubernetes/quickstarts/demo-app/overlays/haproxy/ingress.yaml +++ b/examples/kubernetes/quickstarts/demo-app/overlays/haproxy/ingress.yaml @@ -7,7 +7,7 @@ metadata: app.kubernetes.io/name: echo-app # Comment the following annotations if you configure external auth globally annotations: - haproxy-ingress.github.io/auth-url: "https://heimdall.heimdall.svc.cluster.local:4456" + haproxy-ingress.github.io/auth-url: "https://heimdall.heimdall.svc.cluster.local:4455" haproxy-ingress.github.io/auth-headers-succeed: "authorization" haproxy-ingress.github.io/headers: | X-Forwarded-Uri: %[pathq] diff --git a/examples/kubernetes/quickstarts/demo-app/overlays/nginx-route-based/ingress.yaml b/examples/kubernetes/quickstarts/demo-app/overlays/nginx-route-based/ingress.yaml index 3e5395980..018a6a69f 100644 --- a/examples/kubernetes/quickstarts/demo-app/overlays/nginx-route-based/ingress.yaml +++ b/examples/kubernetes/quickstarts/demo-app/overlays/nginx-route-based/ingress.yaml @@ -6,7 +6,7 @@ metadata: labels: app.kubernetes.io/name: echo-app annotations: - nginx.ingress.kubernetes.io/auth-url: "https://heimdall.heimdall.svc.cluster.local:4456" + nginx.ingress.kubernetes.io/auth-url: "https://heimdall.heimdall.svc.cluster.local:4455" nginx.ingress.kubernetes.io/auth-response-headers: "Authorization" nginx.ingress.kubernetes.io/auth-snippet: | proxy_set_header X-Forwarded-Method $request_method; diff --git a/examples/kubernetes/quickstarts/heimdall/backend-tls-policy.yaml b/examples/kubernetes/quickstarts/heimdall/backend-tls-policy.yaml index d7ed02ffb..80fe3b33f 100644 --- a/examples/kubernetes/quickstarts/heimdall/backend-tls-policy.yaml +++ b/examples/kubernetes/quickstarts/heimdall/backend-tls-policy.yaml @@ -9,7 +9,7 @@ spec: kind: Service namespace: heimdall name: heimdall - sectionName: "4456" + sectionName: "4455" tls: caCertRefs: - name: cacerts diff --git a/examples/kubernetes/quickstarts/heimdall/config.yaml b/examples/kubernetes/quickstarts/heimdall/config.yaml index 246228764..a16b31863 100644 --- a/examples/kubernetes/quickstarts/heimdall/config.yaml +++ b/examples/kubernetes/quickstarts/heimdall/config.yaml @@ -6,13 +6,12 @@ profiling: enabled: true serve: - decision: - tls: - min_version: TLS1.2 - key_store: - path: /etc/heimdall/certs/ssl/tls-combined.pem - trusted_proxies: - - 0.0.0.0/0 + tls: + min_version: TLS1.2 + key_store: + path: /etc/heimdall/certs/ssl/tls-combined.pem + trusted_proxies: + - 0.0.0.0/0 mechanisms: authenticators: diff --git a/examples/kubernetes/quickstarts/heimdall/contour-extension-service.yaml b/examples/kubernetes/quickstarts/heimdall/contour-extension-service.yaml index 3748bad6d..9ff86ea98 100644 --- a/examples/kubernetes/quickstarts/heimdall/contour-extension-service.yaml +++ b/examples/kubernetes/quickstarts/heimdall/contour-extension-service.yaml @@ -7,4 +7,4 @@ spec: protocol: h2 services: - name: heimdall - port: 4456 \ No newline at end of file + port: 4455 \ No newline at end of file diff --git a/examples/kubernetes/quickstarts/heimdall/emissary-auth-service.yaml b/examples/kubernetes/quickstarts/heimdall/emissary-auth-service.yaml index 9106e2b72..fc3449d46 100644 --- a/examples/kubernetes/quickstarts/heimdall/emissary-auth-service.yaml +++ b/examples/kubernetes/quickstarts/heimdall/emissary-auth-service.yaml @@ -4,6 +4,6 @@ metadata: name: heimdall namespace: heimdall spec: - auth_service: "https://heimdall.heimdall.svc.cluster.local:4456" + auth_service: "https://heimdall.heimdall.svc.cluster.local:4455" proto: grpc protocol_version: v3 diff --git a/examples/kubernetes/quickstarts/heimdall/envoygw-security-policy.yaml b/examples/kubernetes/quickstarts/heimdall/envoygw-security-policy.yaml index d229d61ea..1a4efbe96 100644 --- a/examples/kubernetes/quickstarts/heimdall/envoygw-security-policy.yaml +++ b/examples/kubernetes/quickstarts/heimdall/envoygw-security-policy.yaml @@ -13,7 +13,7 @@ spec: grpc: backendRef: name: heimdall - port: 4456 + port: 4455 namespace: heimdall --- diff --git a/examples/kubernetes/quickstarts/heimdall/heimdall-middleware.yaml b/examples/kubernetes/quickstarts/heimdall/heimdall-middleware.yaml index de7fa32bf..0e925881c 100644 --- a/examples/kubernetes/quickstarts/heimdall/heimdall-middleware.yaml +++ b/examples/kubernetes/quickstarts/heimdall/heimdall-middleware.yaml @@ -5,7 +5,7 @@ metadata: namespace: heimdall spec: forwardAuth: - address: "https://heimdall.heimdall.svc.cluster.local:4456" + address: "https://heimdall.heimdall.svc.cluster.local:4455" tls: caSecret: heimdall-tls authResponseHeaders: diff --git a/examples/kubernetes/quickstarts/heimdall/helm-values.yaml b/examples/kubernetes/quickstarts/heimdall/helm-values.yaml index af416ff7a..9a954d2c6 100644 --- a/examples/kubernetes/quickstarts/heimdall/helm-values.yaml +++ b/examples/kubernetes/quickstarts/heimdall/helm-values.yaml @@ -41,4 +41,5 @@ env: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "http://alloy.monitoring:4317" image: - tag: dev + tag: local + repository: heimdall diff --git a/internal/config/configuration.go b/internal/config/configuration.go index 875e76b27..e4dddc35b 100644 --- a/internal/config/configuration.go +++ b/internal/config/configuration.go @@ -26,6 +26,7 @@ import ( type Configuration struct { //nolint:musttag Serve ServeConfig `koanf:"serve"` + Management ManagementConfig `koanf:"management"` Log LoggingConfig `koanf:"log"` Tracing TracingConfig `koanf:"tracing"` Metrics MetricsConfig `koanf:"metrics"` diff --git a/internal/config/default_configuration.go b/internal/config/default_configuration.go index 6e6df0cfe..8a2ad1da6 100644 --- a/internal/config/default_configuration.go +++ b/internal/config/default_configuration.go @@ -31,8 +31,7 @@ const ( defaultMaxIdleConnections = 100 defaultMaxIdleConnectionsPerHost = 100 - defaultProxyServicePort = 4455 - defaultDecisionServicePort = 4456 + defaultServePort = 4455 defaultManagementServicePort = 4457 defaultProfilingServicePort = 10251 @@ -44,45 +43,31 @@ const ( func defaultConfig() Configuration { return Configuration{ Serve: ServeConfig{ - Proxy: ServiceConfig{ - Port: defaultProxyServicePort, - Timeout: Timeout{ - Read: defaultReadTimeout, - Write: defaultWriteTimeout, - Idle: defaultIdleTimeout, - }, - BufferLimit: BufferLimit{ - Read: defaultBufferSize, - Write: defaultBufferSize, - }, - ConnectionsLimit: ConnectionsLimit{ - MaxIdle: defaultMaxIdleConnections, - MaxIdlePerHost: defaultMaxIdleConnectionsPerHost, - }, + Port: defaultServePort, + Timeout: Timeout{ + Read: defaultReadTimeout, + Write: defaultWriteTimeout, + Idle: defaultIdleTimeout, }, - Decision: ServiceConfig{ - Port: defaultDecisionServicePort, - Timeout: Timeout{ - Read: defaultReadTimeout, - Write: defaultWriteTimeout, - Idle: defaultIdleTimeout, - }, - BufferLimit: BufferLimit{ - Read: defaultBufferSize, - Write: defaultBufferSize, - }, + BufferLimit: BufferLimit{ + Read: defaultBufferSize, + Write: defaultBufferSize, }, - Management: ServiceConfig{ - Port: defaultManagementServicePort, - Timeout: Timeout{ - Read: defaultReadTimeout, - Write: defaultWriteTimeout, - Idle: defaultIdleTimeout, - }, - BufferLimit: BufferLimit{ - Read: defaultBufferSize, - Write: defaultBufferSize, - }, + ConnectionsLimit: ConnectionsLimit{ + MaxIdle: defaultMaxIdleConnections, + MaxIdlePerHost: defaultMaxIdleConnectionsPerHost, + }, + }, + Management: ManagementConfig{ + Port: defaultManagementServicePort, + Timeout: Timeout{ + Read: defaultReadTimeout, + Write: defaultWriteTimeout, + Idle: defaultIdleTimeout, + }, + BufferLimit: BufferLimit{ + Read: defaultBufferSize, + Write: defaultBufferSize, }, }, Cache: CacheConfig{ diff --git a/internal/config/management.go b/internal/config/management.go new file mode 100644 index 000000000..411e4b305 --- /dev/null +++ b/internal/config/management.go @@ -0,0 +1,14 @@ +package config + +import "fmt" + +type ManagementConfig struct { + Host string `koanf:"host"` + Port int `koanf:"port"` + Timeout Timeout `koanf:"timeout"` + BufferLimit BufferLimit `koanf:"buffer_limit"` + CORS *CORS `koanf:"cors,omitempty"` + TLS *TLS `koanf:"tls,omitempty"` +} + +func (c ManagementConfig) Address() string { return fmt.Sprintf("%s:%d", c.Host, c.Port) } diff --git a/internal/config/serve.go b/internal/config/serve.go index 434fb150a..55c4a5414 100644 --- a/internal/config/serve.go +++ b/internal/config/serve.go @@ -23,6 +23,20 @@ import ( "github.com/inhies/go-bytesize" ) +type ServeConfig struct { + Host string `koanf:"host"` + Port int `koanf:"port"` + Timeout Timeout `koanf:"timeout"` + BufferLimit BufferLimit `koanf:"buffer_limit"` + ConnectionsLimit ConnectionsLimit `koanf:"connections_limit"` + CORS *CORS `koanf:"cors,omitempty"` + TLS *TLS `koanf:"tls,omitempty"` + TrustedProxies *[]string `koanf:"trusted_proxies,omitempty"` + Respond RespondConfig `koanf:"respond"` +} + +func (c ServeConfig) Address() string { return fmt.Sprintf("%s:%d", c.Host, c.Port) } + type BufferLimit struct { Read bytesize.ByteSize `koanf:"read" mapstructure:"read"` Write bytesize.ByteSize `koanf:"write" mapstructure:"write"` @@ -49,26 +63,6 @@ type CORS struct { MaxAge time.Duration `koanf:"max_age,string"` } -type ServiceConfig struct { - Host string `koanf:"host"` - Port int `koanf:"port"` - Timeout Timeout `koanf:"timeout"` - BufferLimit BufferLimit `koanf:"buffer_limit"` - ConnectionsLimit ConnectionsLimit `koanf:"connections_limit"` - CORS *CORS `koanf:"cors,omitempty"` - TLS *TLS `koanf:"tls,omitempty"` - TrustedProxies *[]string `koanf:"trusted_proxies,omitempty"` - Respond RespondConfig `koanf:"respond"` -} - -func (c ServiceConfig) Address() string { return fmt.Sprintf("%s:%d", c.Host, c.Port) } - -type ServeConfig struct { - Proxy ServiceConfig `koanf:"proxy"` - Decision ServiceConfig `koanf:"decision"` - Management ServiceConfig `koanf:"management"` -} - type ResponseOverride struct { Code int `koanf:"code"` } diff --git a/internal/config/test_data/test_config.yaml b/internal/config/test_data/test_config.yaml index 42c6a0596..f9a7880a5 100644 --- a/internal/config/test_data/test_config.yaml +++ b/internal/config/test_data/test_config.yaml @@ -1,113 +1,87 @@ serve: - decision: - host: 127.0.0.1 - port: 4468 - timeout: - read: 2s - write: 5s - idle: 2m - buffer_limit: - read: 4KB - write: 4KB - tls: - key_store: - path: /path/to/keystore/file.pem - password: VerySecret! - key_id: foo - min_version: TLS1.3 - trusted_proxies: - - 192.168.1.0/24 - respond: - verbose: true - with: - accepted: - code: 202 - precondition_error: - code: 400 - authentication_error: - code: 404 - authorization_error: - code: 404 - communication_error: - code: 502 - internal_error: - code: 500 - no_rule_error: - code: 404 - - proxy: - host: 127.0.0.1 - port: 4469 - timeout: - read: 2s - write: 5s - idle: 2m - buffer_limit: - read: 4KB - write: 4KB - connections_limit: - max_idle: 100 - max_idle_per_host: 100 - max_per_host: 20 - cors: - allowed_origins: - - example.org - allowed_methods: - - GET - - POST - allowed_headers: - - Authorization - exposed_headers: - - X-My-Header - allow_credentials: true - max_age: 1m - tls: - key_store: - path: /path/to/keystore/file.pem - min_version: TLS1.2 - cipher_suites: - - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 - trusted_proxies: - - 192.168.1.0/24 - respond: - with: - precondition_error: - code: 400 - authentication_error: - code: 404 + host: 127.0.0.1 + port: 4469 + timeout: + read: 2s + write: 5s + idle: 2m + buffer_limit: + read: 4KB + write: 4KB + connections_limit: + max_idle: 100 + max_idle_per_host: 100 + max_per_host: 20 + cors: + allowed_origins: + - example.org + allowed_methods: + - GET + - POST + allowed_headers: + - Authorization + exposed_headers: + - X-My-Header + allow_credentials: true + max_age: 1m + tls: + key_store: + path: /path/to/keystore/file.pem + min_version: TLS1.2 + cipher_suites: + - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + trusted_proxies: + - 192.168.1.0/24 + respond: + verbose: true + with: + accepted: + code: 202 + precondition_error: + code: 400 + authentication_error: + code: 404 + authorization_error: + code: 404 + communication_error: + code: 502 + internal_error: + code: 500 + no_rule_error: + code: 404 - management: - host: 127.0.0.1 - port: 4457 - timeout: - read: 2s - write: 5s - idle: 2m - buffer_limit: - read: 4KB - write: 4KB - cors: - allowed_origins: - - example.org - allowed_methods: - - GET - - POST - allowed_headers: - - Authorization - exposed_headers: - - X-My-Header - allow_credentials: true - max_age: 1m - tls: - key_store: - path: /path/to/keystore/file.pem +management: + host: 127.0.0.1 + port: 4457 + timeout: + read: 2s + write: 5s + idle: 2m + buffer_limit: + read: 4KB + write: 4KB + cors: + allowed_origins: + - example.org + allowed_methods: + - GET + - POST + allowed_headers: + - Authorization + exposed_headers: + - X-My-Header + allow_credentials: true + max_age: 1m + tls: + key_store: + path: /path/to/keystore/file.pem cache: type: redis diff --git a/internal/handler/decision/module.go b/internal/handler/decision/module.go index 0516379e9..42d60d0e6 100644 --- a/internal/handler/decision/module.go +++ b/internal/handler/decision/module.go @@ -44,7 +44,7 @@ func newLifecycleManager( exec rule.Executor, cw watcher.Watcher, ) *fxlcm.LifecycleManager { - cfg := conf.Serve.Decision + cfg := conf.Serve return &fxlcm.LifecycleManager{ ServiceName: "Decision", diff --git a/internal/handler/decision/service.go b/internal/handler/decision/service.go index de1bd1db7..3cc8b2cd5 100644 --- a/internal/handler/decision/service.go +++ b/internal/handler/decision/service.go @@ -49,7 +49,7 @@ func newService( log zerolog.Logger, exec rule.Executor, ) *http.Server { - cfg := conf.Serve.Decision + cfg := conf.Serve eh := errorhandler.New( errorhandler.WithVerboseErrors(cfg.Respond.Verbose), errorhandler.WithPreconditionErrorCode(cfg.Respond.With.ArgumentError.Code), diff --git a/internal/handler/decision/service_test.go b/internal/handler/decision/service_test.go index 0f3bf5c38..e0e251a39 100644 --- a/internal/handler/decision/service_test.go +++ b/internal/handler/decision/service_test.go @@ -42,7 +42,7 @@ func TestHandleDecisionEndpointRequest(t *testing.T) { for _, tc := range []struct { uc string - serviceConf config.ServiceConfig + serviceConf config.ServeConfig createRequest func(t *testing.T, host string) *http.Request configureMocks func(t *testing.T, exec *mocks4.ExecutorMock) assertResponse func(t *testing.T, err error, response *http.Response) @@ -289,7 +289,7 @@ func TestHandleDecisionEndpointRequest(t *testing.T) { { uc: "successful rule execution - request method, path and hostname " + "all are not taken from the headers (trusted proxy configured and does not match host)", - serviceConf: config.ServiceConfig{TrustedProxies: &[]string{"111.111.111.111"}}, + serviceConf: config.ServeConfig{TrustedProxies: &[]string{"111.111.111.111"}}, createRequest: func(t *testing.T, host string) *http.Request { t.Helper() @@ -347,7 +347,7 @@ func TestHandleDecisionEndpointRequest(t *testing.T) { { uc: "successful rule execution - only request method is sent via header" + "(trusted proxy configured and matches host)", - serviceConf: config.ServiceConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, + serviceConf: config.ServeConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, createRequest: func(t *testing.T, host string) *http.Request { t.Helper() @@ -386,7 +386,7 @@ func TestHandleDecisionEndpointRequest(t *testing.T) { { uc: "successful rule execution - only host is sent via header" + "(trusted proxy configured and matches host)", - serviceConf: config.ServiceConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, + serviceConf: config.ServeConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, createRequest: func(t *testing.T, host string) *http.Request { t.Helper() @@ -426,7 +426,7 @@ func TestHandleDecisionEndpointRequest(t *testing.T) { { uc: "successful rule execution - only path is sent via header" + "(trusted proxy configured and matches host)", - serviceConf: config.ServiceConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, + serviceConf: config.ServeConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, createRequest: func(t *testing.T, host string) *http.Request { t.Helper() @@ -465,7 +465,7 @@ func TestHandleDecisionEndpointRequest(t *testing.T) { { uc: "successful rule execution - only scheme is sent via header" + "(trusted proxy configured and matches host)", - serviceConf: config.ServiceConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, + serviceConf: config.ServeConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, createRequest: func(t *testing.T, host string) *http.Request { t.Helper() @@ -504,7 +504,7 @@ func TestHandleDecisionEndpointRequest(t *testing.T) { { uc: "successful rule execution - scheme, host, path and method sent via header" + "(trusted proxy configured and matches host)", - serviceConf: config.ServiceConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, + serviceConf: config.ServeConfig{TrustedProxies: &[]string{"0.0.0.0/0"}}, createRequest: func(t *testing.T, host string) *http.Request { t.Helper() @@ -557,7 +557,7 @@ func TestHandleDecisionEndpointRequest(t *testing.T) { listener, err := listener.New("tcp", "test", srvConf.Address(), srvConf.TLS, nil, nil) require.NoError(t, err) - conf := &config.Configuration{Serve: config.ServeConfig{Decision: srvConf}} + conf := &config.Configuration{Serve: srvConf} cch := mocks.NewCacheMock(t) exec := mocks4.NewExecutorMock(t) diff --git a/internal/handler/envoyextauth/grpcv3/module.go b/internal/handler/envoyextauth/grpcv3/module.go index 83216d60d..ff4184602 100644 --- a/internal/handler/envoyextauth/grpcv3/module.go +++ b/internal/handler/envoyextauth/grpcv3/module.go @@ -44,7 +44,7 @@ func newLifecycleManager( cch cache.Cache, cw watcher.Watcher, ) *fxlcm.LifecycleManager { - cfg := conf.Serve.Decision + cfg := conf.Serve return &fxlcm.LifecycleManager{ ServiceName: "Decision Envoy ExtAuth", diff --git a/internal/handler/envoyextauth/grpcv3/service.go b/internal/handler/envoyextauth/grpcv3/service.go index 7128aa209..583ff6561 100644 --- a/internal/handler/envoyextauth/grpcv3/service.go +++ b/internal/handler/envoyextauth/grpcv3/service.go @@ -43,7 +43,7 @@ func newService( logger zerolog.Logger, exec rule.Executor, ) *grpc.Server { - cfg := conf.Serve.Decision + cfg := conf.Serve accessLogger := accesslogmiddleware.New(logger) recoveryHandler := recovery.WithRecoveryHandler(func(any) error { return status.Error(codes.Internal, "internal error") diff --git a/internal/handler/listener/listener_test.go b/internal/handler/listener/listener_test.go index 2f6e3da35..e868ea104 100644 --- a/internal/handler/listener/listener_test.go +++ b/internal/handler/listener/listener_test.go @@ -96,13 +96,13 @@ func TestNewListener(t *testing.T) { for _, tc := range []struct { uc string network string - serviceConf config.ServiceConfig + serviceConf config.ServeConfig assert func(t *testing.T, err error, ln net.Listener, port string) }{ { uc: "creation fails", network: "foo", - serviceConf: config.ServiceConfig{}, + serviceConf: config.ServeConfig{}, assert: func(t *testing.T, err error, _ net.Listener, _ string) { t.Helper() @@ -113,7 +113,7 @@ func TestNewListener(t *testing.T) { { uc: "without TLS", network: "tcp", - serviceConf: config.ServiceConfig{Host: "127.0.0.1"}, + serviceConf: config.ServeConfig{Host: "127.0.0.1"}, assert: func(t *testing.T, err error, ln net.Listener, port string) { t.Helper() @@ -127,7 +127,7 @@ func TestNewListener(t *testing.T) { { uc: "fails due to not existent key store for TLS usage", network: "tcp", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ TLS: &config.TLS{KeyStore: config.KeyStore{Path: "/no/such/file"}}, }, assert: func(t *testing.T, err error, _ net.Listener, _ string) { @@ -141,7 +141,7 @@ func TestNewListener(t *testing.T) { { uc: "fails due to not specified key store", network: "tcp", - serviceConf: config.ServiceConfig{TLS: &config.TLS{}}, + serviceConf: config.ServeConfig{TLS: &config.TLS{}}, assert: func(t *testing.T, err error, _ net.Listener, _ string) { t.Helper() @@ -153,7 +153,7 @@ func TestNewListener(t *testing.T) { { uc: "successful with specified key id", network: "tcp", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ TLS: &config.TLS{ KeyStore: config.KeyStore{Path: pemFile.Name()}, KeyID: "key1", diff --git a/internal/handler/management/module.go b/internal/handler/management/module.go index 428dd6e6f..ead7efda1 100644 --- a/internal/handler/management/module.go +++ b/internal/handler/management/module.go @@ -42,7 +42,7 @@ func newLifecycleManager( khr keyholder.Registry, cw watcher.Watcher, ) *fxlcm.LifecycleManager { - cfg := conf.Serve.Management + cfg := conf.Management return &fxlcm.LifecycleManager{ ServiceName: "Management", diff --git a/internal/handler/management/service.go b/internal/handler/management/service.go index a339f39be..a2a2f3eb1 100644 --- a/internal/handler/management/service.go +++ b/internal/handler/management/service.go @@ -46,7 +46,7 @@ func newService( log zerolog.Logger, khr keyholder.Registry, ) *http.Server { - cfg := conf.Serve.Management + cfg := conf.Management eh := errorhandler2.New() opFilter := func(req *http.Request) bool { return req.URL.Path != EndpointHealth } diff --git a/internal/handler/management/service_test.go b/internal/handler/management/service_test.go index 889ee77c1..308c145d0 100644 --- a/internal/handler/management/service_test.go +++ b/internal/handler/management/service_test.go @@ -113,17 +113,15 @@ func (suite *ServiceTestSuite) SetupTest() { suite.Require().NoError(err) conf := &config.Configuration{ - Serve: config.ServeConfig{ - Management: config.ServiceConfig{ - Host: "127.0.0.1", - Port: port, - CORS: &config.CORS{}, - }, + Management: config.ManagementConfig{ + Host: "127.0.0.1", + Port: port, + CORS: &config.CORS{}, }, Metrics: config.MetricsConfig{Enabled: true}, } - listener, err := listener.New("tcp", "test", conf.Serve.Management.Address(), conf.Serve.Management.TLS, nil, nil) + listener, err := listener.New("tcp", "test", conf.Management.Address(), conf.Management.TLS, nil, nil) suite.Require().NoError(err) suite.addr = "http://" + listener.Addr().String() diff --git a/internal/handler/proxy/module.go b/internal/handler/proxy/module.go index 8c218b563..a212c1e6b 100644 --- a/internal/handler/proxy/module.go +++ b/internal/handler/proxy/module.go @@ -44,7 +44,7 @@ func newLifecycleManager( executor rule.Executor, cw watcher.Watcher, ) *fxlcm.LifecycleManager { - cfg := conf.Serve.Proxy + cfg := conf.Serve return &fxlcm.LifecycleManager{ ServiceName: "Proxy", diff --git a/internal/handler/proxy/request_context.go b/internal/handler/proxy/request_context.go index f4b8331e1..39c4668f3 100644 --- a/internal/handler/proxy/request_context.go +++ b/internal/handler/proxy/request_context.go @@ -46,7 +46,7 @@ type requestContext struct { } func newContextFactory( - cfg config.ServiceConfig, + cfg config.ServeConfig, tlsCfg *tls.Config, ) requestcontext.ContextFactory { transport := &http.Transport{ diff --git a/internal/handler/proxy/request_context_test.go b/internal/handler/proxy/request_context_test.go index 0985f81dd..e2ae33b39 100644 --- a/internal/handler/proxy/request_context_test.go +++ b/internal/handler/proxy/request_context_test.go @@ -309,7 +309,7 @@ func TestRequestContextFinalize(t *testing.T) { Write: 100 * time.Millisecond, Idle: 1 * time.Second, } - ctx := newContextFactory(config.ServiceConfig{Timeout: timeouts}, nil).Create(rw, req) + ctx := newContextFactory(config.ServeConfig{Timeout: timeouts}, nil).Create(rw, req) backend := tc.setup(t, ctx, targetURL) diff --git a/internal/handler/proxy/service.go b/internal/handler/proxy/service.go index bc4cd65d0..fc547ba69 100644 --- a/internal/handler/proxy/service.go +++ b/internal/handler/proxy/service.go @@ -88,7 +88,7 @@ func newService( exec rule.Executor, ) *http.Server { der := &deadlineResetter{} - cfg := conf.Serve.Proxy + cfg := conf.Serve eh := errorhandler.New( errorhandler.WithVerboseErrors(cfg.Respond.Verbose), errorhandler.WithPreconditionErrorCode(cfg.Respond.With.ArgumentError.Code), diff --git a/internal/handler/proxy/service_test.go b/internal/handler/proxy/service_test.go index 7b0904f14..01e9073e2 100644 --- a/internal/handler/proxy/service_test.go +++ b/internal/handler/proxy/service_test.go @@ -99,7 +99,7 @@ func TestProxyService(t *testing.T) { for _, tc := range []struct { uc string - serviceConf config.ServiceConfig + serviceConf config.ServeConfig enableMetrics bool disableHTTP2 bool createRequest func(t *testing.T, host string) *http.Request @@ -276,7 +276,7 @@ func TestProxyService(t *testing.T) { { uc: "successful rule execution - request method and path are taken from the real request " + "(trusted proxy not configured)", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ Timeout: config.Timeout{Read: 1 * time.Second, Write: 1 * time.Second, Idle: 1 * time.Second}, }, createRequest: func(t *testing.T, host string) *http.Request { @@ -359,7 +359,7 @@ func TestProxyService(t *testing.T) { { uc: "successful rule execution - request method is taken from the header " + "(trusted proxy configured)", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ Timeout: config.Timeout{Read: 1 * time.Second, Write: 1 * time.Second, Idle: 1 * time.Second}, TrustedProxies: &[]string{"0.0.0.0/0"}, }, @@ -441,7 +441,7 @@ func TestProxyService(t *testing.T) { { uc: "successful rule execution - request path is taken from the header " + "(trusted proxy configured)", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ Timeout: config.Timeout{Read: 1 * time.Second, Write: 1 * time.Second, Idle: 1 * time.Second}, TrustedProxies: &[]string{"0.0.0.0/0"}, }, @@ -522,7 +522,7 @@ func TestProxyService(t *testing.T) { }, { uc: "CORS test actual request", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ Timeout: config.Timeout{Read: 1 * time.Second, Write: 1 * time.Second, Idle: 1 * time.Second}, CORS: &config.CORS{ AllowedMethods: []string{http.MethodGet}, @@ -607,7 +607,7 @@ func TestProxyService(t *testing.T) { }, { uc: "CORS test preflight request", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ Timeout: config.Timeout{Read: 10 * time.Second}, CORS: &config.CORS{ AllowedMethods: []string{http.MethodGet}, @@ -649,7 +649,7 @@ func TestProxyService(t *testing.T) { }, { uc: "test metrics collection", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ Timeout: config.Timeout{Read: 10 * time.Second}, CORS: &config.CORS{ AllowedMethods: []string{http.MethodGet}, @@ -688,7 +688,7 @@ func TestProxyService(t *testing.T) { }, { uc: "http2 usage", - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ Timeout: config.Timeout{Read: 1000 * time.Second, Write: 1000 * time.Second, Idle: 1000 * time.Second}, TLS: &config.TLS{ KeyStore: config.KeyStore{ @@ -783,7 +783,7 @@ func TestProxyService(t *testing.T) { { uc: "http2 not supported by upstream server", disableHTTP2: true, - serviceConf: config.ServiceConfig{ + serviceConf: config.ServeConfig{ Timeout: config.Timeout{Read: 1 * time.Second, Write: 1 * time.Second, Idle: 1 * time.Second}, TLS: &config.TLS{ KeyStore: config.KeyStore{ @@ -932,7 +932,7 @@ func TestProxyService(t *testing.T) { require.NoError(t, err) conf := &config.Configuration{ - Serve: config.ServeConfig{Proxy: proxyConf}, + Serve: proxyConf, Metrics: config.MetricsConfig{Enabled: tc.enableMetrics}, } cch := mocks.NewCacheMock(t) @@ -1034,15 +1034,13 @@ func TestWebSocketSupport(t *testing.T) { conf := &config.Configuration{ Serve: config.ServeConfig{ - Proxy: config.ServiceConfig{ - Timeout: config.Timeout{ - Read: 1 * time.Second, - Write: 1 * time.Second, - Idle: 1 * time.Second, - }, - Host: "127.0.0.1", - Port: port, + Timeout: config.Timeout{ + Read: 1 * time.Second, + Write: 1 * time.Second, + Idle: 1 * time.Second, }, + Host: "127.0.0.1", + Port: port, }, } @@ -1050,7 +1048,7 @@ func TestWebSocketSupport(t *testing.T) { defer proxy.Shutdown(context.Background()) - listener, err := listener.New("tcp", "test", conf.Serve.Proxy.Address(), conf.Serve.Proxy.TLS, nil, nil) + listener, err := listener.New("tcp", "test", conf.Serve.Address(), conf.Serve.TLS, nil, nil) require.NoError(t, err) go func() { @@ -1059,7 +1057,7 @@ func TestWebSocketSupport(t *testing.T) { time.Sleep(50 * time.Millisecond) - wsURL := url.URL{Scheme: "ws", Host: conf.Serve.Proxy.Address(), Path: "/foo"} + wsURL := url.URL{Scheme: "ws", Host: conf.Serve.Address(), Path: "/foo"} con, resp, err := websocket.DefaultDialer.Dial(wsURL.String(), nil) require.NoError(t, err) @@ -1134,15 +1132,13 @@ func TestServerSentEventsSupport(t *testing.T) { conf := &config.Configuration{ Serve: config.ServeConfig{ - Proxy: config.ServiceConfig{ - Timeout: config.Timeout{ - Read: 40 * time.Millisecond, - Write: 50 * time.Millisecond, - Idle: 1 * time.Second, - }, - Host: "127.0.0.1", - Port: port, + Timeout: config.Timeout{ + Read: 40 * time.Millisecond, + Write: 50 * time.Millisecond, + Idle: 1 * time.Second, }, + Host: "127.0.0.1", + Port: port, }, } @@ -1150,7 +1146,7 @@ func TestServerSentEventsSupport(t *testing.T) { defer proxy.Shutdown(context.Background()) - listener, err := listener.New("tcp", "test", conf.Serve.Proxy.Address(), conf.Serve.Proxy.TLS, nil, nil) + listener, err := listener.New("tcp", "test", conf.Serve.Address(), conf.Serve.TLS, nil, nil) require.NoError(t, err) go func() { @@ -1159,7 +1155,7 @@ func TestServerSentEventsSupport(t *testing.T) { time.Sleep(50 * time.Millisecond) - req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, fmt.Sprintf("http://%s/foo", conf.Serve.Proxy.Address()), nil) + req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, fmt.Sprintf("http://%s/foo", conf.Serve.Address()), nil) require.NoError(t, err) req.Header.Set("Cache-Control", "no-cache") req.Header.Set("Accept", "text/event-stream") diff --git a/release-please-config.json b/release-please-config.json index c650ac5fd..999a959e8 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -12,6 +12,5 @@ ], "packages": { ".": {} - }, - "release-as": "0.16.0" + } } \ No newline at end of file diff --git a/schema/config.schema.json b/schema/config.schema.json index 45fea00f5..8424abb9e 100644 --- a/schema/config.schema.json +++ b/schema/config.schema.json @@ -1655,7 +1655,9 @@ "description": "Configures signer options for issued JWTs.", "type": "object", "additionalProperties": false, - "required": [ "key_store" ], + "required": [ + "key_store" + ], "properties": { "name": { "description": "The name of the signer (string or URL). Used for the 'iss' claim in the issued JWTs", @@ -2158,132 +2160,79 @@ "pattern": "^v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" }, "serve": { - "description": "HTTP(s) configuration of exposed services", + "description": "HTTP(s) configuration of the main service", "additionalProperties": false, "type": "object", "properties": { - "decision": { - "description": "Decision service Configuration", - "type": "object", - "additionalProperties": false, - "properties": { - "port": { - "description": "The port to listen on.", - "type": "integer" - }, - "host": { - "description": "The network interface to listen on.", - "type": "string", - "default": "", - "examples": [ - "localhost", - "127.0.0.1" - ] - }, - "timeout": { - "$ref": "#/definitions/timeoutConfig" - }, - "buffer_limit": { - "$ref": "#/definitions/bufferLimitConfig" - }, - "tls": { - "$ref": "#/definitions/tlsConfig" - }, - "trusted_proxies": { - "description": "The list IPs or CIDRs heimdall should trust and thus make use of headers, like X-Forwarded-*, Forwarded, etc", - "type": "array", - "items": { - "type": "string" - } - }, - "respond": { - "$ref": "#/definitions/respondWithConfig" - } - } + "port": { + "description": "The port to listen on.", + "type": "integer" }, - "proxy": { - "description": "Proxy service configuration", - "type": "object", - "additionalProperties": false, - "properties": { - "port": { - "description": "The port to listen on.", - "type": "integer" - }, - "host": { - "description": "The network interface to listen on.", - "type": "string", - "default": "", - "examples": [ - "localhost", - "127.0.0.1" - ] - }, - "timeout": { - "$ref": "#/definitions/timeoutConfig" - }, - "buffer_limit": { - "$ref": "#/definitions/bufferLimitConfig" - }, - "connections_limit": { - "$ref": "#/definitions/connectionsLimitConfig" - }, - "cors": { - "$ref": "#/definitions/corsConfig" - }, - "tls": { - "$ref": "#/definitions/tlsConfig" - }, - "trusted_proxies": { - "description": "The list IPs or CIDRs heimdall should trust and thus make use of headers, like X-Forwarded-*, Forwarded, etc", - "type": "array", - "items": { - "type": "string" - } - }, - "respond": { - "$ref": "#/definitions/respondWithConfig" - } - } + "host": { + "description": "The network interface to listen on.", + "type": "string", + "default": "", + "examples": [ + "localhost", + "127.0.0.1" + ] }, - "management": { - "description": "Management service configuration", - "type": "object", - "additionalProperties": false, - "properties": { - "port": { - "description": "The port to listen on.", - "type": "integer" - }, - "host": { - "description": "The network interface to listen on.", - "type": "string", - "default": "", - "examples": [ - "localhost", - "127.0.0.1" - ] - }, - "timeout": { - "$ref": "#/definitions/timeoutConfig" - }, - "buffer_limit": { - "$ref": "#/definitions/bufferLimitConfig" - }, - "cors": { - "$ref": "#/definitions/corsConfig" - }, - "tls": { - "$ref": "#/definitions/tlsConfig" - }, - "trusted_proxies": { - "description": "The list IPs or CIDRs heimdall should trust and thus make use of headers, like X-Forwarded-*, Forwarded, etc", - "type": "array", - "items": { - "type": "string" - } - } + "timeout": { + "$ref": "#/definitions/timeoutConfig" + }, + "buffer_limit": { + "$ref": "#/definitions/bufferLimitConfig" + }, + "connections_limit": { + "$ref": "#/definitions/connectionsLimitConfig" + }, + "cors": { + "$ref": "#/definitions/corsConfig" + }, + "tls": { + "$ref": "#/definitions/tlsConfig" + }, + "trusted_proxies": { + "description": "The list IPs or CIDRs heimdall should trust and thus make use of headers, like X-Forwarded-*, Forwarded, etc", + "type": "array", + "items": { + "type": "string" } + }, + "respond": { + "$ref": "#/definitions/respondWithConfig" + } + } + }, + "management": { + "description": "Management service configuration", + "type": "object", + "additionalProperties": false, + "properties": { + "port": { + "description": "The port to listen on.", + "type": "integer" + }, + "host": { + "description": "The network interface to listen on.", + "type": "string", + "default": "", + "examples": [ + "localhost", + "127.0.0.1" + ] + }, + "timeout": { + "$ref": "#/definitions/timeoutConfig" + }, + "buffer_limit": { + "$ref": "#/definitions/bufferLimitConfig" + }, + "cors": { + "$ref": "#/definitions/corsConfig" + }, + "tls": { + "$ref": "#/definitions/tlsConfig" } } },