The vercel firewall CLI now covers custom rules, IP blocks, Attack Mode, and DDoS-mitigation toggles through a staged publish model, which moves a security control that lived behind a dashboard button into the same pull-request workflow as the rest of your config. The command surface is broader than the changelog framing suggests, but three gaps persist: there is no CLI command for WAF Managed Rulesets or for editing rules across projects, the vercel.json rules subset drops most of the actions the CLI and dashboard offer, and rate-limit counters run per-region rather than globally.
What the vercel firewall CLI actually exposes
The vercel firewall command surfaces six operations plus a staging-and-publish workflow that mirrors how you already ship code: overview, rules, ip-blocks, system-bypass, attack-mode, and system-mitigations, with diff, publish, and discard handling staged changes (CLI reference). The crucial behavioral split is which changes need a publish. Custom rule and IP-block changes are staged as drafts and require an explicit publish to affect production, while system bypass, Attack Mode, and system mitigations apply immediately, with no publish step (CLI reference).
That split maps onto two operational modes: policy controls that should pass through review before they touch traffic, and panic switches that need to flip the moment an incident starts. The diff, publish, and discard triple turns rule changes into a reviewable artifact, the way you would inspect a diff before merging a branch. The trade is that the immediate-application controls bypass that review entirely. Attack Mode in particular is the knob you raise mid-incident to add challenge friction across a project, and because it applies on execution rather than on publish, a misconfigured toggle hits production the moment you press enter. Staging the wrong kind of control, or forgetting to publish the right kind, is the failure mode this design invites, and it is the one a team migrating off the dashboard is most likely to hit first.
The rules add action set is deny, challenge, log, bypass, rate_limit, and redirect, which matches the dashboard set (CLI reference). The --ai natural-language rule generator and the interactive wizard both require a TTY, so they will not run inside a CI pipeline or a non-interactive script; those contexts have to fall back to --condition flags or hand-built --json (CLI reference). Persistent time-based IP blocks on challenge, deny, and rate-limit are set with --duration values of 1m, 5m, 15m, 30m, or 1h; the dashboard exposes the same concept through a timeframe dropdown that defaults to one minute (CLI reference).
How CLI rate-limit counters behave across regions
Rate limiting via the CLI is full-featured, but it carries a per-region counter trap that the command surface does not flag. The available rate-limit keys are ip, ja4, and header:<name> (CLI reference), and the dashboard’s Enterprise tier additionally supports User Agent keys; the Token Bucket algorithm is Enterprise-only, leaving Hobby and Pro on Fixed Window (rate-limiting docs).
The structural caveat is that counters are tracked per-region, so traffic matching a given rate-limit key across multiple regions can exceed the configured limit for any single region (rate-limiting docs). A 100 req/min limit set through the CLI is effectively 100 per region, not 100 globally. For an app with a global edge audience, that means a single source can push multiples of the configured ceiling as long as its requests land in different regions. This is documented behavior, but it is not surfaced in the CLI’s own help text, and it is the kind of detail that surfaces during an actual abuse event rather than during configuration review.
The split between the CLI key set and the dashboard Enterprise key set matters for teams that have built abuse-response rules around User Agent strings. Those rules cannot be expressed through the CLI and have to stay in the dashboard, which breaks the goal of keeping every security rule under version control.
Is vercel.json enough for firewall-as-code?
If you hoped to commit firewall rules as JSON the way you already commit redirects, vercel.json gets you partway there and stops. Custom WAF rules defined through vercel.json routes support only challenge and deny; log, bypass, and redirect are explicitly not supported (custom-rules docs).
That makes vercel.json a strict subset of both the dashboard and the CLI. The CLI can express log, bypass, rate_limit, and redirect (CLI reference); vercel.json cannot. A team that has standardized on vercel.json for routing and security will find that the only rule actions available there are the two most disruptive ones, and that the observability-only log action, the one you reach for when you want to evaluate a rule before enforcing it, is missing entirely. Splitting policy between vercel.json for the enforceable subset and the CLI for everything else works, but it fragments the single declarative source that the file format was supposed to provide.
What still forces a dashboard visit?
Two control surfaces have no CLI command at all: configuring WAF Managed Rulesets and editing rules across more than one project. Vercel’s firewall runs in a fixed order: DDoS mitigation first, then WAF IP blocking, then WAF custom rules, then WAF Managed Rulesets (firewall overview). The CLI docs cover commands for IP blocks, custom rules, Attack Mode, and system mitigations, but they list no command for configuring WAF Managed Rulesets (firewall overview). Managed Rulesets run last in the pipeline, and the only documented way to tune them is the dashboard.
Because Managed Rulesets are dashboard-only, that layer of the firewall is not represented in your repository’s history. A teammate reviewing CLI-managed rules in a pull request will not see whether a Managed Ruleset was enabled, disabled, or tuned in the same window, because that change never produced a commit.
Every vercel firewall subcommand also operates against a single linked project, and the docs describe no flag for bulk-editing rules across multiple projects at once (CLI reference). For an org running the same security posture across dozens of projects, that leaves bulk edits as either a dashboard task or a scripted loop of per-project vercel firewall calls, neither of which is the declarative, reviewable state a CLI was supposed to provide.
When is the Terraform provider the better tool?
For teams that already run Terraform, vercel_firewall_config is the more honest infrastructure-as-code path, though it covers a different slice than the CLI. The Vercel Terraform provider added vercel_firewall_config, which manages custom rules and ip_rules, alongside a separate vercel_attack_challenge_mode resource; adoption is a terraform init -upgrade away (Terraform provider changelog).
The framing point that is easy to miss is that the Terraform support and the CLI firewall command are independent surfaces. Vercel’s visible June 2026 changelog lists a run of adjacent releases, including zero-config Node server deploys, CLI blob-URL signing, WebSocket public beta, a redesigned Workflows trace viewer, and the Terraform firewall resources, but it carries no dated “firewall CLI shipped” entry (Vercel changelog). Treating the CLI command and the Terraform provider as the same announcement is the easy mistake to make; they solve overlapping but distinct problems. Terraform gives you plan-time review and drift detection on a defined resource graph, while the CLI gives you an interactive, project-scoped tool that matches how an engineer debugs one project in real time.
Neither surface is a superset of the other. The CLI can drive Attack Mode and system mitigations interactively; the Terraform provider models custom rules, IP rules, and attack-challenge mode as declared resources. Managed Rulesets and bulk edits are absent from both, so even teams that adopt Terraform should not expect to retire the dashboard entirely.
What plan limits let a CLI-managed rule do
What a CLI-managed rule can actually do is capped by your plan, and the caps are uneven. Hobby allows 1 rate-limit rule per project, 3 total custom rules, Fixed Window rate limiting, a window range of 10 seconds to 10 minutes, and 1 million included requests; Pro raises the custom-rule cap to 40; Enterprise goes to 1,000 rules, adds Token Bucket, and extends windows up to 1 hour (rate-limiting docs). Overage across the tiers is $0.50 per 1,000,000 allowed requests (rate-limiting docs).
| Plan | Custom-rule cap | Rate-limit algorithm |
|---|---|---|
| Hobby | 3 | Fixed Window |
| Pro | 40 | Fixed Window |
| Enterprise | 1,000 | Token Bucket (and Fixed Window) |
The practical implication is that the CLI command set looks identical across plans, but the rule it lets you write does not. A Hobby project that needs a second rate-limit rule, or a window outside the 10-second-to-10-minute band, cannot express that policy through the CLI no matter how complete the command looks, because the constraint is plan-side rather than tool-side. The rate-limiting docs spell out Hobby’s window and included-request figures in detail but do not enumerate Pro’s or Enterprise’s on the same page, so expect to cross-reference the plan matrix rather than reading the limits off one table.
The overage model is metered on allowed requests rather than blocked requests, which makes a too-permissive rate-limit rule the expensive failure mode, not a too-strict one. A rule that lets traffic through quietly accrues charges; a rule that blocks aggressively does not. Pair that with the per-region counter behavior and the picture is that the cheapest misconfiguration is the one nobody notices, which is exactly the misconfiguration a CLI staged as a draft and then forgotten can produce.
For most teams the realistic setup is layered: vercel.json for the enforceable challenge and deny rules that belong next to the routing config, the CLI for interactive tuning and incident response on a single project, Terraform where drift detection across a resource graph is worth the overhead, and the dashboard for Managed Rulesets, bulk edits, and the Enterprise-only rate-limit keys. The CLI closes real ground on firewall-as-code. It does not close enough to make the dashboard optional.
Frequently Asked Questions
Can vercel firewall run inside a CI pipeline, or is it interactive-only?
It works in CI, but you must skip the TTY-only paths. The --ai generator and the interactive wizard require a terminal, so automated jobs should build rules with --condition flags or raw --json. Because every subcommand targets one linked project, a CI job that needs to update many projects must loop over them, and for immediate-application controls such as Attack Mode the CI log becomes the only reviewable artifact.
How does the new CLI firewall command relate to the Terraform provider’s firewall resources?
They are separate releases. Vercel’s June 2026 changelog mentions the Terraform vercel_firewall_config and vercel_attack_challenge_mode resources alongside unrelated items such as custom OIDC token audiences, Claude Design deploys, and Sakana Fugu Ultra on the AI Gateway, yet it carries no dated “firewall CLI shipped” entry. Terraform fits plan-time review and drift detection; the CLI fits single-project incident response where Attack Mode takes effect immediately.
What is the most expensive rate-limit misconfiguration to watch for in the CLI?
A cap that is too permissive. Overage is billed at $0.50 per million allowed requests, not blocked requests, and the counters are per-region, so a distributed source can exceed the limit by routing traffic through multiple regions. Monitor allowed-request volume and regional distribution rather than relying on the rule count alone.
Which firewall controls still cannot be stored in version control even with both CLI and Terraform?
WAF Managed Rulesets, multi-project edits, and Enterprise-only rate-limit keys such as User Agent are absent from both surfaces. That means any policy using User Agent fingerprinting or Managed Ruleset tuning stays dashboard-only and will not appear in a pull request diff, despite much coverage framing the Terraform release as ‘firewall-as-code’.