mirror of
https://github.com/sredevopsorg/deepseek-kubernetes-sandbox.git
synced 2026-11-03 01:13:24 +00:00
fix(gateway)!: replace token cookies with revocable sessions and harden abuse controls
- 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.
This commit is contained in:
@@ -61,14 +61,27 @@ Values from [versions.env](../versions.env) at the current identity:
|
||||
| --- | --- | --- |
|
||||
| Upstream DSH source | `DSH_REPO` | [versions.env](../versions.env) |
|
||||
| DSH ref | `dsh-v0.2.1-rc.5` | `DSH_VERSION` |
|
||||
| DSH commit | `b830ec950faba0a46dda564be3e2d854afed94f1` | `DSH_COMMIT`; the main image build fails unless the clone's `HEAD` matches |
|
||||
| Repository revision | `(empty)` | `RELEASE_REVISION` |
|
||||
| pnpm | `11.28.5` | `PNPM_VERSION` |
|
||||
| Node build image | `docker.io/node:24-trixie@sha256:8c761eca2bf7eec965f946cf47b8090143cb41f45f2f8699af0cc0298d2d2d19` | `NODE_BUILD_IMAGE`, digest-pinned |
|
||||
| Node runtime image | `docker.io/node:24-trixie-slim@sha256:54f84b4cf8432b21aaffd5d3ce8d41e12cea0d10d33c09d2f3c9879d49d6b446` | `NODE_RUNTIME_IMAGE`, digest-pinned |
|
||||
| Gateway Python image | `docker.io/python:3.12-slim@sha256:aa943ce411423c7582288f18707ff66eddcbaeb510502d747a72aeb34f30d159` | `GATEWAY_PYTHON_IMAGE`, digest-pinned |
|
||||
| agent-sandbox (CRDs) | `v1.0.8` | `AGENT_SANDBOX_VERSION`, used by the examples and CI dry-run |
|
||||
| Kubernetes Gateway API | `v1.2.1` | `GATEWAY_API_VERSION`, used by the SSO exposure variant |
|
||||
| oauth2-proxy | `quay.io/oauth2-proxy/oauth2-proxy:v7.15.5` | `OAUTH2_PROXY_IMAGE` |
|
||||
| oauth2-proxy | `quay.io/oauth2-proxy/oauth2-proxy:v7.15.5@sha256:8498b0d0ef0a7b29686414000a08aee467f02d0299c9ed1e006a8f33fc017916` | `OAUTH2_PROXY_IMAGE`, digest-pinned and used by the SSO exposure variant |
|
||||
| Main image | `ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox` | `GHCR_IMAGE` |
|
||||
| Gateway image | `ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox/dsh-agents-as-a-service/gateway` | `GATEWAY_IMAGE`, nested below `GHCR_IMAGE` |
|
||||
|
||||
Every container base image is referenced as `name:tag@sha256:<index digest>`, not
|
||||
by tag alone: `check-versions.sh` rejects a pin without a digest, so a re-pushed
|
||||
tag cannot change what we build from. The example gateway's Python dependencies
|
||||
are fully hash-pinned in
|
||||
[requirements.txt](../examples/dsh-agents-as-a-service/gateway/requirements.txt)
|
||||
and
|
||||
[requirements-dev.txt](../examples/dsh-agents-as-a-service/gateway/requirements-dev.txt)
|
||||
and installed with `pip install --require-hashes`.
|
||||
|
||||
Example component images are always nested below the main package:
|
||||
`<GHCR_IMAGE>/<example>/<component>`. `check-versions.sh` rejects an unrelated
|
||||
top-level package.
|
||||
@@ -86,8 +99,15 @@ file to derive from it. Never edit the Dockerfile, manifests, Makefile or
|
||||
workflows with a literal version.
|
||||
|
||||
- New upstream DSH ref: change `DSH_VERSION` and clear `RELEASE_REVISION`.
|
||||
- Repository-only change at the same DSH ref: keep `DSH_VERSION`, set
|
||||
`RELEASE_REVISION=r(N+1)`.
|
||||
`set-version` resolves the new ref's commit with `git ls-remote` (peeled `^{}`
|
||||
commit first, tag ref as fallback) and rewrites `DSH_COMMIT` in `versions.env`,
|
||||
the Dockerfile ARG default and `.env.sample`; the build then verifies it.
|
||||
- Repository-only change at the same DSH ref: keep `DSH_VERSION` and `DSH_COMMIT`,
|
||||
set `RELEASE_REVISION=r(N+1)`.
|
||||
- Base images (Node and Python) are bumped by hand: change the tag *and* the
|
||||
`@sha256:` digest in `versions.env` together, then run `make check` and a build.
|
||||
There is deliberately no automated digest refresh, because a silent base-image
|
||||
change is exactly what digest pinning exists to prevent.
|
||||
|
||||
## Release checklist
|
||||
|
||||
@@ -98,7 +118,8 @@ workflows with a literal version.
|
||||
the tag does not already exist, and previews the generated notes.
|
||||
5. Create and push the annotated `dsh-*` release tag (or dispatch
|
||||
`release.yaml` with an existing tag). The workflow validates that the tag
|
||||
matches [versions.env](../versions.env).
|
||||
matches [versions.env](../versions.env) and that the upstream ref still
|
||||
resolves to `DSH_COMMIT` before building anything.
|
||||
6. The workflow builds and pushes multi-arch images for the main image and the
|
||||
example components (the identity tag plus `latest`), creates the GitHub
|
||||
Release from the git-cliff notes, and opens a `chore(changelog)` PR that
|
||||
@@ -142,8 +163,17 @@ make changelog # regenerate CHANGELOG.md locally
|
||||
|
||||
## Digest pinning
|
||||
|
||||
Release identities are mutable only in theory; deployments should still pin the
|
||||
resolved digest for reproducibility and supply-chain safety:
|
||||
Supply-chain inputs are pinned to immutable content, not to mutable tags:
|
||||
|
||||
- **Build inputs**: every container base image is referenced by multi-arch index
|
||||
digest in [versions.env](../versions.env), and the example gateway's Python
|
||||
dependencies are hash-pinned (`--require-hashes`).
|
||||
- **Upstream source**: the Dockerfile clones `DSH_VERSION` and fails unless the
|
||||
clone's `HEAD` equals `DSH_COMMIT`, so a moved upstream tag cannot change what
|
||||
a rebuild packages.
|
||||
|
||||
Release identities are immutable in theory; deployments should still pin the
|
||||
_resolved_ digest for reproducibility and supply-chain safety:
|
||||
|
||||
```bash
|
||||
docker buildx imagetools inspect ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox:dsh-v0.2.1-rc.5
|
||||
|
||||
Reference in New Issue
Block a user