# Permissions and security boundaries

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.

```bash
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](https://docs.deno.com/runtime/fundamentals/security/) and [Permissions reference](https://docs.deno.com/runtime/reference/permissions/).
