Files
clawmates/deploy/helm/teamclaw/templates/frontend.yaml
T
Omar SobhandClaude Fable 5 ceca21ca79 Clerk frontend integration: one image, runtime-switched identity
- src/lib/auth/bearer.ts is the single identity dispatch for both
  server-side token consumers (RSC apiFetch and the /api proxy route):
  local -> httpOnly tc_session cookie; clerk -> Clerk getToken() session
  JWT. The Clerk SDK is imported lazily, so the air-gapped/local path
  never loads it
- Runtime env (AUTH_MODE / CLERK_PUBLISHABLE_KEY / CLERK_SECRET_KEY),
  deliberately NOT build-time NEXT_PUBLIC_*: the same standalone image
  serves both deployment targets
- Conditional <ClerkProvider> in the root layout (publishableKey passed
  at render from runtime env); /login renders Clerk's <SignIn /> in
  clerk mode and the local form otherwise; proxy.ts middleware delegates
  to clerkMiddleware() only when active
- Helm: frontend deployment injects the Clerk keys from a Secret when
  auth.mode=clerk
- mode.ts unit-tested (default local, exact-match clerk, loud failure
  without the publishable key); the local path stays proven by all 29
  journeys; the Clerk branch is thin delegation to the SDK, exercised in
  deployment smoke per docs/clerk.md

157 Rust + 68 frontend tests + 29 Playwright journeys.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 10:36:51 -05:00

56 lines
1.8 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: teamclaw-frontend
labels: {{- include "teamclaw.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.frontend.replicas }}
selector:
matchLabels: {{- include "teamclaw.frontendSelector" . | nindent 6 }}
template:
metadata:
labels:
{{- include "teamclaw.frontendSelector" . | nindent 8 }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
securityContext:
runAsNonRoot: true
seccompProfile: { type: RuntimeDefault }
containers:
- name: frontend
image: "{{ .Values.image.registry }}/frontend:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- { containerPort: 3000, name: http }
env:
- name: API_ORIGIN
value: http://teamclaw-server:8080
{{- if eq .Values.auth.mode "clerk" }}
- name: AUTH_MODE
value: clerk
- name: CLERK_PUBLISHABLE_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.auth.clerkSecretName }}
key: publishable-key
- name: CLERK_SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.auth.clerkSecretName }}
key: secret-key
{{- end }}
resources: {{- toYaml .Values.frontend.resources | nindent 12 }}
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: ["ALL"] }
---
apiVersion: v1
kind: Service
metadata:
name: teamclaw-frontend
labels: {{- include "teamclaw.labels" . | nindent 4 }}
spec:
selector: {{- include "teamclaw.frontendSelector" . | nindent 4 }}
ports:
- { name: http, port: 3000, targetPort: http }