Skip to content

feat(sandbox): virtual-by-default capability model (sandbox:/env:)#372

Open
davydog187 wants to merge 1 commit into
feat/virtual-vfsfrom
feat/virtual-sandbox-api
Open

feat(sandbox): virtual-by-default capability model (sandbox:/env:)#372
davydog187 wants to merge 1 commit into
feat/virtual-vfsfrom
feat/virtual-sandbox-api

Conversation

@davydog187

Copy link
Copy Markdown
Contributor

Virtual-by-default, PR 2/4 — capability model

Stacked on #371 (the vendored Lua.VFS). Review/merge that first; this PR's base is feat/virtual-vfs and retargets to main after.

Replaces the per-path deny-list with a single virtual ↔ host toggle. The default VM is now virtual and sandboxed; opting out installs the host implementations.

API

Lua.new()                                  # virtual + sandboxed (default)
Lua.new(env: [{"HOME", "/app"}])           # inject env for os.getenv
|> Lua.write_file("/main.lua", "return 1")  # seed the virtual FS
|> Lua.put_dep("greet", "return 'hi'")      # seed a require-able module
Lua.new(sandbox: false)                    # host os/io/loaders (real machine)

Mechanics

  • Whole-implementation swap at install time (no per-call mode branch): os installs getenv/tmpname/remove/rename/execute as virtual or host variants based on sandbox:.
  • os gains real execute/remove/rename. Sandboxed remove/rename/tmpname use the VFS; os.execute is denied. Host variants touch the real disk/shell.
  • require/loadfile/dofile resolve from the VFS (anchored at /lua/deps) when sandboxed, real disk under sandbox: false. load/loadstring compile strings in-memory in both modes.
  • Added Lua.write_file/3, Lua.put_dep/3, Lua.read_file/2.
  • io is now an explicit library (stubbed pending full virtualization in PR 3/4), preserving the sandboxed table-of-functions shape (io_stub_test green).

Breaking changes

  • Removed Lua.new(sandboxed:/exclude:) and Lua.sandbox/2. A deprecation shim accepts the legacy options for one minor (sandboxed: []sandbox: false) with an IO.warn.
  • Default os.getenv returns injected/nil instead of raising; require/loadfile/dofile now work against the VFS instead of being denied.
  • Full migration notes + the README/guide narrative rewrite land in PR 4/4 (docs).

Verification

  • mix test: 2606 passed (+16 new in test/lua/sandbox_test.exs), 0 failures
  • mix test --only lua53: 20/9/0 (no regression)
  • mix format + mix compile --warnings-as-errors: clean
  • Re-pointed ~30 sandboxed: [] test sites to sandbox: false (behavior-identical)

Replace the per-path deny-list with a single virtual/host toggle:

- Lua.new(sandbox: true) (default) installs the virtual os/io/loader
  implementations; sandbox: false installs the host ones. The choice is made
  once at install time (no per-call mode branch).
- Lua.new(env: [...]) injects env values the sandboxed os.getenv reads; the
  host environment is never touched in the default sandbox.
- os gains real execute/remove/rename; sandboxed remove/rename/tmpname operate
  on the VFS, host variants touch real disk. os.execute is denied when sandboxed.
- require/loadfile/dofile resolve from the VFS (anchored at /lua/deps) when
  sandboxed, real disk under sandbox: false. load/loadstring compile strings
  in-memory in both modes.
- Add Lua.write_file/3, put_dep/3, read_file/2 to seed and harvest the VFS.
- Remove @default_sandbox, the :sandboxed/:exclude options, and Lua.sandbox/2;
  a deprecation shim maps the legacy options to :sandbox for one minor.
- io is installed as an explicit library (stubbed for now; full virtualization
  follows) preserving the sandboxed table-of-functions shape.

BREAKING: see CHANGELOG (docs rewrite follows in a later PR).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant