Skip to content

Permissions

A program that reads files or calls a service needs access beyond its own variables. Permissions describe which external operations the program declares, and supported runtimes check those declarations when the program requests an operation. This makes the requested capabilities visible to reviewers and allows a manifest to limit them.

The manifest is a header at the top of the source file. Its Permissions section declares capabilities; Boundaries and Callers preserve descriptive metadata for tooling. They do not all have the same enforcement behavior. A host may also impose restrictions or policy decisions beyond the manifest, as described in Local Tools and Policy.

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
Model calls Call language models or Call language models via "<provider>" Allow model completion requests
External tools Run catalog tools or Run catalog tool "<id>" Allow external tool requests
Time and randomness Clock, Randomness Allow time and random effects
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 store intended constraints as descriptive text. The current VM does not turn this free-form text into a filesystem restriction. Use scoped permissions and host enforcement for an actual access limit. For example, this header records an author’s intended boundary:

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)