mirror of
https://github.com/sredevopsorg/deepseek-kubernetes-sandbox.git
synced 2026-11-03 09:23:25 +00:00
- Replace user:token cookies with opaque server-side sessions, revocable on logout, delete, recreate and expiry; bind every credential to the path user and add cross-user regression tests. - Rate-limit /users and /login, add optional signup invite codes and form same-origin checks, and unify login failures to 401. - Require explicit ALLOW_INSECURE_COOKIES for plain HTTP, use __Host-dsh_gw_session when secure, and fix secure cookie deletion. - Strip client-supplied forwarding/SSO headers, add an optional upstream allowlist, per-user in-flight and WebSocket message caps, credential-free handshake errors, and sweep-time state pruning. - Digest-pin base images, hash-pin gateway dependencies, verify DSH_COMMIT in the build, and run the gateway image as non-root with a pinned Python base. - Update manifests, production checklist, architecture/security docs and add an SSO preflight script. BREAKING CHANGE: existing dsh_gw_session=<user>:<token> cookies are invalid; users must sign in again. Unknown users on POST /login now return 401 instead of 404, and the gateway refuses COOKIE_SECURE=false unless ALLOW_INSECURE_COOKIES=1.
147 lines
5.2 KiB
YAML
147 lines
5.2 KiB
YAML
# oauth2-proxy — GitHub OAuth login in front of the dsh-gateway.
|
|
#
|
|
# Runs as a reverse proxy: it authenticates the browser against GitHub
|
|
# (restricted to a configured organization), then forwards the request to
|
|
# the dsh-gateway Service with the authenticated identity in X-Forwarded-User
|
|
# (plus X-Auth-Request-* via --set-xauthrequest). The gateway trusts that
|
|
# header only when AUTH_PROXY_HEADER is set on its Deployment.
|
|
#
|
|
# ENABLING SSO TAKES BOTH SIDES (see ../../../exposure/README.md):
|
|
# 1. Set AUTH_PROXY_HEADER=X-Forwarded-User on deploy/dsh-gateway, otherwise
|
|
# the gateway ignores the header and the login is cosmetic:
|
|
# kubectl -n dsh-demo set env deploy/dsh-gateway \
|
|
# AUTH_PROXY_HEADER=X-Forwarded-User COOKIE_SECURE=true
|
|
# 2. Make dsh-gateway reachable ONLY through this proxy: keep the Service
|
|
# ClusterIP, route browser traffic through 71-httproute.yaml, and do not
|
|
# apply ../ingress/ (or anything else that reaches the gateway). A
|
|
# client that can reach dsh-gateway:8080 can spoof X-Forwarded-User and
|
|
# impersonate any user.
|
|
#
|
|
# 75-networkpolicies.yaml enforces that boundary at the network layer: the
|
|
# gateway accepts traffic only from oauth2-proxy pods, oauth2-proxy only from
|
|
# the Gateway implementation, and oauth2-proxy egress is limited to DNS,
|
|
# public HTTPS and the gateway. Apply it with this variant.
|
|
#
|
|
# TLS terminates at the Gateway listener (70-gateway.yaml); keep
|
|
# --cookie-secure=true and COOKIE_SECURE=true on the gateway.
|
|
#
|
|
# The image is digest-pinned: quay.io/oauth2-proxy/oauth2-proxy:v7.15.5@sha256:...
|
|
# (versions.env: OAUTH2_PROXY_IMAGE). The digest is the immutable multi-arch
|
|
# index, so the tag can never be moved under us. Credentials come from the
|
|
# "oauth2-proxy" Secret (see 73-oauth2-proxy-secret.yaml.example); this
|
|
# manifest never carries secrets.
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: oauth2-proxy
|
|
namespace: dsh-demo
|
|
labels:
|
|
app: oauth2-proxy
|
|
app.kubernetes.io/part-of: dsh-demo
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: oauth2-proxy
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: oauth2-proxy
|
|
app.kubernetes.io/part-of: dsh-demo
|
|
spec:
|
|
# OPTIONAL: run the proxy under gVisor and/or pin it to a node pool.
|
|
# See ../../../docs/optional-hardening.md.
|
|
# runtimeClassName: gvisor
|
|
# nodeSelector:
|
|
# dsh.example.com/node-pool: dsh
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 2000
|
|
runAsGroup: 2000
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
containers:
|
|
- name: oauth2-proxy
|
|
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.5@sha256:8498b0d0ef0a7b29686414000a08aee467f02d0299c9ed1e006a8f33fc017916
|
|
imagePullPolicy: IfNotPresent
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
capabilities:
|
|
drop: ["ALL"]
|
|
args:
|
|
- --http-address=0.0.0.0:4180
|
|
- --provider=github
|
|
# TODO: replace with the GitHub organization allowed to sign in.
|
|
- --github-org=your-github-org
|
|
- --email-domain=*
|
|
# Reverse-proxy target: the gateway backend Service.
|
|
- --upstream=http://dsh-gateway:8080
|
|
# Public callback (TLS terminates at the Gateway listener).
|
|
# TODO: replace with the actual public FQDN.
|
|
- --redirect-url=https://dsh-demo.example.com/oauth2/callback
|
|
- --cookie-secure=true
|
|
- --cookie-name=_oauth2_proxy
|
|
# Also expose X-Auth-Request-User/Email/Groups upstream.
|
|
- --set-xauthrequest
|
|
# Single provider: skip the provider-selection page.
|
|
- --skip-provider-button
|
|
env:
|
|
- name: OAUTH2_PROXY_CLIENT_ID
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: oauth2-proxy
|
|
key: client-id
|
|
- name: OAUTH2_PROXY_CLIENT_SECRET
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: oauth2-proxy
|
|
key: client-secret
|
|
- name: OAUTH2_PROXY_COOKIE_SECRET
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: oauth2-proxy
|
|
key: cookie-secret
|
|
ports:
|
|
- name: http
|
|
containerPort: 4180
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: http
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 1
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /ready
|
|
port: http
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
resources:
|
|
requests:
|
|
cpu: 10m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 200m
|
|
memory: 128Mi
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: oauth2-proxy
|
|
namespace: dsh-demo
|
|
labels:
|
|
app: oauth2-proxy
|
|
app.kubernetes.io/part-of: dsh-demo
|
|
spec:
|
|
selector:
|
|
app: oauth2-proxy
|
|
ports:
|
|
- name: http
|
|
port: 4180
|
|
targetPort: http
|