Skip to content

Commit

Permalink
Facilitate logout via OAuth proxy and fix line endings (#61)
Browse files Browse the repository at this point in the history
* OAuth proxy allows redirect to keycloak for logout

Add the keycloak host to the whitelist_domains of sessions' OAuth proxy configuration.
This enables a logout from the OAuth proxy that automatically redirects to the Keycloak logout URL.

* Unify template line endings to LF

Some template files in the theia.cloud chart used CRLF line endings for some reason. This changes them to LF.
  • Loading branch information
lucas-koehler authored Oct 14, 2024
1 parent 63a265f commit ad4d8d5
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 198 deletions.
2 changes: 1 addition & 1 deletion charts/theia-cloud/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.12.0-next.3
version: 0.12.0-next.4

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
Expand Down
152 changes: 76 additions & 76 deletions charts/theia-cloud/templates/instances-ingress-path-based.yaml
Original file line number Diff line number Diff line change
@@ -1,76 +1,76 @@
{{- if .Values.hosts.usePaths }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ tpl (.Values.ingress.instanceName | toString) . }}
namespace: {{ .Release.Namespace }}
annotations:
{{- if not .Values.ingress.tls }}
nginx.ingress.kubernetes.io/ssl-redirect: "false"
{{- end }}
nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header 'X-Forwarded-Uri' $request_uri;
nginx.ingress.kubernetes.io/proxy-body-size: {{ tpl (.Values.ingress.proxyBodySize | toString) . }}
{{- if .Values.ingress.addTLSSecretName }}
{{- if .Values.ingress.certManagerAnnotations }}
cert-manager.io/cluster-issuer: {{ tpl (.Values.ingress.clusterIssuer | toString) . }}
{{- if .Values.ingress.theiaCloudCommonName }}
cert-manager.io/common-name: "Theia Cloud"
{{- end }}
acme.cert-manager.io/http01-ingress-class: nginx
{{- end }}
{{- end }}
spec:
ingressClassName: nginx
{{- if .Values.ingress.tls }}
tls:
- hosts:
- {{ tpl (.Values.hosts.configuration.baseHost | toString) . }}
{{- if .Values.ingress.addTLSSecretName }}
{{- range $wildcard := .Values.hosts.allWildcardInstances }}
{{- if (not (hasKey $.Values.ingress.allWildcardSecretNames $wildcard)) }}
- {{ printf "%s%s" (tpl . $) (tpl $.Values.hosts.configuration.baseHost $)| quote }}
{{- end }}
{{- end }}
secretName: ws-cert-secret
{{- end }}
{{- end }}

{{- range $wildcard := .Values.hosts.allWildcardInstances }}
{{- if hasKey $.Values.ingress.allWildcardSecretNames $wildcard }}
{{- $secretName := get $.Values.ingress.allWildcardSecretNames $wildcard }}
- hosts:
- {{ printf "%s%s" (tpl $wildcard $) (tpl $.Values.hosts.configuration.baseHost $) | quote }}
secretName: {{ tpl $secretName $ | quote }}
{{- end }}
{{- end }}
{{- if not (lookup "networking.k8s.io/v1" "Ingress" .Release.Namespace (tpl (.Values.ingress.instanceName | toString) .) ) }}
rules:
- host: {{ tpl (.Values.hosts.configuration.baseHost | toString) . }}
http:
{{- range .Values.hosts.allWildcardInstances }}
- host: {{ printf "'%s%s'" (tpl . $) (tpl $.Values.hosts.configuration.baseHost $) }}
http:
{{- end }}
{{- else }}
rules:
{{ range $rule := (lookup "networking.k8s.io/v1" "Ingress" .Release.Namespace (tpl (.Values.ingress.instanceName | toString) .)).spec.rules }}
- host: {{ .host | quote }}
{{ if .http }}
http:
paths:
{{ with index .http.paths 0 }}
- path: {{ .path }}
pathType: Prefix
backend:
service:
name: {{ .backend.service.name }}
port:
number: {{ .backend.service.port.number }}
{{- end }}
{{ end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.hosts.usePaths }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ tpl (.Values.ingress.instanceName | toString) . }}
namespace: {{ .Release.Namespace }}
annotations:
{{- if not .Values.ingress.tls }}
nginx.ingress.kubernetes.io/ssl-redirect: "false"
{{- end }}
nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header 'X-Forwarded-Uri' $request_uri;
nginx.ingress.kubernetes.io/proxy-body-size: {{ tpl (.Values.ingress.proxyBodySize | toString) . }}
{{- if .Values.ingress.addTLSSecretName }}
{{- if .Values.ingress.certManagerAnnotations }}
cert-manager.io/cluster-issuer: {{ tpl (.Values.ingress.clusterIssuer | toString) . }}
{{- if .Values.ingress.theiaCloudCommonName }}
cert-manager.io/common-name: "Theia Cloud"
{{- end }}
acme.cert-manager.io/http01-ingress-class: nginx
{{- end }}
{{- end }}
spec:
ingressClassName: nginx
{{- if .Values.ingress.tls }}
tls:
- hosts:
- {{ tpl (.Values.hosts.configuration.baseHost | toString) . }}
{{- if .Values.ingress.addTLSSecretName }}
{{- range $wildcard := .Values.hosts.allWildcardInstances }}
{{- if (not (hasKey $.Values.ingress.allWildcardSecretNames $wildcard)) }}
- {{ printf "%s%s" (tpl . $) (tpl $.Values.hosts.configuration.baseHost $)| quote }}
{{- end }}
{{- end }}
secretName: ws-cert-secret
{{- end }}
{{- end }}

{{- range $wildcard := .Values.hosts.allWildcardInstances }}
{{- if hasKey $.Values.ingress.allWildcardSecretNames $wildcard }}
{{- $secretName := get $.Values.ingress.allWildcardSecretNames $wildcard }}
- hosts:
- {{ printf "%s%s" (tpl $wildcard $) (tpl $.Values.hosts.configuration.baseHost $) | quote }}
secretName: {{ tpl $secretName $ | quote }}
{{- end }}
{{- end }}
{{- if not (lookup "networking.k8s.io/v1" "Ingress" .Release.Namespace (tpl (.Values.ingress.instanceName | toString) .) ) }}
rules:
- host: {{ tpl (.Values.hosts.configuration.baseHost | toString) . }}
http:
{{- range .Values.hosts.allWildcardInstances }}
- host: {{ printf "'%s%s'" (tpl . $) (tpl $.Values.hosts.configuration.baseHost $) }}
http:
{{- end }}
{{- else }}
rules:
{{ range $rule := (lookup "networking.k8s.io/v1" "Ingress" .Release.Namespace (tpl (.Values.ingress.instanceName | toString) .)).spec.rules }}
- host: {{ .host | quote }}
{{ if .http }}
http:
paths:
{{ with index .http.paths 0 }}
- path: {{ .path }}
pathType: Prefix
backend:
service:
name: {{ .backend.service.name }}
port:
number: {{ .backend.service.port.number }}
{{- end }}
{{ end }}
{{- end }}
{{- end }}
{{- end }}
154 changes: 77 additions & 77 deletions charts/theia-cloud/templates/instances-ingress.yaml
Original file line number Diff line number Diff line change
@@ -1,77 +1,77 @@
{{- if not .Values.hosts.usePaths }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ tpl (.Values.ingress.instanceName | toString) . }}
namespace: {{ .Release.Namespace }}
annotations:
{{- if not .Values.ingress.tls }}
nginx.ingress.kubernetes.io/ssl-redirect: "false"
{{- end }}
{{- if .Values.ingress.addTLSSecretName }}
{{- if .Values.ingress.certManagerAnnotations }}
cert-manager.io/cluster-issuer: {{ tpl (.Values.ingress.clusterIssuer | toString) . }}
{{- if .Values.ingress.theiaCloudCommonName }}
cert-manager.io/common-name: "Theia Cloud"
{{- end }}
acme.cert-manager.io/http01-ingress-class: nginx
{{- end }}
{{- end }}
nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header 'X-Forwarded-Uri' $request_uri;
nginx.ingress.kubernetes.io/proxy-body-size: {{ tpl (.Values.ingress.proxyBodySize | toString) . }}
spec:
ingressClassName: nginx
{{- if .Values.ingress.tls }}
tls:
- hosts:
- {{ tpl (printf "%s.%s" .Values.hosts.configuration.instance .Values.hosts.configuration.baseHost | toString) . }}
{{- if .Values.ingress.addTLSSecretName }}
{{- range $wildcard := .Values.hosts.allWildcardInstances }}
{{- if (not (hasKey $.Values.ingress.allWildcardSecretNames $wildcard)) }}
- {{ printf "%s%s.%s" (tpl . $) (tpl $.Values.hosts.configuration.instance $) (tpl $.Values.hosts.configuration.baseHost $) | quote }}
{{- end }}
{{- end }}
secretName: ws-cert-secret
{{- end }}
{{- end }}

{{- range $wildcard := .Values.hosts.allWildcardInstances }}
{{- if hasKey $.Values.ingress.allWildcardSecretNames $wildcard }}
{{- $secretName := get $.Values.ingress.allWildcardSecretNames $wildcard }}
- hosts:
- {{ printf "%s%s.%s" (tpl $wildcard $) (tpl $.Values.hosts.configuration.instance $) (tpl $.Values.hosts.configuration.baseHost $) | quote }}
secretName: {{ tpl $secretName $ | quote }}
{{- end }}
{{- end }}

{{- if not (lookup "networking.k8s.io/v1" "Ingress" .Release.Namespace (tpl (.Values.ingress.instanceName | toString) .) ) }}
rules:
- host: {{ printf "%s.%s" (tpl .Values.hosts.configuration.instance .) (tpl .Values.hosts.configuration.baseHost .) }}
http:
{{- range .Values.hosts.allWildcardInstances }}
- host: {{ printf "%s%s.%s" (tpl . $) (tpl $.Values.hosts.configuration.instance $) (tpl $.Values.hosts.configuration.baseHost $) | quote }}
http:
{{- end }}
{{- else }}
rules:
{{ range $rule := (lookup "networking.k8s.io/v1" "Ingress" .Release.Namespace (tpl (.Values.ingress.instanceName | toString) .)).spec.rules }}
- host: {{ .host | quote }}
{{ if .http }}
http:
paths:
{{ with index .http.paths 0 }}
- path: {{ .path }}
pathType: Prefix
backend:
service:
name: {{ .backend.service.name }}
port:
number: {{ .backend.service.port.number }}
{{- end }}
{{ end }}
{{- end }}
{{- end }}
{{- end }}
{{- if not .Values.hosts.usePaths }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ tpl (.Values.ingress.instanceName | toString) . }}
namespace: {{ .Release.Namespace }}
annotations:
{{- if not .Values.ingress.tls }}
nginx.ingress.kubernetes.io/ssl-redirect: "false"
{{- end }}
{{- if .Values.ingress.addTLSSecretName }}
{{- if .Values.ingress.certManagerAnnotations }}
cert-manager.io/cluster-issuer: {{ tpl (.Values.ingress.clusterIssuer | toString) . }}
{{- if .Values.ingress.theiaCloudCommonName }}
cert-manager.io/common-name: "Theia Cloud"
{{- end }}
acme.cert-manager.io/http01-ingress-class: nginx
{{- end }}
{{- end }}
nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header 'X-Forwarded-Uri' $request_uri;
nginx.ingress.kubernetes.io/proxy-body-size: {{ tpl (.Values.ingress.proxyBodySize | toString) . }}
spec:
ingressClassName: nginx
{{- if .Values.ingress.tls }}
tls:
- hosts:
- {{ tpl (printf "%s.%s" .Values.hosts.configuration.instance .Values.hosts.configuration.baseHost | toString) . }}
{{- if .Values.ingress.addTLSSecretName }}
{{- range $wildcard := .Values.hosts.allWildcardInstances }}
{{- if (not (hasKey $.Values.ingress.allWildcardSecretNames $wildcard)) }}
- {{ printf "%s%s.%s" (tpl . $) (tpl $.Values.hosts.configuration.instance $) (tpl $.Values.hosts.configuration.baseHost $) | quote }}
{{- end }}
{{- end }}
secretName: ws-cert-secret
{{- end }}
{{- end }}

{{- range $wildcard := .Values.hosts.allWildcardInstances }}
{{- if hasKey $.Values.ingress.allWildcardSecretNames $wildcard }}
{{- $secretName := get $.Values.ingress.allWildcardSecretNames $wildcard }}
- hosts:
- {{ printf "%s%s.%s" (tpl $wildcard $) (tpl $.Values.hosts.configuration.instance $) (tpl $.Values.hosts.configuration.baseHost $) | quote }}
secretName: {{ tpl $secretName $ | quote }}
{{- end }}
{{- end }}

{{- if not (lookup "networking.k8s.io/v1" "Ingress" .Release.Namespace (tpl (.Values.ingress.instanceName | toString) .) ) }}
rules:
- host: {{ printf "%s.%s" (tpl .Values.hosts.configuration.instance .) (tpl .Values.hosts.configuration.baseHost .) }}
http:
{{- range .Values.hosts.allWildcardInstances }}
- host: {{ printf "%s%s.%s" (tpl . $) (tpl $.Values.hosts.configuration.instance $) (tpl $.Values.hosts.configuration.baseHost $) | quote }}
http:
{{- end }}
{{- else }}
rules:
{{ range $rule := (lookup "networking.k8s.io/v1" "Ingress" .Release.Namespace (tpl (.Values.ingress.instanceName | toString) .)).spec.rules }}
- host: {{ .host | quote }}
{{ if .http }}
http:
paths:
{{ with index .http.paths 0 }}
- path: {{ .path }}
pathType: Prefix
backend:
service:
name: {{ .backend.service.name }}
port:
number: {{ .backend.service.port.number }}
{{- end }}
{{ end }}
{{- end }}
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: oauth2-proxy-config
namespace: {{ .Release.Namespace }}
data:
oauth2-proxy.cfg: |+
# Provider config
provider="keycloak-oidc"
redirect_url="https://placeholder/oauth2/callback"
oidc_issuer_url="{{ tpl (.Values.keycloak.authUrl | toString) . }}realms/{{ tpl (.Values.keycloak.realm | toString) . }}"
ssl_insecure_skip_verify=true
# Client config
client_id="{{ tpl (.Values.keycloak.clientId | toString) . }}"
client_secret="{{ tpl (.Values.keycloak.clientSecret | toString) . }}"
cookie_secret="{{ tpl (.Values.keycloak.cookieSecret | toString) . }}"
cookie_secure="false"
#proxy_prefix=""
# Upstream config
http_address="0.0.0.0:5000"
upstreams="http://127.0.0.1:placeholder-port/"
# Proxy Config
#user_id_claim="preferred_username"
skip_auth_routes=["/health.*"]
skip_provider_button="true"
reverse_proxy="true"
# email_domains=["*"]
{{- if .Values.hosts.usePaths }}
cookie_domains=["{{ tpl (.Values.hosts.configuration.baseHost | toString) . }}"]
whitelist_domains=["{{ tpl (.Values.hosts.configuration.baseHost | toString) . }}:*",".google.com:*"]
{{- else }}
cookie_domains=["{{ tpl (.Values.hosts.configuration.instance | toString) . }}.{{ tpl (.Values.hosts.configuration.baseHost | toString) . }}"]
whitelist_domains=["{{ tpl (.Values.hosts.configuration.instance | toString) . }}.{{ tpl (.Values.hosts.configuration.baseHost | toString) . }}:*",".google.com:*"]
{{- end }}
custom_templates_dir="/templates"
{{- /* Extract the host where the Keycloak runs by extracting it from the auth URL via regex. */ -}}
{{- $keycloakUrl := tpl (.Values.keycloak.authUrl | toString) . -}}
{{- /* Regex to match a URL that matches the host in group 1: ([^/]+) */ -}}
{{- $hostRegex := `^https?://([^/]+)(/.*)?$` -}}
{{- /* Replace the URL with only the first group which is only the host. */ -}}
{{- $keycloakHost:= regexReplaceAll $hostRegex $keycloakUrl `$1` -}}

apiVersion: v1
kind: ConfigMap
metadata:
name: oauth2-proxy-config
namespace: {{ .Release.Namespace }}
data:
oauth2-proxy.cfg: |+
# Provider config
provider="keycloak-oidc"
redirect_url="https://placeholder/oauth2/callback"
oidc_issuer_url="{{ $keycloakUrl }}realms/{{ tpl (.Values.keycloak.realm | toString) . }}"
ssl_insecure_skip_verify=true
# Client config
client_id="{{ tpl (.Values.keycloak.clientId | toString) . }}"
client_secret="{{ tpl (.Values.keycloak.clientSecret | toString) . }}"
cookie_secret="{{ tpl (.Values.keycloak.cookieSecret | toString) . }}"
cookie_secure="false"
#proxy_prefix=""
# Upstream config
http_address="0.0.0.0:5000"
upstreams="http://127.0.0.1:placeholder-port/"
# Proxy Config
#user_id_claim="preferred_username"
skip_auth_routes=["/health.*"]
skip_provider_button="true"
reverse_proxy="true"
# email_domains=["*"]
{{- if .Values.hosts.usePaths }}
cookie_domains=["{{ tpl (.Values.hosts.configuration.baseHost | toString) . }}"]
whitelist_domains=["{{ tpl (.Values.hosts.configuration.baseHost | toString) . }}:*","{{ $keycloakHost }}:*",".google.com:*"]
{{- else }}
cookie_domains=["{{ tpl (.Values.hosts.configuration.instance | toString) . }}.{{ tpl (.Values.hosts.configuration.baseHost | toString) . }}"]
whitelist_domains=["{{ tpl (.Values.hosts.configuration.instance | toString) . }}:*","{{ $keycloakHost }}:*",".google.com:*"]
{{- end }}
custom_templates_dir="/templates"
Loading

0 comments on commit ad4d8d5

Please sign in to comment.