From the 2026-06-10 multi-agent review of feat/sandbox-execution-backend (deferred from the fix PR by design discussion).
k8s-stage.ts writes the pre-stage attestation to /workspace/.tale/prestage.json, and the harvest container reads it back — but the whole /workspace emptyDir (including .tale/) is writable by the runner container (same UID, shared volume). User code can therefore forge priorStage (staged/skipped lists, sha256s) and stageMs before harvest reads them.
Impact: the platform's PRE_STAGE_FAILED gate diffs priorStage.staged against its manifest — forged attestation could make a partially-staged workspace look fully staged. The blast radius is limited to the user's own run, but the attestation's integrity claim is hollow on k8s (the docker path computes it spawner-side, outside the runtime's reach).
Possible directions (needs a design pass):
- have stage pass the attestation out-of-band (e.g. stage prints it to its own container log; the spawner reads it like the harvest result line), or
- have harvest distrust
.tale/ and recompute hashes for the files it can see, or
- accept + document the delta.
Refs: services/sandbox/src/backend/kubernetes/k8s-stage.ts, k8s-harvest.ts (readPrestage), k8s-protocol.ts (PRESTAGE_PATH).
From the 2026-06-10 multi-agent review of feat/sandbox-execution-backend (deferred from the fix PR by design discussion).
k8s-stage.tswrites the pre-stage attestation to/workspace/.tale/prestage.json, and the harvest container reads it back — but the whole/workspaceemptyDir (including.tale/) is writable by the runner container (same UID, shared volume). User code can therefore forgepriorStage(staged/skipped lists, sha256s) andstageMsbefore harvest reads them.Impact: the platform's PRE_STAGE_FAILED gate diffs
priorStage.stagedagainst its manifest — forged attestation could make a partially-staged workspace look fully staged. The blast radius is limited to the user's own run, but the attestation's integrity claim is hollow on k8s (the docker path computes it spawner-side, outside the runtime's reach).Possible directions (needs a design pass):
.tale/and recompute hashes for the files it can see, orRefs: services/sandbox/src/backend/kubernetes/k8s-stage.ts, k8s-harvest.ts (readPrestage), k8s-protocol.ts (PRESTAGE_PATH).