1
0
mirror of https://github.com/sredevopsorg/deepseek-kubernetes-sandbox.git synced 2026-11-03 09:23:25 +00:00
Files
deepseek-kubernetes-sandbox/examples/dsh-agents-as-a-service/manifests/exposure/gateway-api-sso/75-networkpolicies.yaml
SREDevOps.org Agent 9466449f84 fix(exposure): check SSO RBAC and NetworkPolicies in preflight (#47)
The preflight is the documented gate before real SSO traffic, but it did
not check two things the dsh-demo install got wrong:

- The gateway Role must grant `patch` on
  extensions.agents.x-k8s.io/sandboxclaims. The SSO landing path rotates
  the claim's token-hash annotation whenever the browser has no valid
  gateway session (first visit, expired or foreign cookie, gateway
  restart), so a missing verb makes every such sign-in answer 503.
  Verify with `kubectl auth can-i --as`; when a read-only kubeconfig
  cannot impersonate, fall back to reading the rules of the Role (or
  ClusterRole) the RoleBinding points at.
- The variant's NetworkPolicies must be applied. Without them any Pod in
  the cluster can reach dsh-gateway:8080 and spoof X-Forwarded-User, so
  the exposure is demo-only. Fail the preflight while either policy from
  75-networkpolicies.yaml is missing.

Also fix a false positive in the cookie-secret check: oauth2-proxy accepts
16, 24 or 32 raw bytes, or URL-safe unpadded base64 that decodes to one of
those lengths (pkg/encryption.SecretBytes). The documented
`secrets.token_urlsafe(32)` value is 43 base64 characters that decode to 32
bytes, so it is valid and must not be reported as 43 raw bytes.

The docs that enumerate the preflight checks are updated to match, and
75-networkpolicies.yaml notes that the preflight enforces it.

Verified with shellcheck, yamllint, make check and the gateway test suite
(150 passed); the new checks were exercised read-only against the live
dsh-demo cluster.

Entire-Checkpoint: 01M6FNY2WTC4GMAJ8BAHABN88M

Co-authored-by: SREDevOpsAgents <agents@sredevops.org>
2026-11-03 01:03:06 -03:00

123 lines
3.3 KiB
YAML

# REQUIRED with the SSO exposure variant: enforce the trust boundary at the
# network layer. Applying the SSO variant without this file is demo-only.
# `scripts/preflight-sso.sh` fails while either policy below is missing.
#
# The chain is Traefik (Gateway API) -> oauth2-proxy -> dsh-gateway. These
# policies make it the ONLY chain:
# - the gateway accepts traffic only from oauth2-proxy pods;
# - oauth2-proxy accepts traffic only from the Gateway implementation;
# - oauth2-proxy egress is limited to DNS, public HTTPS (GitHub) and the
# gateway.
# The gateway's own egress (Kubernetes API, sandbox pods) is intentionally not
# restricted here: the API-server endpoint is cluster-specific. Add it for
# production. See
# ../../../docs/optional-hardening.md#gateway-egress-required-for-production.
#
# This manifest assumes Traefik, matching gatewayClassName: traefik in
# 70-gateway.yaml. Adjust the app.kubernetes.io/name selector for another
# implementation. NetworkPolicy enforcement of kubelet probes is CNI-dependent;
# if the gateway or proxy fails its probes, allow the node CIDR on the probe
# port or remove the ingress policy.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dsh-gateway-ingress
namespace: dsh-demo
spec:
podSelector:
matchLabels:
app: dsh-gateway
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: oauth2-proxy
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: oauth2-proxy-ingress
namespace: dsh-demo
spec:
podSelector:
matchLabels:
app: oauth2-proxy
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector: {}
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
ports:
- protocol: TCP
port: 4180
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: oauth2-proxy-egress
namespace: dsh-demo
spec:
podSelector:
matchLabels:
app: oauth2-proxy
policyTypes:
- Egress
egress:
# Cluster DNS.
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# NodeLocal DNSCache.
- to:
- ipBlock:
cidr: 169.254.20.10/32
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# The gateway backend.
- to:
- podSelector:
matchLabels:
app: dsh-gateway
ports:
- protocol: TCP
port: 8080
# GitHub OAuth endpoints are public HTTPS. Private ranges and the metadata
# server stay blocked.
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 169.254.0.0/16
- 100.64.0.0/10
- ipBlock:
cidr: "::/0"
except:
- "fc00::/7"
- "fe80::/10"
ports:
- protocol: TCP
port: 443