# oauth2-proxy gate in front of Supabase Studio at db.0.knoe.dev. # # Sits between the GCE Ingress and supabase-kong; redirects unauthenticated # requests to Google Workspace, allows any @knoey.com identity through, then # proxies the request upstream to supabase-kong:8000 (which serves Studio at # the / route). Outside-domain users are rejected at this layer. # # Bootstrap: ./etc/init_oauth2_proxy.sh # Cluster: knoe-dev-0 (GKE app cluster) # Namespace: supabase (alongside supabase-* workloads + the existing Ingress) # # After this Deployment is Ready, the supabase-kong Ingress is patched to # route db.0.knoe.dev through oauth2-proxy:80, and the basic-auth plugin on # the Kong dashboard route is removed (oauth2-proxy is the gate now). # # Unified host model (Studio + SDK on the same hostname): # the `--skip-auth-route` args below let SDK requests on /auth/v1, /rest/v1, # /realtime/v1, /storage/v1, /functions/v1, /graphql/v1, /pg/* bypass the # Google sign-in flow and pass straight through to supabase-kong, where # Kong's `key-auth` plugin enforces the existing anon/service-role API keys. # The Studio UI at / remains Google-gated (no skip rule). Net effect: one # URL (db.0.knoe.dev) covers humans-in-Studio AND robots-via-supabase-py, # with the same security envelope as before — Kong's key-auth is the # enforcer on API paths regardless of which hostname they came in on. # # When knoe-auth Round 1 ships an OIDC OP at https://api.knoe.dev/auth, swap # the args below from `--provider=google` to `--provider=oidc` + # `--oidc-issuer-url=https://api.knoe.dev/auth` and reapply — no other # manifest changes needed. --- apiVersion: v1 kind: ServiceAccount metadata: name: oauth2-proxy namespace: supabase labels: app: oauth2-proxy app.kubernetes.io/managed-by: knoe-installer --- apiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: oauth2-proxy-backend-config namespace: supabase labels: app: oauth2-proxy app.kubernetes.io/managed-by: knoe-installer spec: healthCheck: type: HTTP requestPath: /ping port: 4180 timeoutSec: 60 --- apiVersion: v1 kind: Service metadata: name: oauth2-proxy namespace: supabase labels: app: oauth2-proxy app.kubernetes.io/managed-by: knoe-installer annotations: cloud.google.com/backend-config: '{"default": "oauth2-proxy-backend-config"}' spec: type: ClusterIP selector: app: oauth2-proxy ports: - name: http port: 80 targetPort: 4180 protocol: TCP --- apiVersion: apps/v1 kind: Deployment metadata: name: oauth2-proxy namespace: supabase labels: app: oauth2-proxy app.kubernetes.io/managed-by: knoe-installer spec: replicas: 1 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: oauth2-proxy template: metadata: labels: app: oauth2-proxy spec: serviceAccountName: oauth2-proxy securityContext: runAsNonRoot: true runAsUser: 65532 runAsGroup: 65532 seccompProfile: type: RuntimeDefault containers: - name: oauth2-proxy image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2 imagePullPolicy: IfNotPresent args: - --provider=google - --email-domain=knoey.com - --upstream=http://supabase-kong:8000 - --http-address=0.0.0.0:4180 - --reverse-proxy=true - --cookie-secure=true - --cookie-name=_knoe_studio_oauth2 - --cookie-domain=db.0.knoe.dev - --whitelist-domain=db.0.knoe.dev - --redirect-url=https://db.0.knoe.dev/oauth2/callback - --skip-provider-button=true - --scope=openid email profile # NB: do NOT set --pass-authorization-header / --set-authorization-header. # Those flags rewrite (or strip) the request's Authorization header, # which clobbers the supabase-py / Studio Authorization: Bearer # value that the storage and other Supabase services expect to parse # against JWT_SECRET. When per-user identity passthrough lands (post # knoe-auth Round 1), use --pass-user-headers / --set-xauthrequest # instead — those use X-Forwarded-* headers and don't collide with # Supabase's own auth. # # Bypass Google auth for Supabase API surfaces — Kong's key-auth # is the enforcer on these paths (anon / service-role keys). - --skip-auth-route=^/(auth|rest|realtime|storage|functions|graphql)/v1/.* - --skip-auth-route=^/pg/.* # Bypass Google auth for the onboarding reveal page. URL fragments # don't survive an OAuth redirect, so we can't gate this with # Google sign-in; instead, the engineer's URL is single-shot # delivery (email / QR), the temp password expires in 24h, and # the page recommends immediate rotation via `\password`. - --skip-auth-route=^/onboard\.html$ # Public support endpoint — 302s to mailto:support@knoe.dev. Skipping # auth so an unauthenticated user looking for help isn't bounced into # a confusing Google sign-in detour. - --skip-auth-route=^/support$ - --request-logging=true - --auth-logging=true - --standard-logging=true env: - name: OAUTH2_PROXY_CLIENT_ID valueFrom: secretKeyRef: name: oauth2-proxy-google-oidc key: client_id - name: OAUTH2_PROXY_CLIENT_SECRET valueFrom: secretKeyRef: name: oauth2-proxy-google-oidc key: client_secret - name: OAUTH2_PROXY_COOKIE_SECRET valueFrom: secretKeyRef: name: oauth2-proxy-google-oidc key: cookie_secret ports: - name: http containerPort: 4180 protocol: TCP livenessProbe: httpGet: path: /ping port: http initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 3 readinessProbe: httpGet: path: /ping port: http initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 3 resources: requests: cpu: 50m memory: 64Mi limits: cpu: 100m memory: 128Mi securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] readOnlyRootFilesystem: true