feat(smolmachines): patch smolvm state DB to actually enforce per-bottle allowlist
Earlier commit framed this PR as "infrastructure landed, TSI enforcement blocked on upstream smolvm 0.8.0." Found a clean workaround that lets us enforce now. Smolvm persists each machine's config (including `allowed_cidrs`) as a JSON BLOB in `~/Library/Application Support/smolvm/server/smolvm.db`, `vms.data`. `machine create --allow-cidr X/32` silently writes `allowed_cidrs: null` to that row when combined with `--from`, but smolvm reads the row at `machine start` — so patching the row between create and start sets the allowlist for real. New `loopback_alias.force_allowlist(machine_name, cidrs)` opens the SQLite DB, JSON-decodes the row, sets `allowed_cidrs`, and writes back as BLOB (Text type silently corrupts smolvm's later reads). launch.py calls it immediately after `machine_create` and before `machine_start`. Verified end-to-end on macOS / Docker Desktop: VM allowlist after start: ["127.0.0.16/32"] VM → 127.0.0.1:3000 → BLOCKED (Permission denied) VM → 8.8.8.8:53 → BLOCKED (Permission denied) VM → 127.0.0.16:<bundle> → CONNECTED The DB-patch hack is correct only because smolvm reads `allowed_cidrs` from the row at start time (not derived in- process). When upstream honors `--allow-cidr` with `--from`, the call becomes redundant — drop the call and the workaround is gone. Tests: 4 new for `force_allowlist` (BLOB round-trip; Linux no-op; missing DB; missing row). Total 593 unit tests pass. README + PRD updated to reflect the fix landed (no longer "infrastructure pending upstream"). gitea#75 can close. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -611,21 +611,31 @@ PRD 0024's bundle image is a prerequisite — this PRD assumes
|
||||
bound to macOS's loopback** — postgres, dev servers, other
|
||||
bottles' published ports, mDNSResponder, etc.
|
||||
|
||||
**Attempted fix + upstream block (`smolmachines-loopback-
|
||||
alias-scoping` branch).** Allocate each bottle a unique
|
||||
loopback alias (`127.0.0.16` .. `127.0.0.31`), bind bundle
|
||||
port-forwards to it, set TSI's `--allow-cidr` to that /32.
|
||||
Verified empirically that `smolvm 0.8.0 machine create --from
|
||||
<smolmachine> --net --allow-cidr X/32` **silently drops the
|
||||
allowlist** — `agent.config.json` shows `allowed_cidrs:null`
|
||||
and the VM reaches all of `127.0.0.0/8` regardless of the
|
||||
flag. Workarounds tried: `machine update --allow-cidr`
|
||||
doesn't exist; stop-edit-`agent.config.json`-restart fails
|
||||
(file is removed on stop); `--smolfile` is mutually exclusive
|
||||
with `--from`. Alias-allocation infrastructure is in place
|
||||
so the day smolvm honors `--allow-cidr` with `--from`, the
|
||||
scoping starts working. Until then the agent can reach the
|
||||
whole host loopback. Tracked in gitea issue #75.
|
||||
**Fix + smolvm 0.8.0 workaround.** Allocate each bottle a
|
||||
unique loopback alias (`127.0.0.16` .. `127.0.0.31`), bind
|
||||
bundle port-forwards to it, set TSI's allowlist to that
|
||||
alias's /32. The agent can only reach its own bundle; other
|
||||
bottles' ports, host loopback services, and the internet are
|
||||
all denied.
|
||||
|
||||
Smolvm 0.8.0 silently drops `--allow-cidr` when combined
|
||||
with `--from <smolmachine>` (verified empirically:
|
||||
`agent.config.json` shows `allowed_cidrs:null` despite the
|
||||
flag). The launcher patches smolvm's persistent state DB
|
||||
(`~/Library/Application Support/smolvm/server/smolvm.db`,
|
||||
`vms.data` BLOB) between `machine create` and `machine
|
||||
start` to set the allowlist directly. Smolvm reads the DB
|
||||
at start, so TSI enforces. Tested end-to-end: VM → `127.0.0.1`
|
||||
= "Permission denied"; VM → `<alias>:<bundle-port>` =
|
||||
connects.
|
||||
|
||||
Other paths tried that didn't work: `machine update
|
||||
--allow-cidr` doesn't exist; stop-edit-`agent.config.json`-
|
||||
restart fails (file removed on stop); `--smolfile` mutually
|
||||
exclusive with `--from`; `--image localhost:<port>/...` fails
|
||||
because smolvm's pull agent can't reach host loopback during
|
||||
pull. When smolvm honors `--allow-cidr` with `--from`
|
||||
upstream, the DB patch becomes redundant and can be removed.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
Reference in New Issue
Block a user