Skip to content

Commit e910610

Browse files
committed
fix(server): validate k8s serviceaccount tokens with tokenreview
1 parent 8e88775 commit e910610

8 files changed

Lines changed: 331 additions & 277 deletions

File tree

‎.agents/skills/helm-dev-environment/SKILL.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ mise run helm:k3s:create
2626
```
2727

2828
Creates a k3d cluster and merges its kubeconfig into the worktree-local `kubeconfig` file.
29-
Also applies base manifests (`deploy/kube/manifests/agent-sandbox.yaml`). Traefik is
30-
disabled at cluster creation time.
29+
Also applies base manifests (`deploy/kube/manifests/agent-sandbox.yaml`) and preloads the
30+
default community sandbox image into k3d so the first sandbox create does not wait on a
31+
large registry pull. Traefik is disabled at cluster creation time.
3132

3233
**Multi-worktree support:** the cluster name is derived from the last component of the
3334
current git branch (e.g. branch `kube-support/local-dev/tmutch` → cluster
@@ -43,6 +44,8 @@ Port mappings created at cluster time (cannot be changed without recreating):
4344

4445
Override with env vars before running `helm:k3s:create`:
4546
- `HELM_K3S_LB_HOST_PORT` (default: `8080`)
47+
- `HELM_K3S_PRELOAD_SANDBOX_IMAGE` (default:
48+
`ghcr.io/nvidia/openshell-community/sandboxes/base:latest`; set to an empty value to skip)
4649

4750
### 2. Deploy OpenShell
4851

‎architecture/gateway.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,12 @@ authorized by role policy when OIDC or edge identity is enabled.
4949
Sandbox secrets are gateway-signed JWTs bound to a single sandbox ID. Docker,
5050
Podman, and VM drivers deliver the initial token through supervisor-only
5151
runtime material; Kubernetes supervisors exchange a projected ServiceAccount
52-
token through `IssueSandboxToken`. Supervisors renew gateway JWTs in memory
53-
before expiry. Older tokens are not server-revoked; deployments bound replay
54-
exposure with short `gateway_jwt.ttl_secs` lifetimes.
52+
token through `IssueSandboxToken`. The gateway validates that projected token
53+
with Kubernetes `TokenReview`, checks the returned pod binding against the live
54+
pod UID, and reads the pod's sandbox annotation before minting the gateway JWT.
55+
Supervisors renew gateway JWTs in memory before expiry. Older tokens are not
56+
server-revoked; deployments bound replay exposure with short
57+
`gateway_jwt.ttl_secs` lifetimes.
5558

5659
Sandbox JWTs are not user credentials. The gRPC router accepts
5760
`Principal::Sandbox` only on the supervisor-to-gateway RPC allowlist

‎crates/openshell-sandbox/src/grpc_client.rs‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
//! gRPC client for fetching sandbox policy, provider environment, and inference
55
//! route bundles from `OpenShell` server.
66
//!
7-
//! Every request carries a gateway-minted JWT in the `Authorization` header
8-
//! (PR 3 of the per-sandbox identity series; see issue #1354). The token is
9-
//! resolved at startup from one of three sources:
7+
//! Every request carries a gateway-minted JWT in the `Authorization` header.
8+
//! The token is resolved at startup from one of three sources:
109
//!
1110
//! 1. `OPENSHELL_SANDBOX_TOKEN` — raw JWT in the env (test harness path).
1211
//! 2. `OPENSHELL_SANDBOX_TOKEN_FILE` — file containing the JWT (Docker /

0 commit comments

Comments
 (0)