mirror of
https://github.com/sredevopsorg/deepseek-kubernetes-sandbox.git
synced 2026-11-03 09:23:25 +00:00
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>
This commit is contained in:
committed by
GitHub
parent
2178e58d57
commit
9466449f84
@@ -395,7 +395,8 @@ Notes and limits:
|
||||
- **SSO is trust-on-hop.** `AUTH_PROXY_HEADER` makes the gateway trust the proxy-asserted
|
||||
identity; the SSO variant must remain the only path to the Service, and its NetworkPolicy is
|
||||
required, not optional. Run [`scripts/preflight-sso.sh`](../scripts/preflight-sso.sh) after
|
||||
applying it.
|
||||
applying it: it fails when the Role does not grant `patch` on `sandboxclaims` (SSO token
|
||||
rotation) or when the variant's NetworkPolicies are missing.
|
||||
|
||||
## Failure modes
|
||||
|
||||
@@ -412,7 +413,7 @@ Notes and limits:
|
||||
| Per-user concurrency cap hit | HTTP `503` + `Retry-After`, or WebSocket close `1011` | `MAX_IN_FLIGHT_PER_USER` protects the single gateway from one busy tenant; reduce concurrency or raise the cap deliberately. These are per replica |
|
||||
| Oversized WebSocket message from DSH | Connection closes | `WS_MAX_MESSAGE_BYTES` (16 MiB) is enforced on upstream messages; raise it only if DSH legitimately needs larger frames |
|
||||
| Session expiry / revocation | `401` (HTTP) or close `4401` (WebSocket) | Expected after logout, user delete, `/recreate`, `COOKIE_MAX_AGE` expiry or a gateway restart; sign in again |
|
||||
| SSO variant applied without its NetworkPolicy (or with an Ingress) | Gateway accepts spoofed `X-Forwarded-User` | Demo-only configuration; keep `75-networkpolicies.yaml`, remove the second path, and run `scripts/preflight-sso.sh` |
|
||||
| SSO variant applied without its NetworkPolicy (or with an Ingress) | Gateway accepts spoofed `X-Forwarded-User` | Demo-only configuration; keep `75-networkpolicies.yaml`, remove the second path, and run `scripts/preflight-sso.sh`, which fails when either policy is missing |
|
||||
| Browser aborts a request (tab reload, back navigation) during a slow wake or handshake | No response reaches the client; nothing appears in the access log | If the abort lands before the response starts, the body read raises `ClientDisconnect` and the app answers `499` (`CLIENT_CLOSED_REQUEST`), which cannot reach the departed peer. Nothing reached DSH, no ERROR traceback is logged, and the in-flight slot is released. A request already streaming ends with its upstream status. |
|
||||
| DSH auth cookie expired mid-session | Proxy `401` once, then recovers | Gateway refreshes the handshake once |
|
||||
| Upstream pod name changed after resume | Cached cookie keyed by old pod UID is useless | Cache is invalidated on suspend; next request re-handshakes |
|
||||
|
||||
@@ -338,8 +338,10 @@ The SSO policy is what turns the trust boundary in the
|
||||
The `dsh-gateway` Service must still stay ClusterIP; do not apply both exposure
|
||||
variants. After applying the SSO variant, run
|
||||
[`scripts/preflight-sso.sh`](../scripts/preflight-sso.sh): it checks the
|
||||
gateway's SSO env, the Secrets, the TLS reference, leftover placeholders and
|
||||
accidental second paths (such as an Ingress).
|
||||
gateway's SSO env, the Secrets, the TLS reference, leftover placeholders,
|
||||
accidental second paths (such as an Ingress), the gateway Role's `patch` verb on
|
||||
`sandboxclaims` (SSO token rotation) and that both SSO NetworkPolicies are
|
||||
applied.
|
||||
|
||||
Verify the negative case from a sandbox pod (it is not the proxy):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user