RouteWarden CLI (rwarden)
rwarden is a lightweight developer CLI for testing path rules, verifying RouteWarden configs offline, and outputting the official JSON Schema.
Installation
1. One-Liner Script (macOS & Linux)
Download and install the latest pre-compiled release binary automatically:
curl -fsSL https://routewarden.github.io/cli/install.sh | bashTo install without sudo into a user directory like ~/.local/bin:
curl -fsSL https://routewarden.github.io/cli/install.sh | INSTALL_DIR=$HOME/.local/bin bash2. Pre-built Release Binaries
Download standalone, statically compiled binaries for Linux, macOS, and Windows directly from GitHub Releases:
| Platform | Architecture | Archive |
|---|---|---|
| macOS | Apple Silicon (arm64) | rwarden_2.1.0_darwin_arm64.tar.gz |
| macOS | Intel (amd64) | rwarden_2.1.0_darwin_amd64.tar.gz |
| Linux | 64-bit (amd64) | rwarden_2.1.0_linux_amd64.tar.gz |
| Linux | ARM64 (arm64) | rwarden_2.1.0_linux_arm64.tar.gz |
| Windows | 64-bit (amd64) | rwarden_2.1.0_windows_amd64.zip |
macOS Gatekeeper Notice
If macOS displays "Apple could not verify “rwarden” is free of malware..." when running a downloaded binary, macOS Gatekeeper has placed it in quarantine. You can remove the quarantine flag using:
xattr -d com.apple.quarantine $(which rwarden)
# Or for a downloaded binary directly:
xattr -d com.apple.quarantine rwardenAlternatively, navigate to System Settings > Privacy & Security and click "Allow Anyway" next to the rwarden prompt.
All downloads and checksums are verified on the Releases Page.
3. Container Image (Docker / CI/CD)
Run rwarden via container without installing any local binaries:
# Validate configuration file directly
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest validate --config /routewarden.json
# Test path interactively
docker run --rm ghcr.io/routewarden/cli:latest test --path "/.env"4. From Source (Go)
git clone https://github.com/routewarden/cli.git
cd cli
go build -o /usr/local/bin/rwarden .Verify installation:
rwarden version
# rwarden version 2.1.0docker run --rm ghcr.io/routewarden/cli:latest version
# rwarden version 2.1.0Uninstallation
rwarden is a single self-contained binary with no background background services or external runtime dependencies. To completely remove it from your machine:
# If installed system-wide (default):
sudo rm -f /usr/local/bin/rwarden
# If installed in user directory:
rm -f ~/.local/bin/rwardenCommands
1. Test URL Paths & Queries (test)
Simulate candidate path extraction, normalization, and pattern matching on an arbitrary path without starting Traefik, Caddy, or NGINX:
# Test a sensitive file path (positional or --path)
rwarden test /.env
rwarden test --path "/.env"
# Test double URL encoding anti-evasion
rwarden test "/static/%252e%252e/.env"
# Test query string inspection (-q or --query)
rwarden test -q "file=secret.conf" /search
# Test custom HTTP methods (-X, -m, or --method)
rwarden test -X POST /wp-config.php
# Test custom HTTP headers (-H or --header, repeatable)
rwarden test -H "X-Forwarded-Uri: /.env" /api
# Test against a custom RouteWarden config file (-c or --config)
rwarden test -c routewarden.json /admin/dashboard
# Test client IP whitelisting
rwarden test -c routewarden.json --ip "10.0.0.1" /admin
# Pipe configuration via stdin
cat routewarden.json | rwarden test -c - /admin# Test a sensitive path
docker run --rm ghcr.io/routewarden/cli:latest test /.env
# Test double URL encoding anti-evasion
docker run --rm ghcr.io/routewarden/cli:latest test "/static/%252e%252e/.env"
# Test evasion via query inspection
docker run --rm ghcr.io/routewarden/cli:latest test -q "file=secret.conf" /search
# Test against custom config file
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest test -c /routewarden.json --ip "10.0.0.1" /admin| Flag | Type | Default | Description |
|---|---|---|---|
[path], --path | string | "" | Request path to evaluate (e.g. /.env or /api/v1) |
-c, --config | string | "" | Optional path to routewarden.json (or - for stdin) |
-q, --query | string | "" | Optional request query string to evaluate |
-X, -m, --method | string | "GET" | HTTP method (e.g. GET, POST, HEAD) |
-H, --header | string | "" | Optional header in Key:Value format to test (repeatable) |
--ip | string | "" | Optional client IP address to evaluate against allowedIps |
--check-query | bool | true | Enable or disable query string inspection |
Example Output:
🔍 Testing: GET /static/%252e%252e/.env
Candidate paths extracted (2):
- /static/%252e%252e/.env
- /.env
Result: 🛑 BLOCKED (HTTP Status 403)
Reason: block_pattern_match
Target: /.env
Pattern: (?i)\.env2. Validate Configurations (validate)
Validate a RouteWarden JSON configuration file before deploying:
# Validate routewarden.json directly (positional or --config)
rwarden validate routewarden.json
rwarden validate -c routewarden.json
# Auto-detects routewarden.json in current directory if omitted
rwarden validate
# Validate piped config via stdin
cat routewarden.json | rwarden validate# Validate mounted config file
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest validate /routewarden.json| Flag | Type | Default | Description |
|---|---|---|---|
[config], -c, --config | string | "routewarden.json" | Path to RouteWarden JSON config file (or - for stdin) |
Example Output:
✓ Configuration routewarden.json is VALID.
- Enabled: true
- Default patterns enabled: true
- Default allow patterns enabled: true
- Methods: [GET]
- Custom block patterns: 2
- Monitored headers: [X-Forwarded-Uri]Exits with non-zero status code if invalid regexes, CIDRs, or configuration options are encountered, making it ideal for CI/CD pipelines.
3. Output JSON Schema (schema)
Print the official RouteWarden configuration JSON Schema:
rwarden schema > routewarden.schema.jsondocker run --rm ghcr.io/routewarden/cli:latest schema > routewarden.schema.json4. Generate Gateway Configs (generate)
Convert routewarden.json into native gateway configuration — no manual translation required. Flags and positional arguments may be used interchangeably:
# Traefik: dynamic YAML middleware definition
rwarden generate traefik-yaml [routewarden.json] > dynamic.yml
rwarden generate yaml > dynamic.yml
# Traefik: dynamic TOML middleware definition
rwarden generate traefik-toml [routewarden.json] > dynamic.toml
rwarden generate toml > dynamic.toml
# Traefik: Docker Compose labels block
rwarden generate traefik-labels [routewarden.json]
rwarden generate compose
# Caddy: Caddyfile directive block
rwarden generate caddy [routewarden.json]
# NGINX / OpenResty: Lua init table for nginx.conf
rwarden generate nginx [routewarden.json]# Traefik: output as dynamic YAML middleware definition
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest generate traefik-yaml /routewarden.json > dynamic.yml
# Traefik: output as dynamic TOML middleware definition
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest generate traefik-toml /routewarden.json > dynamic.toml
# Traefik: output as Docker Compose labels block
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest generate traefik-labels /routewarden.json
# Caddy: output as Caddyfile directive block
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest generate caddy /routewarden.json
# NGINX / OpenResty: output as Lua init table for nginx.conf
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest generate nginx /routewarden.json| Flag | Type | Default | Description |
|---|---|---|---|
<target>, -t, --target | string | "" | Target gateway format (e.g. traefik-yaml, caddy, nginx) |
[config], -c, --config | string | "routewarden.json" | Path to RouteWarden JSON config file (or - for stdin) |
Available Targets & Aliases:
| Target / Alias | Output |
|---|---|
traefik-yaml, traefik, yaml, yml | Traefik dynamic YAML middleware definition (dynamic.yml) |
traefik-toml, toml | Traefik dynamic TOML middleware definition (dynamic.toml) |
traefik-labels, compose, docker-compose, labels | Docker Compose labels: block |
caddy, caddyfile | Caddyfile routewarden { ... } directive block |
nginx, openresty | OpenResty Lua table for init_by_lua_block in nginx.conf |
5. Live Gateway Sandbox (sandbox)
Test configurations against an ephemeral Docker container running Traefik, Caddy, or NGINX.
rwarden sandbox supports:
- Generic JSON (
routewarden.json): Automatically synthesized into complete gateway configurations. - Actual Gateway Configs: Pass real
traefik.toml,traefik.yaml/dynamic.yml,docker-compose.yaml,Caddyfile, ornginx.confdirectly. Target gateway and format are auto-detected from filename and content. - Inline Docker Labels: Test Traefik label snippets directly via
--labels. - Snippets & Complete Production Configs:
- Snippets: Middleware-only snippets are automatically wrapped with sandbox entrypoints and mock upstream endpoints returning
200 OKfor passing traffic. - Complete Configs: Full configurations with backend service URLs, upstreams, or proxies are automatically adapted for ephemeral sandboxes in-memory without modifying your source file:
- Traefik: External loadBalancer service URLs (
url,service) are redirected to Traefik's internal ping service (ping@internal), entrypoints guarantee:8080binding, and router TLS directives are safely neutralized for local HTTP testing. - Caddy: Upstream
reverse_proxytargets are replaced with mock200 OKresponders,order routewarden firstandauto_https offare injected, and custom site blocks bind to:8080. - NGINX: External
upstreamhostnames are neutralized withdownto prevent OpenResty startup DNS failures,proxy_passdirectives are converted to mock Lua200 OKresponders, local SSL certificate requirements are bypassed, andlisten 8080;is configured.
- Traefik: External loadBalancer service URLs (
- Live Upstream Reachability: In
--testmode, RouteWarden recognizes upstream reachability (HTTP200, or HTTP502/504from an offline production backend) as an allowlist pass-through.
- Snippets: Middleware-only snippets are automatically wrapped with sandbox entrypoints and mock upstream endpoints returning
# 1. Test actual Traefik TOML configuration (auto-detects target & mounts dynamic.toml)
rwarden sandbox traefik.toml
rwarden sandbox -c traefik.toml
# 2. Test actual Traefik YAML / dynamic.yml
rwarden sandbox dynamic.yml
# 3. Test Docker Compose with Traefik labels
rwarden sandbox docker-compose.yaml
# 4. Test Traefik labels inline
rwarden sandbox --labels "traefik.http.middlewares.shield.plugin.routewarden.enabled=true"
# 5. Test actual Caddyfile
rwarden sandbox Caddyfile
# 6. Test actual nginx.conf
rwarden sandbox nginx.conf
# 7. Automated live probe verification with custom path and IP allowlist assertion
rwarden sandbox docker-compose.yaml --test --probe-path "/immich/api/admin" --probe-ip "10.0.0.1"
# 8. Dry-run: inspect generated/wrapped gateway config & exact docker run command
rwarden sandbox traefik.toml -n -p
# 9. Run in detached background mode
rwarden sandbox caddy Caddyfile -d
# 10. Run against specific RouteWarden plugin version or local plugin path
rwarden sandbox traefik --plugin-version v1.2.0
rwarden sandbox traefik --plugin-path ../traefik-warden# Test actual traefik.toml via Docker (mounts docker.sock):
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/traefik.toml:/config/traefik.toml:ro \
-p 8080:8080 \
ghcr.io/routewarden/cli:latest sandbox /config/traefik.toml
# Test Docker Compose Traefik labels via Docker:
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/docker-compose.yaml:/config/docker-compose.yaml:ro \
-p 8080:8080 \
ghcr.io/routewarden/cli:latest sandbox /config/docker-compose.yaml --test
# Test inline labels without mounting files:
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 8080:8080 \
ghcr.io/routewarden/cli:latest sandbox \
--labels "traefik.http.middlewares.shield.plugin.routewarden.enabled=true" \
--test| Flag | Type | Default | Description |
|---|---|---|---|
[config], -c, --config | string | "" | Path to gateway config (traefik.toml, dynamic.yml, docker-compose.yaml, Caddyfile, nginx.conf, routewarden.json, or -) |
-t, --target | string | "" | Target gateway: traefik, caddy, or nginx (optional if auto-detected or passed as positional argument) |
--format | string | "" | Explicit format: traefik-toml, traefik-yaml, traefik-labels, caddy, nginx, json |
--labels | string | "" | Direct Traefik Docker labels string (e.g. 'traefik.http.middlewares.warden...') |
--probe-path | string | "" | Custom endpoint path to verify blocked during --test |
--probe-ip | string | "" | Client IP to simulate via X-Forwarded-For to verify allowlist bypass during --test |
--port | int | 8080 | Local port to bind the gateway |
--version | string | "" | Target gateway container version tag (e.g. v3.3, 2.11.4, alpine) |
--plugin-version | string | "" | RouteWarden plugin version/tag/branch (e.g. v1.2.0, v1.1.0, main) |
--plugin-path | string | "" | Local path to RouteWarden plugin directory to mount for development |
-p, --print-config | bool | false | Print generated/wrapped gateway configuration before running |
--test | bool | false | Run automated live HTTP probe assertions against container then exit |
-n, --dry-run | bool | false | Generate config and show docker command without starting container |
-d, --detach | bool | false | Run container in background mode |
Testing Live with curl
Once your sandbox container is running on port 8080, test real HTTP requests against it:
# 1. Direct sensitive file access (blocked)
curl -i http://localhost:8080/.env
# 2. Path traversal & double URL encoding evasion (blocked)
curl -i http://localhost:8080/static/%252e%252e/.env
# 3. Query string inspection (blocked if checkQuery is enabled)
curl -i "http://localhost:8080/search?file=secret.conf"
# 4. Semicolon matrix parameter evasion (blocked)
curl -i "http://localhost:8080/app;jsessionid=123/.env"
# 5. Reverse proxy header smuggling (blocked if checkHeaders is enabled)
curl -i -H "X-Forwarded-Uri: /.env" http://localhost:8080/api/dashboard
# 6. Legitimate public asset (allowed downstream)
curl -i http://localhost:8080/robots.txt
# 7. Client IP whitelisting test (simulating a request from whitelisted IP 192.168.1.50)
curl -i -H "X-Forwarded-For: 192.168.1.50" http://localhost:8080/.envSecurity Note on Client IP & Reverse Proxies
In local testing and the sandbox, passing X-Forwarded-For allows you to simulate requests from whitelisted IPs without reconfiguring your network.
In production deployments, edge reverse proxies (Cloudflare, AWS ALB, Traefik, or NGINX) strip or overwrite untrusted client-supplied X-Forwarded-For headers with the client's actual TCP socket IP. Ensure your edge gateway is configured to only trust upstream proxy headers from verified addresses (e.g. trustedIPs in Traefik, trusted_proxies in Caddy, or set_real_ip_from in NGINX).
6. Cleanup Sandbox Containers (cleanup)
Stop and remove all running or detached RouteWarden sandbox containers:
rwarden cleanup
# Or via sandbox subcommand:
rwarden sandbox cleanupdocker run --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/routewarden/cli:latest cleanup7. Check CLI Version (version)
Display the current RouteWarden CLI version:
rwarden version
rwarden --version
rwarden -vdocker run --rm ghcr.io/routewarden/cli:latest versionExample Output:
rwarden version 2.1.0JSON Schema & IDE Setup
The official RouteWarden JSON Schema is hosted at:
https://routewarden.github.io/cli/schema.json(Also mirrored at https://raw.githubusercontent.com/routewarden/cli/main/config.schema.json)
It provides real-time validation, syntax checking, and inline autocomplete for:
- Traefik dynamic middleware YAML/JSON configurations
- Caddy JSON API routes and handler configurations
- Standalone RouteWarden JSON/YAML configs loaded by NGINX Lua or CI/CD pipelines
1. Visual Studio Code Setup
Add schema mappings to your workspace .vscode/settings.json:
{
"json.schemas": [
{
"fileMatch": [
"routewarden*.json",
"*traefik*.json",
"caddy*.json"
],
"url": "https://raw.githubusercontent.com/routewarden/cli/main/config.schema.json"
}
],
"yaml.schemas": {
"https://raw.githubusercontent.com/routewarden/cli/main/config.schema.json": [
"routewarden*.yml",
"routewarden*.yaml",
"dynamic_conf.yml",
"traefik-dynamic*.yml"
]
}
}Tip: Ensure the official Red Hat YAML extension (
redhat.vscode-yaml) is installed for YAML file validation.
2. JetBrains IDEs (IntelliJ, GoLand, WebStorm)
- Open Settings / Preferences (
⌘,on macOS orCtrl+Alt+Son Linux/Windows). - Navigate to Languages & Frameworks → Schemas and DTDs → JSON Schema Mappings.
- Click + (Add):
- Name:
RouteWarden - Schema file or URL:
https://raw.githubusercontent.com/routewarden/cli/main/config.schema.json - Schema version:
JSON Schema version 7or2020-12
- Name:
- Under File path pattern, add:
routewarden*.jsonroutewarden*.ymldynamic_conf.ymlcaddy*.json
3. Gateway Usage Examples
Traefik Dynamic YAML Configuration
Use top-of-file modeline comment to bind schema directly without global IDE settings:
# yaml-language-server: $schema=https://raw.githubusercontent.com/routewarden/cli/main/config.schema.json
enabled: true
enableDefaultPatterns: true
checkQuery: true
checkHeaders:
- X-Forwarded-Uri
- X-Rewrite-URL
methods:
- GET
- POST
response:
mode: json
statusCode: 403
body: '{"error":"Forbidden: Sensitive access blocked"}'Caddy JSON Configuration
When configuring Caddy via the REST API or JSON files, map the route_warden handler directly:
{
"$schema": "https://raw.githubusercontent.com/routewarden/cli/main/config.schema.json",
"enabled": true,
"enableDefaultPatterns": true,
"checkQuery": false,
"checkHeaders": ["X-Forwarded-Uri"],
"methods": ["GET", "HEAD"],
"response": {
"mode": "json",
"statusCode": 403
}
}NGINX / OpenResty JSON Configuration
If your NGINX Lua configuration reads external JSON configs via cjson.decode(io.open("/etc/nginx/routewarden.json"):read("*a")):
{
"$schema": "https://raw.githubusercontent.com/routewarden/cli/main/config.schema.json",
"enabled": true,
"enableDefaultPatterns": true,
"enableDefaultAllowPatterns": true,
"checkQuery": true,
"checkHeaders": ["X-Forwarded-Uri", "X-Rewrite-URL"],
"methods": ["GET", "POST"],
"response": {
"mode": "rateLimitChallenge",
"statusCode": 429,
"retryAfterSeconds": 300
}
}And in NGINX init_by_lua_block:
init_by_lua_block {
local cjson = require("cjson")
local routewarden = require("resty.routewarden")
local f = io.open("/etc/nginx/routewarden.json", "r")
local cfg_json = f:read("*all")
f:close()
local cfg = cjson.decode(cfg_json)
warden = routewarden.new(cfg)
}Using routewarden.json in Production
routewarden.json is a universal, gateway-agnostic security configuration file. It lets you decouple your security posture from your web server configurations, allowing security and DevOps teams to maintain rules centrally with schema validation.
Workflow Overview
┌──────────────────────────────────────────────────────────┐
│ routewarden.json │
│ - Built with schema autocomplete ($schema) │
│ - Tested & validated via rwarden in CI/CD │
└────────────────────────────┬─────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ NGINX / Lua │ │ Traefik │ │ Caddy │
│ JSON Loader │ │ File Provider│ │ REST API │
└──────────────┘ └──────────────┘ └──────────────┘1. Offline Verification & CI/CD Pipeline Linting
Before pushing updates to production, use rwarden to validate your routewarden.json configuration file:
# Offline syntax, regex, and CIDR validation
rwarden validate --config routewarden.json
# Simulate request evaluation against the rules
rwarden test --path "/.env"
rwarden test --path "/dashboard" --header "X-Forwarded-Uri:/.env"# Offline syntax, regex, and CIDR validation via container
docker run --rm -v $(pwd)/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest validate --config /routewarden.json
# Simulate request evaluation against the rules
docker run --rm ghcr.io/routewarden/cli:latest test --path "/.env"
docker run --rm ghcr.io/routewarden/cli:latest test --path "/dashboard" --header "X-Forwarded-Uri:/.env"GitHub Actions CI Example (.github/workflows/verify-rules.yml)
name: Verify Security Rules
on:
pull_request:
paths:
- 'routewarden.json'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Install RouteWarden CLI
run: go install github.com/routewarden/cli@latest
- name: Validate Configuration
run: rwarden validate --config routewarden.jsonname: Verify Security Rules
on:
pull_request:
paths:
- 'routewarden.json'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate Configuration via Docker
run: docker run --rm -v ${{ github.workspace }}/routewarden.json:/routewarden.json ghcr.io/routewarden/cli:latest validate --config /routewarden.json2. Loading into NGINX / OpenResty
Instead of hardcoding rules in nginx.conf, mount routewarden.json into your container and load it dynamically during worker startup:
docker-compose.yml
services:
nginx:
image: openresty/openresty:alpine
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./routewarden.json:/etc/nginx/routewarden.json:ronginx.conf
http {
init_by_lua_block {
local cjson = require("cjson")
local routewarden = require("resty.routewarden")
-- Load external JSON configuration
local f, err = io.open("/etc/nginx/routewarden.json", "r")
if not f then
ngx.log(ngx.ERR, "failed to read routewarden.json: ", err)
return
end
local content = f:read("*all")
f:close()
local config = cjson.decode(content)
warden = routewarden.new(config)
}
server {
listen 80;
access_by_lua_block {
warden:check()
}
location / {
proxy_pass http://backend_upstream;
}
}
}To update rules without restarting NGINX, simply modify routewarden.json and reload:
nginx -s reload3. Traefik Dynamic File Provider
Traefik natively supports JSON for dynamic configuration providers:
traefik.yml (Static Config)
providers:
file:
filename: /etc/traefik/dynamic_conf.json
watch: truedynamic_conf.json
{
"$schema": "https://raw.githubusercontent.com/routewarden/cli/main/config.schema.json",
"http": {
"middlewares": {
"security-warden": {
"plugin": {
"routewarden": {
"enabled": true,
"enableDefaultPatterns": true,
"checkQuery": true,
"checkHeaders": ["X-Forwarded-Uri", "X-Rewrite-URL"],
"response": {
"mode": "json",
"statusCode": 403
}
}
}
}
}
}
}4. Caddy JSON API Automation
Caddy's runtime configuration is completely addressable via JSON. You can push routewarden.json directly to Caddy's admin API endpoint with zero downtime:
# Push RouteWarden config to the first route handler
curl -X POST "http://localhost:2019/config/apps/http/servers/srv0/routes/0/handle/0" \
-H "Content-Type: application/json" \
-d @routewarden.jsonOr inspect how a Caddyfile translates into the JSON schema:
caddy adapt --config Caddyfile --prettyChangelog
All notable changes to the RouteWarden CLI (rwarden) are documented below. The CLI adheres to Semantic Versioning.
[v2.1.0] - 2026-09-24
Added
- Flexible Positional Arguments & Lenient Flag Parsing:
- Direct positional inputs for all commands:
rwarden test /.env,rwarden validate [config],rwarden generate <target> [config], andrwarden sandbox <target> [config]. - Flags can now be placed interchangeably before or after positional arguments.
- Automatic fallback to
routewarden.jsonin current working directory when--configis omitted invalidateandgenerate.
- Direct positional inputs for all commands:
- Shorthand Flag Aliases:
- Added
-cfor--config,-tfor--target,-qfor--query,-Xand-mfor--method,-H(repeatable) for--header,-nfor--dry-run,-dfor--detach,-pfor--print-config, and-vforversion.
- Added
- Target & Format Aliases:
- Target generator and sandbox accept standard aliases:
yaml,yml,toml,compose,labels,docker-compose,caddyfile,openresty.
- Target generator and sandbox accept standard aliases:
- Production Gateway Config Adaptation in Sandbox:
- Support for passing complete, production Traefik (
traefik.yaml,traefik.toml), Docker Compose (docker-compose.yaml), Caddy (Caddyfile), and NGINX (nginx.conf) files directly torwarden sandbox. - In-memory auto-adaptation: rewrites external upstream backend URLs, proxies, and certificates for isolated local testing without modifying original configuration files.
- Live probe testing (
--test) accommodates upstream reachability (HTTP 200, 502, 504) as allowlist pass-through.
- Support for passing complete, production Traefik (
- Dedicated Sandbox Teardown Command:
rwarden cleanup(andrwarden sandbox cleanup) to stop and prune dangling or detached sandbox containers in one command.
Fixed
- Regex & Configuration Parsing:
- Fixed RE2 regex backreference in Traefik label parsing to ensure 100% Go regexp standard library compliance.
- Prevented multiline upstream regex greediness in NGINX config adaptation from corrupting
server {blocks. - Injected missing
middlewares:parent block in synthetic Traefik sandbox YAML generation. - Enhanced label normalization to recognize root-level response parameters (
status,statusCode,mode,action,customResponseText). - Removed legacy direct boolean
silentDropproperty fromConfigschema, structs, and Docker label converters (usemode: "silentDrop",action: "silentDrop", orresponse.mode: "silentDrop"instead).
[v2.0.0] - 2026-09-21
Added
- Ephemeral Gateway Sandbox (
rwarden sandbox):- Spin up live, ephemeral container environments for Traefik, Caddy, and NGINX (OpenResty) pre-configured with RouteWarden security rules.
- Automatically translates and mounts native dynamic configurations (
dynamic.yml,Caddyfile,nginx.conf) into isolated test containers. - Interactive foreground mode with instant graceful teardown on
Ctrl+C. - Detached background mode (
--detach/-d) for local dev workflows and integration testing. - Automated probe testing (
--test) to execute live HTTP test suites asserting blocking and bypass behavior directly against the running container. - Dry-run mode (
--dry-run) to inspect generated gateway configurations and exact Docker run commands without launching containers. - Print configuration option (
--print-config/-p) to output generated gateway configuration before launching.
- Custom RouteWarden Plugin Support:
--plugin-version: Specify custom plugin version/tag/branch for testing specific releases (Traefik plugin catalog version, Caddy / NGINX container tag).--plugin-path: Mount local plugin repository directories for real-time plugin development and verification.
- Pre-flight Environment Validation:
- Added early Docker installation and daemon accessibility checks (
CheckDockerInstalled) to fail fast with actionable guidance before preparing or running containers.
- Added early Docker installation and daemon accessibility checks (
- Enhanced Container Tooling:
- Included
docker-cliinside the RouteWarden container image (ghcr.io/routewarden/cli) to enable running sandboxes from within Docker via/var/run/docker.sock.
- Included
[v1.1.0] - 2026-09-21
Added
- Multi-Gateway Config Generator (
generate):- Convert
routewarden.jsoninto native configuration for Traefik Dynamic YAML (--target traefik), Traefik Docker Labels (--target traefik-labels), Caddy Caddyfile (--target caddy), and NGINX / OpenResty Lua (--target nginx). - Added support for
--config -to stream configuration via standard input (stdin). - Accurate serialization for
checkQuery,checkHeaders,methods, and nestedresponse { mode, status, body }blocks.
- Convert
- Client IP Whitelist Simulation (
test --ip):- Test client IP evaluation against CIDR blocks and single IP allowlists offline (
rwarden test --config routewarden.json --path "/admin" --ip "10.0.0.1").
- Test client IP evaluation against CIDR blocks and single IP allowlists offline (
- HTTP Header Smuggling Inspection (
test --header):- Test custom headers in
Key:Valueformat (e.g.,X-Forwarded-Uri,X-Rewrite-URL,X-Original-URL) to evaluate reverse proxy path normalization anti-evasion.
- Test custom headers in
- Config & Query Precedence in Offline Testing:
- Added
--config <path>flag torwarden testto evaluate paths directly against custom configurations with full rule normalization. - Added
--check-queryboolean flag (defaulttruefor interactive CLI usage, respects configuration file when provided).
- Added
- Comprehensive Configuration Validation (
validate):- Added HTTP status code range checks (100–599) across top-level and response configs.
- Added response mode validation (
text,json,html,captcha,redirect,silentDrop,drop,gzipBomb,tarpit,fakeSuccess,rateLimitChallenge,proxy,infiniteStream). - Added required target URL validation for
redirect(redirectUrl) andproxy(proxyUrl) modes. - Added CAPTCHA provider validation (
turnstile,hcaptcha,recaptcha,custom).
- Release Automation:
- Added
scripts/update-version.shandVERSIONING.mdfor maintainers.
- Added
Changed
- Normalized top-level
mode,action, andsilentDropaliases uniformly intoResponse.Mode. - Modernized Caddyfile generator output to use the standard
response { mode ... status ... body ... }directive block.
[v1.0.0] - 2026-09-20
Initial Release
- Path Anti-Evasion Inspection Engine (
test):- Offline candidate path extraction simulating Traefik and Caddy middleware pipelines.
- Recursive multi-layer URL percent-decoding (
%252e%252e). - Semicolon matrix parameter stripping (
/;param/.env). - Windows/IIS backslash normalization (
\..\). - Null-byte injection scrubbing (
%00). - Dot-segment path traversal resolving (
/static/../.env). - Default block pattern matching across sensitive files (
.env,server.key,cert.pem,Dockerfile,.git, etc.). - Default allow pattern overrides (
robots.txt,favicon.ico,sitemap.xml,.well-known).
- Configuration Validator (
validate):- Offline schema validation of
routewarden.json. - Detection of invalid regular expressions and malformed CIDR blocks.
- Detailed summary breakdown of active rules, allowlists, and monitored headers.
- Offline schema validation of
- Official JSON Schema Export (
schema):- CLI command emitting
config.schema.jsondirectly for IDE integration (VS Code, JetBrains, Neovim) and CI/CD validation.
- CLI command emitting
- Distribution:
- Single-binary zero-dependency Go distribution for macOS (
amd64,arm64), Linux (amd64,arm64), and Windows (amd64). - Automated installation script (
curl -fsSL https://routewarden.github.io/cli/install.sh | bash). - Official multi-architecture Docker container image on GitHub Container Registry (
ghcr.io/routewarden/cli:latest).
- Single-binary zero-dependency Go distribution for macOS (