Permissions and security boundaries
Apply least privilege to files, network, environment, subprocesses, FFI, and dynamic imports
Deno denies sensitive I/O by default. Permissions apply to an execution thread; they are not independent per dependency.
Common permissions
| Capability | Scoped example |
|---|---|
| Read files | --allow-read=./config,./public |
| Write files | --allow-write=./data |
| Network | --allow-net=api.example.com:443 |
| Environment | --allow-env=PORT,API_KEY |
| Subprocess | --allow-run=git |
| Dynamic imports | --allow-import=jsr.io |
--deny-* takes precedence over its matching --allow-*, so broad grants can exclude specific paths or hosts. Use --no-prompt in non-interactive environments so missing grants fail immediately.
deno run \
--allow-net=api.example.com:443 \
--allow-env=API_KEY \
--no-prompt main.ts
High-risk grants
-A/--allow-alldisables the sandbox.- A process started with
--allow-rundoes not inherit Deno's restrictions; do not let constrained code launch a shell or a newdeno -A. --allow-ffiloads native machine code whose system calls are outside the JavaScript permission layer.- Loading the initial static module graph and runtime I/O are separate boundaries. Successful imports do not grant application network access.
Verification checklist
- Run with no grants and identify the denied operation.
- Add one scoped grant at a time.
- Use
--no-promptin CI. - Use OS or container isolation for tools, plugins, and user code; do not rely on Deno permissions alone.
Official references: Security and permissions and Permissions reference.