Grant an isolated child what it may reach - #84
Merged
Merged
Conversation
Isolated mode bounded what Python could consume but nothing it could reach: the child held every authority the node's user held. The caps option names its directories, environment and addresses, and refuses the rest. The model and its vocabulary come from erlang_wasm's WASI implementation, so a grant means the same thing in both. It is a cooperative policy over Python, not a boundary: built on an audit hook, it binds Python and not a C extension, and covers only what CPython announces. The guide says what holds and what does not, and names the kernel work that would change the answer.
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.
Isolated mode bounded what Python could consume: memory, CPU, time, a crash. It bounded nothing it could reach. The child ran as the node's user with the node's environment, could read and write every file that user could, dial anywhere, spawn processes, and truncate the shared memory regions it was handed, which turns the mapping the VM holds into a
SIGBUS.capsnames what a child may reach and refuses the rest: directories with an access level, environment variables, network rules. Leaving a key out grants none of it, and omitting the option leaves today's behaviour alone.{ok, Ctx} = py_context:new(#{ mode => isolated, caps => #{dirs => [{"/srv/models", read}, {"/var/data/job42", write}], env => #{<<"MODEL_DIR">> => <<"/srv/models">>}, net => #{connect => [{tcp, <<"10.0.0.0/8">>, {5432, 5432}}], resolve => deny}}}).The model, the option shape, the refusal semantics and the test list come from erlang_wasm's WASI implementation rather than being invented, so a grant means the same thing in both: rules name addresses and never host names, resolution is its own capability, binding is checked against
listenand notconnect, IPv4-mapped addresses are folded before matching, and a malformed rule is an error where the grant is written rather than a connection refused later. Path containment is that project's native backend, which needed a C NIF there because Erlang has noopenatand needs none here because Python has one.It is a policy over Python, not a kernel boundary, and the guide says so in those words: a C extension calling
open(2)is not stopped, nor is a thread that swaps a path between the check and the kernel's resolution. Landlock takes the same table and is the next step.