Deno Network Permission: Host‑Specific Scoping Without Wildcards
0 reputation · 12 May 2020, 07:38 UTC
0 reputation · 12 May 2020, 07:38 UTC
For workloads that run infrequently, limiting network access can reduce the attack surface and simplify compliance. However, Deno’s current permission system requires explicit host names for each --allow-net grant, which can become burdensome when the set of external services changes.
The runtime accepts only comma‑separated host strings (e.g., --allow-net=api.example.com,db.example.org) and offers no built‑in mechanism to match host patterns or subdomains. This lack of pattern support forces manual updates whenever a new domain is added or removed.
Given this limitation, I need to understand how to manage host lists efficiently and whether future releases will address pattern matching or integrate cost‑based throttling.
--allow-net when domains change frequently?35275 reputation · 12 May 2020, 16:25 UTC
Deno's --allow-net flag accepts only a comma-separated list of exact host[:port] entries. Wildcards, regex patterns, CIDR ranges, and subdomain matching are not supported in any released version (through 1.46). Every distinct hostname or IP must be enumerated explicitly. Permissions are evaluated at connect/listen time and cannot be modified after process start — changes require a restart.
--allow-net=api.example.com,db.example.org:5432 (comma-separated). Older versions require repeating the flag: --allow-net=a.com --allow-net=b.com.api.example.com does not cover example.com or cdn.example.com.host:443 restricts to that port; omitting the port allows any port on that host.--allow-net=[::1]:8080.localhost, 127.0.0.1, and [::1] are separate entries.Deno.permissions.query({ name: 'net', host: 'example.com' }) returns { state: 'granted' | 'denied' | 'prompt' }. This is read-only; it cannot grant new hosts.Keep a canonical source (JSON, YAML, or a small script) listing required hosts. Render it into the startup command during your build or deploy pipeline:
# Example: hosts.json
[
"api.payment.example.com:443",
"db.analytics.example.org:5432",
"metrics.internal:9090"
]
# Build step (bash)
HOSTS=$(jq -r 'join(",")' hosts.json)
den run --allow-net="$HOSTS" server.ts
This avoids manual editing of launch scripts and makes the list auditable in version control.
A small shell/JS wrapper can read the same source and invoke Deno, so developers don't maintain two copies:
#!/usr/bin/env bash
# run-dev.sh
HOSTS=$(jq -r 'join(",")' hosts.json)
exec deno run --allow-net="$HOSTS" --watch "$@"
Log the queried state for each expected host on boot to catch drift early:
for (const host of requiredHosts) {
const { state } = await Deno.permissions.query({ name: 'net', host });
console.log(`[net] ${host}: ${state}`);
}
Deno.permissions.request({ name: 'net', host: 'new.example.com' }) will prompt (if running interactively) but cannot succeed in non-interactive environments.The Deno team has not announced wildcard/regex support for --allow-net in public roadmaps. Discussions in the repo indicate a preference for explicit lists to keep the permission model simple and auditable. If pattern matching is a hard requirement, the current workaround is to generate the explicit list from your service-discovery or config source at deploy time (strategy #1 above).
What mechanism currently produces the list of external hosts your workload contacts? (e.g., static config, service discovery, DNS records, a dependency manifest) Knowing this determines whether strategy #1 can be fully automated or requires a custom generator.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 12 May 2020, 10:27 UTC
While automating the --allow-net list via CI/CD is the standard approach, it is important to clarify how Deno handles the resolution of those hostnames. Deno validates the permission against the hostname provided in the request, not the resulting IP address from DNS resolution.
This behavior introduces a specific edge case: if you allow api.example.com, Deno permits the connection regardless of which IP the DNS resolver returns for that domain. To achieve stricter network isolation, you must use IP literals:
--allow-net=api.example.com (Trusts DNS)--allow-net=192.0.2.1 (Bypasses DNS trust)For high-security environments, verifying the resolved IP against a known allow-list within the application logic—after the runtime permission check—is the only way to prevent DNS spoofing or hijacking from bypassing the --allow-net scope.