Learn the model
JSON manifest
The complete human-facing language for filesystem, network and process boundaries.The JSON manifest is the human-facing source format for a resolved sandbox decision. It is intentionally small, strict and fail-closed: required sections must be present, duplicate or unknown keys are rejected, and invalid values never fall back to defaults that widen access.
Complete shape
{
"$schema": "https://schemas.maelys.dev/mir-source/v2/schema.json",
"formatVersion": 2,
"filesystem": {
"default": "deny",
"rules": [
{
"access": "write",
"path": { "root": "workspace", "relative": "build" },
"scope": "tree",
"missing": "skip"
}
]
},
"network": {
"mode": "mediated",
"allow": [
{ "protocol": "tcp", "host": "github.com", "port": 443 }
]
},
"process": { "treeConfinement": "required" }
}Top-level members
| Member | Required | Accepted value |
|---|---|---|
$schema | no | exactly https://schemas.maelys.dev/mir-source/v2/schema.json |
formatVersion | yes | integer 2 |
filesystem | yes | deny-default filesystem object |
network | yes | one network posture |
process | yes | process-tree requirement |
Object member order and whitespace do not matter. Every object rejects duplicate and unknown members. Input is limited to 1 MiB and nesting depth to 32.
Filesystem policy
filesystem.default must be deny. rules is required and may be empty.
Each rule accepts:
| Member | Required | Values | Default |
|---|---|---|---|
access | yes | read, write, deny | — |
path | yes | one of the path forms below | — |
scope | no | exact, tree | tree |
missing | no | error, skip | error |
exact addresses only the named entry. tree addresses the entry and descendants. Write implies read. Duplicate targets are removed and conflicts resolve to the narrowest result: deny > write > read.
Portable path forms
Minimal files required to load and start the executable:
{ "special": "minimal-runtime" }The complete workspace or temporary root:
{ "root": "workspace" }
{ "root": "temp" }A path below a symbolic root:
{ "root": "workspace", "relative": "build/output" }root accepts only workspace or temp. relative must not begin with /; repeated separators and . segments are normalized, while every .. segment is rejected.
Absolute host paths
{ "absolute": "/opt/company/toolchain" }An absolute path cannot be combined with root, relative or special. Use it only in trusted, host-specific policy because it makes the decision dependent on that path existing on the target machine.
Missing paths
missing: "error" requires the path to exist during resolution. missing: "skip" permits only “not found” and “not a directory” to remove the rule. Permission errors, symlink loops and all other failures remain hard errors—even for a deny rule—because silently losing a deny could widen access.
Network policy
Disable networking:
{ "mode": "none" }Declare ambient host networking as an explicit requirement:
{ "mode": "direct" }Require mediated connections to selected destinations:
{
"mode": "mediated",
"allow": [
{ "protocol": "tcp", "host": "registry.npmjs.org", "port": 443 }
]
}allow is required and non-empty only for mediated; it is forbidden for none and direct. Version 2 supports TCP, DNS hostnames and ports 1..65535. Hostnames are validated, converted to lowercase, sorted and deduplicated. IP literals and wildcard domains are not accepted.
Process policy
{ "treeConfinement": "required" }Use required when children must inherit the boundary. disabled means this guarantee is not requested; it does not grant a process permission or disable all sandboxing.
What compilation changes
Compilation normalizes paths and hostnames, sorts records, removes duplicates and applies conflict precedence. It never resolves symbolic roots to host paths. The output is canonical MIR v2; the original JSON spelling and member order are not part of policy identity.
many equivalent JSON spellings
│
▼
normalize · sort · deduplicate
│
▼
one canonical policy.mir