Skip to content

Commit 7f0e216

Browse files
iamriajulRiajul Islamclaude
authored
fix(helm): Traefik code-server auth redirect + redirect-url fix
- Add oauth2-proxy-code deployment+service for code-server (Traefik only) Routes code-server ingress through oauth2-proxy with --upstream=frontend:13337 - Code-server ingress backend: oauth2-proxy-code:4180 on Traefik (direct on nginx) - Frontend redirect-url: https://<domain>/oauth2/callback (Traefik, same domain) vs https://auth.<domain>/oauth2/callback (nginx, auth subdomain) Co-authored-by: Riajul Islam <riajul@kahf.co> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0f1494e commit 7f0e216

3 files changed

Lines changed: 153 additions & 9 deletions

File tree

helm/vibe-kanban-team/templates/frontend-code-server-ingress.yaml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
{{- if include "vibe-kanban-team.frontend.codeServerIngressEnabled" . -}}
22
{{- $frontendName := include "vibe-kanban-team.frontend.fullname" . -}}
33
{{- $codeServerPort := .Values.frontend.codeServer.port -}}
4+
{{- $ingressClassName := .Values.global.ingressClassName | default "" -}}
5+
{{- $useTraefikProxy := and .Values.frontend.auth.enabled (contains "traefik" $ingressClassName) -}}
6+
{{- $backendName := ternary (printf "%s-oauth2-proxy-code" $frontendName) $frontendName $useTraefikProxy -}}
7+
{{- $backendPort := ternary 4180 ($codeServerPort | int) $useTraefikProxy -}}
48
{{- $annotations := include "vibe-kanban-team.ingress.annotations" (dict "root" . "annotations" .Values.frontend.codeServerIngress.annotations) -}}
59
{{- $authAnnotations := include "vibe-kanban-team.frontend.authAnnotations" . -}}
6-
{{- if and .Values.frontend.auth.enabled (eq (trim $authAnnotations) "") -}}
10+
{{- if and .Values.frontend.auth.enabled (not $useTraefikProxy) (eq (trim $authAnnotations) "") -}}
711
{{- fail "frontend.auth.enabled=true but no protected ingress annotations could be derived. Set global.ingressClassName to nginx, or set frontend.auth.createTraefikMiddleware=true with a traefik ingress class, or provide frontend.auth.protectedIngressAnnotations." -}}
812
{{- end -}}
913
{{- $className := include "vibe-kanban-team.ingress.className" (dict "root" . "className" .Values.frontend.codeServerIngress.className) -}}
@@ -16,12 +20,12 @@ metadata:
1620
labels:
1721
{{- include "vibe-kanban-team.labels" . | nindent 4 }}
1822
app.kubernetes.io/component: frontend
19-
{{- if or (ne (trim $annotations) "") (ne (trim $authAnnotations) "") }}
23+
{{- if or (ne (trim $annotations) "") (and (not $useTraefikProxy) (ne (trim $authAnnotations) "")) }}
2024
annotations:
2125
{{- if ne (trim $annotations) "" }}
2226
{{- $annotations | nindent 4 }}
2327
{{- end }}
24-
{{- if ne (trim $authAnnotations) "" }}
28+
{{- if and (not $useTraefikProxy) (ne (trim $authAnnotations) "") }}
2529
{{- $authAnnotations | nindent 4 }}
2630
{{- end }}
2731
{{- end }}
@@ -57,9 +61,9 @@ spec:
5761
pathType: {{ .pathType }}
5862
backend:
5963
service:
60-
name: {{ $frontendName }}
64+
name: {{ $backendName }}
6165
port:
62-
number: {{ $codeServerPort }}
66+
number: {{ $backendPort }}
6367
{{- end }}
6468
{{- end }}
6569
{{- else if $derivedHost }}
@@ -70,18 +74,18 @@ spec:
7074
pathType: Prefix
7175
backend:
7276
service:
73-
name: {{ $frontendName }}
77+
name: {{ $backendName }}
7478
port:
75-
number: {{ $codeServerPort }}
79+
number: {{ $backendPort }}
7680
- host: {{ $derivedProxyHost | quote }}
7781
http:
7882
paths:
7983
- path: /
8084
pathType: Prefix
8185
backend:
8286
service:
83-
name: {{ $frontendName }}
87+
name: {{ $backendName }}
8488
port:
85-
number: {{ $codeServerPort }}
89+
number: {{ $backendPort }}
8690
{{- end }}
8791
{{- end }}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
{{- if and .Values.frontend.enabled .Values.frontend.auth.enabled .Values.frontend.codeServer.enabled (contains "traefik" (.Values.global.ingressClassName | default "")) }}
2+
{{- $frontendName := include "vibe-kanban-team.frontend.fullname" . -}}
3+
{{- $proxyName := printf "%s-oauth2-proxy-code" $frontendName -}}
4+
{{- $codeServerHost := include "vibe-kanban-team.codeServer.host" . -}}
5+
---
6+
# oauth2-proxy for code-server (Traefik only) — proxies to code-server port.
7+
apiVersion: apps/v1
8+
kind: Deployment
9+
metadata:
10+
name: {{ $proxyName }}
11+
labels:
12+
{{- include "vibe-kanban-team.labels" . | nindent 4 }}
13+
app.kubernetes.io/component: oauth2-proxy-code
14+
spec:
15+
replicas: 1
16+
selector:
17+
matchLabels:
18+
{{- include "vibe-kanban-team.selectorLabels" . | nindent 6 }}
19+
app.kubernetes.io/component: oauth2-proxy-code
20+
template:
21+
metadata:
22+
labels:
23+
{{- include "vibe-kanban-team.labels" . | nindent 8 }}
24+
app.kubernetes.io/component: oauth2-proxy-code
25+
spec:
26+
{{- with .Values.imagePullSecrets }}
27+
imagePullSecrets:
28+
{{- toYaml . | nindent 8 }}
29+
{{- end }}
30+
securityContext:
31+
runAsNonRoot: true
32+
runAsUser: 65534
33+
fsGroup: 65534
34+
containers:
35+
- name: oauth2-proxy
36+
image: "{{ .Values.frontend.auth.image.repository }}:{{ .Values.frontend.auth.image.tag }}"
37+
imagePullPolicy: {{ .Values.frontend.auth.image.pullPolicy }}
38+
args:
39+
- --provider={{ .Values.frontend.auth.provider | default "google" }}
40+
{{- if .Values.frontend.auth.oidcIssuerUrl }}
41+
- --oidc-issuer-url={{ .Values.frontend.auth.oidcIssuerUrl }}
42+
{{- end }}
43+
{{- range .Values.frontend.auth.emailDomains }}
44+
- --email-domain={{ . }}
45+
{{- end }}
46+
{{- if gt (len .Values.frontend.auth.allowedEmails) 0 }}
47+
- --authenticated-emails-file=/etc/oauth2-proxy/emails
48+
{{- end }}
49+
{{- if .Values.frontend.auth.githubOrg }}
50+
- --github-org={{ .Values.frontend.auth.githubOrg }}
51+
{{- end }}
52+
{{- if .Values.frontend.auth.githubTeam }}
53+
- --github-team={{ .Values.frontend.auth.githubTeam }}
54+
{{- end }}
55+
{{- range .Values.frontend.auth.extraArgs }}
56+
- {{ . }}
57+
{{- end }}
58+
- --upstream=http://{{ $frontendName }}:{{ .Values.frontend.codeServer.port }}/
59+
- --http-address=0.0.0.0:4180
60+
- --reverse-proxy=true
61+
- --set-xauthrequest=true
62+
- --set-authorization-header=true
63+
- --cookie-domain={{ .Values.frontend.auth.cookieDomain | default (include "vibe-kanban-team.frontend.cookieDomain" .) }}
64+
- --cookie-samesite=lax
65+
- --cookie-secure=true
66+
- --whitelist-domain={{ .Values.frontend.auth.cookieDomain | default (include "vibe-kanban-team.frontend.cookieDomain" .) }}
67+
- --redirect-url=https://{{ $codeServerHost }}/oauth2/callback
68+
- --skip-provider-button=true
69+
env:
70+
- name: OAUTH2_PROXY_CLIENT_ID
71+
valueFrom:
72+
secretKeyRef:
73+
name: {{ .Values.frontend.auth.secretName }}
74+
key: client-id
75+
- name: OAUTH2_PROXY_CLIENT_SECRET
76+
valueFrom:
77+
secretKeyRef:
78+
name: {{ .Values.frontend.auth.secretName }}
79+
key: client-secret
80+
- name: OAUTH2_PROXY_COOKIE_SECRET
81+
valueFrom:
82+
secretKeyRef:
83+
name: {{ .Values.frontend.auth.secretName }}
84+
key: cookie-secret
85+
ports:
86+
- name: http
87+
containerPort: 4180
88+
protocol: TCP
89+
livenessProbe:
90+
httpGet:
91+
path: /ping
92+
port: http
93+
initialDelaySeconds: 5
94+
periodSeconds: 10
95+
readinessProbe:
96+
httpGet:
97+
path: /ping
98+
port: http
99+
initialDelaySeconds: 3
100+
periodSeconds: 5
101+
resources:
102+
{{- toYaml .Values.frontend.auth.resources | nindent 12 }}
103+
securityContext:
104+
allowPrivilegeEscalation: false
105+
readOnlyRootFilesystem: true
106+
{{- if gt (len .Values.frontend.auth.allowedEmails) 0 }}
107+
volumeMounts:
108+
- name: emails
109+
mountPath: /etc/oauth2-proxy
110+
readOnly: true
111+
{{- end }}
112+
{{- if gt (len .Values.frontend.auth.allowedEmails) 0 }}
113+
volumes:
114+
- name: emails
115+
configMap:
116+
name: {{ $frontendName }}-oauth2-proxy-emails
117+
{{- end }}
118+
---
119+
apiVersion: v1
120+
kind: Service
121+
metadata:
122+
name: {{ $proxyName }}
123+
labels:
124+
{{- include "vibe-kanban-team.labels" . | nindent 4 }}
125+
app.kubernetes.io/component: oauth2-proxy-code
126+
spec:
127+
type: ClusterIP
128+
ports:
129+
- port: 4180
130+
targetPort: http
131+
protocol: TCP
132+
name: http
133+
selector:
134+
{{- include "vibe-kanban-team.selectorLabels" . | nindent 4 }}
135+
app.kubernetes.io/component: oauth2-proxy-code
136+
{{- end }}

helm/vibe-kanban-team/templates/frontend-oauth2-proxy-deployment.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ spec:
7171
- --cookie-samesite=lax
7272
- --cookie-secure=true
7373
- --whitelist-domain={{ .Values.frontend.auth.cookieDomain | default (include "vibe-kanban-team.frontend.cookieDomain" .) }}
74+
{{- if contains "traefik" $ingressClassName }}
75+
- --redirect-url=https://{{ include "vibe-kanban-team.frontend.host" . }}/oauth2/callback
76+
{{- else }}
7477
- --redirect-url=https://{{ .Values.frontend.auth.host | default (include "vibe-kanban-team.auth.host" .) }}/oauth2/callback
78+
{{- end }}
7579
- --skip-provider-button=true
7680
env:
7781
- name: OAUTH2_PROXY_CLIENT_ID

0 commit comments

Comments
 (0)