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

CapabilityScoped 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-all disables the sandbox.
  • A process started with --allow-run does not inherit Deno's restrictions; do not let constrained code launch a shell or a new deno -A.
  • --allow-ffi loads 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

  1. Run with no grants and identify the denied operation.
  2. Add one scoped grant at a time.
  3. Use --no-prompt in CI.
  4. 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.

Type to search all documentation.