Skip to content

Permissions

Devlish programs can declare their required permissions, resource boundaries, and allowed callers in a manifest header. When present, the VM enforces these declarations at runtime.

The manifest appears at the top of a .dvl file, before the program body:

Permissions:
Read files from "/inbox/"
Write files to "/receipts/"
HTTP requests to "api.example.com"
Filesystem operations on "/data/"
Call Gmail service
Boundaries:
No writes outside "/Users/admin/Dropbox/Financials/"
Callers:
Any MCP client
# Program body starts here
Read JSON from "/inbox/invoice.json" as invoice
Permission Syntax Effect
Read files Read files or Read files from "<path>" Allow file reads (optionally scoped to path prefix)
Write files Write files or Write files to "<path>" Allow file writes (optionally scoped)
HTTP requests HTTP requests or HTTP requests to "<domain>" Allow HTTP calls (optionally scoped to domain)
Filesystem Filesystem operations or Filesystem operations on "<path>" Allow copy, move, delete, mkdir, list, glob
Service calls Call <ServiceName> service Allow calls to a named external service

Scoped permissions (with from, to, or on) restrict effects to paths starting with the given prefix:

Permissions:
Read files from "/data/projects/"
Write files to "/output/"

Unscoped permissions allow all paths for that effect type:

Permissions:
Read files
Write files

When a manifest with permissions is present, the VM checks every effect against the declared permissions. An undeclared effect produces a “Permission denied” error:

Permissions:
Read files from "/inbox/"
# This succeeds:
Read JSON from "/inbox/data.json" as data
# This fails at runtime with "Permission denied":
Read JSON from "/secrets/keys.json" as keys

Programs without any manifest remain unrestricted for backward compatibility.

Boundaries add hard constraints regardless of other permissions:

Boundaries:
No writes outside "/Users/admin/Dropbox/Financials/"

Caller declarations are metadata for documentation and tooling. They compile into the bytecode package so clients can inspect them before invocation:

Callers:
Any MCP client

The manifest compiles into the .dvlc.json bytecode package:

{
"manifest": {
"permissions": [
{"kind": "read_file", "scope": "/inbox/"},
{"kind": "write_file", "scope": "/receipts/"},
{"kind": "http_request", "scope": "api.example.com"}
],
"boundaries": ["No writes outside \"/Users/admin/Dropbox/\""],
"callers": ["Any MCP client"]
}
}

This allows MCP clients, deployment systems, and code review tools to understand what a program does without executing it.

The permission system follows a “default open, opt-in restrict” model:

  • No manifest: program can do anything the host allows
  • With manifest: only declared effects are permitted
  • The devlish-runtime npm package rejects tools that declare HTTP or filesystem permissions at load time (sandboxed WASM execution)