Repository navigation
isb 3.1.0: isbx runs any CLI in a sandbox; egress waits for DNS and gains presets - #68
Merged
Merged
Conversation
…c -e KEY - A fresh or restarted egress sandbox waits until its guest resolves an allowed name: the first command used to run before /etc/resolv.conf existed and failed DNS. - `@npm`, `@pypi`, `@crates`, `@go`, `@github`, `@mise`, `@public` in an allow list stand for those hosts. - `*` / `*:PORT` allows any public name on that port; `dns: all` makes the bridge DNS answer every name with the proxy address, so unlisted names reach the proxy and are refused there. - The proxy records each host:port it allowed or denied per sandbox under <state>/egress/names/<network>. - `isb exec -e KEY` passes the caller's $KEY, keeping a value out of argv. - prune_missing_path moves to sandbox/prune.rs. Claude-Session: https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ
`isbx CMD` (the isb binary under that name) is `isb x run CMD`: the project (the git repository you are in, else the directory) is mounted at its own path in a kept dev-base sandbox, .git read-only, as uid 1000, with a shared package cache volume. `$HOME`, its ancestors and credential and host directories are refused as roots. The project sandbox's egress list only grows: it starts closed (DNS answers, the proxy refuses and records), and a package manager's first run adds its registry, GitHub releases and mise's hosts once. --net none and --net public are sandboxes of their own. After a failed run isbx names the hosts the proxy refused. The proxy marks the policy it applied, so isbx waits for a widened list to reach it before the command's first connection. Also: `isb x ls`, `isb x stop`, `isb x gc --idle/--missing`; output helpers move to src/bin/isb/output.rs. Claude-Session: https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ
`isb x install NAME --from npm:|pypi:|cargo:|go:|script:URL|sh:LINE` installs into a new sandbox generation (x-NAME-N) as dev, finds the programs the install added, and writes a shim for each in $XDG_DATA_HOME/isb/x/bin. `isb x update` builds the next generation and switches only once it works. A tool mounts the project it runs in (hot plugged, earlier projects detached unless a live run uses them), a fixed directory, or nothing. Secrets go on the wire as placeholders, or with --secret-env are read with `op read` per run and sent in the exec request. --learn installs with any public host open and keeps the hosts used. Also `isb x tool`, `rm`, `shim` (plain host commands through isbx), `allow`, `deny`, `doctor`; `isbx NAME` finds an installed tool. A VM defaults to images:ubuntu/24.04/cloud. Docs: docs/guides/isbx.md, the CLI and compose references, the egress guide (presets, `*`, `dns: all`, readiness, the name record), the security model, SKILL.md and the daemon's cli guide topic. Claude-Session: https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ
… tests - isb serve stops (never deletes) isbx sandboxes outside orgs that no run has used for 30 minutes (`isbx.idle` sets another time), skipping one a run is going in. - Every isbx sandbox waits until uid 1000 exists (a cloud image makes it with cloud-init after starting). - `isb x doctor` checks net.ipv4.ip_unprivileged_port_start, which the proxy needs at 80 or lower to listen on 443 and 80. - tests/x.rs (ISB_INTEGRATION=1): a one-off run's paths, exit codes, stdin, ownership, read-only .git, env filtering, refused roots, the first command's DNS; a tool's install, shim, update, failed update and removal. Claude-Session: https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ
Claude-Session: https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ
…STSEC-2026-0346..0349, 0381, 0382) Claude-Session: https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ
…crypto-bigint 0.5 ignored ruzstd 0.9.1 bounds a block's decoded size, so a crafted .zst can no longer exhaust memory in a backup restore; ctutils 0.4.5 makes argon2's comparisons branch-free. Both need Rust 1.87. crypto-bigint 0.5 comes only through age's P-256 recipients, which isb never uses, and no age release takes the fix. is_multiple_of replaces the modulo checks clippy flags at the new MSRV. Claude-Session: https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ
…r's target (macOS /var/lib) Claude-Session: https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ
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.
isb x(andisbx, the same binary under another name) runs any CLI in an isb sandbox instead of on the host.One-off runs:
isbx npm installruns in a kept sandbox for the project. The project is mounted at its own path,.gitis read-only, the command runs as uid 1000, and only display variables pass through (-e KEYnames another). The network starts closed. A package manager's first run opens its registry preset, and a refused host is named after the failure.Installed tools:
isb x install NAME --from npm:|pypi:|cargo:|go:|script:URL|sh:LINEputs the CLI in a sandbox of its own and adds host shims in~/.local/share/isb/x/bin. Alsoupdate(blue/green),rm,shim,allow/deny,ls,stop,gcanddoctor.--learninstalls with public hosts open and keeps only the hosts the install used.Egress, for every sandbox: a new egress sandbox's first command no longer fails DNS. Adds presets (
@npm,@pypi,@crates,@go,@github,@mise,@public),*anddns: all. The proxy records the hosts it allowed and refused.isb exec -e KEYtakes the value from the host environment, so it never appears in host argv.isb servestops isbx sandboxes that have been idle for 30 minutes.Dependencies: MSRV is now 1.87. Updates rustls 0.23.46, rustls-webpki 0.103.16, webpki-roots 1.0.11, ruzstd 0.9.1 and ctutils 0.4.5 for this week's RustSec advisories. crypto-bigint 0.5 is ignored, with a reason: it only reaches isb through age's P-256 recipients, which isb doesn't use.
Docs:
docs/guides/isbx.md, plus updates to the CLI reference, the egress guide, the security concepts page and SKILL.md.Tests:
scripts/check.shpasses.tests/x.rs(ISB_INTEGRATION) passes in a preview VM running its ownisb serve.https://claude.ai/code/session_0193FJYdMzGpzZb8q3KQMDgJ