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

CODE
{
  "$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

MemberRequiredAccepted value
$schemanoexactly https://schemas.maelys.dev/mir-source/v2/schema.json
formatVersionyesinteger 2
filesystemyesdeny-default filesystem object
networkyesone network posture
processyesprocess-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:

MemberRequiredValuesDefault
accessyesread, write, deny—
pathyesone of the path forms below—
scopenoexact, treetree
missingnoerror, skiperror

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:

CODE
{ "special": "minimal-runtime" }

The complete workspace or temporary root:

CODE
{ "root": "workspace" }
{ "root": "temp" }

A path below a symbolic root:

CODE
{ "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

CODE
{ "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:

CODE
{ "mode": "none" }

Declare ambient host networking as an explicit requirement:

CODE
{ "mode": "direct" }

Require mediated connections to selected destinations:

CODE
{
  "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

CODE
{ "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.

CODE
many equivalent JSON spellings
             │
             ▼
normalize · sort · deduplicate
             │
             ▼
one canonical policy.mir