Repository navigation
fix(sandbox,danger): residual hardening after sandbox networks - #335
Merged
Merged
Conversation
classifyPathLexical strips the /private prefix from the target path, but accountHomes compared it with $HOME as spelled. With HOME under /private/var or /private/tmp (macOS physical paths), writes to ~/.ssh, shell rc files and odek's trust anchors classified as local_write instead of system_write. Compare against the stripped spelling too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tworks by ID The setup-time grant check returned early when no approval had been recorded in the process, so a surface that reached setupSandbox without the approval gate would attach project-requested networks unchecked. The sandbox config now carries the project's own network request, and setup refuses those networks unless an approval with their IDs was recorded (ODEK_APPROVE_PROJECT_SANDBOX=1 still approves). Sub-agents narrowed networks by name only, so a network recreated under the same name between the parent's and the child's start was attached under its new ID. The parent now stamps the IDs of the networks it attached into the task file, and the child refuses any network that no longer carries one of them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestMain swaps HOME for a fixture directory, which hides the docker CLI context Docker Desktop relies on, so every Docker-gated test skipped as "Docker daemon unavailable" on macOS. Pin the active context's endpoint as DOCKER_HOST before the swap (an explicit DOCKER_HOST or DOCKER_CONTEXT is left alone). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestRED_RtOps_KeyFDStrictParse passed r.Fd() of a live pipe to readKeyFromInheritedFD, which closes the descriptor it is handed. r's finalizer later closed the same number again after the kernel had reused it, typically for the directory fd os.RemoveAll was walking in a parallel test, which then failed with "unlinkat: bad file descriptor". Pass a dup, close r explicitly, and pin the rule for every fd-handoff test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
odek | 0f08e48 | Commit Preview URL Branch Preview URL |
Oct 25 2026, 01:46 PM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up hardening for the sandbox network support in v2.36.0, plus a classifier fix and a test-suite flake fix found along the way.
Changes
Classifier: a
$HOMEspelled through/privateis protected again (internal/danger)/privateprefix from macOS paths (/private/var/…→/var/…) before comparing, but compared them with$HOMEas spelled.HOMEunder/private/varor/private/tmp, writes to~/.sshkeys, shell rc files and odek's~/.odektrust anchors classifiedlocal_writeinstead ofsystem_write.accountHomesnow also compares the stripped spelling. It only adds home candidates, so no verdict can go down.Project-requested networks need a recorded approval (
cmd/odek)ODEK_APPROVE_PROJECT_SANDBOX=1still approves.Sub-agents are pinned to their parent's network IDs
Docker-gated tests run on Docker Desktop
TestMainswapsHOMEfor a fixture directory, which hides the docker CLI context Docker Desktop uses, so every Docker-gated test skipped as "Docker daemon unavailable".TestMainnow pins the active context's endpoint asDOCKER_HOSTbefore the swap. An explicitDOCKER_HOSTorDOCKER_CONTEXTis left alone.Intermittent
TempDir RemoveAll cleanup: unlinkat: bad file descriptorfailuresTestRED_RtOps_KeyFDStrictParsehanded a live pipe's descriptor toreadKeyFromInheritedFD, which closes the descriptor it is given.os.RemoveAllwas walking in a parallel test.Docs:
SECURITY.md,SANDBOXING.md,AGENTS.md.Testing
TestRED_*tests for each fix, including a revert check for each.go test -count=1for./cmd/odek,./internal/sandbox,./internal/configand./internal/danger(with a non-rootHOME) pass../cmd/odekwith coverage was run three times in a row with nobad file descriptorfailures. Before the fix it showed up in most full runs on this machine.DOCKER_HOSTset:ODEK_E2E=true go test ./cmd/odek -run TestE2E_Sandbox, 5 tests run and pass (all 5 skipped before).go test -raceon./cmd/odek,./internal/sandboxand./internal/configpasses.golangci-lintreports 0 issues andgofmtis clean.cmd/odek78.9%,internal/danger93.3%,internal/sandbox93.7%). Changed executable lines incmd/odek: 71/76. The rest issetupSandboxwiring that needs a live daemon; it's pinned by a source test and exercised by the Docker E2E.🤖 Generated with Claude Code