Skip to content

Configuration

Griffen Fargo edited this page Aug 20, 2026 · 6 revisions

Configuration

Doorman uses a JSON configuration file to define your firewall rules. The configuration is validated using JSON Schema and provides full TypeScript support.

Schema URL

Add the schema reference to your config file for editor autocompletion and validation:

{
  "$schema": "https://doorman.griffen.codes/schema.json"
}

Basic Structure

Vercel Configuration

{
  "$schema": "https://doorman.griffen.codes/schema.json",
  "projectId": "prj_abc123",
  "teamId": "team_xyz789",
  "rules": [],
  "ips": []
}

Cloudflare Configuration

{
  "$schema": "https://doorman.griffen.codes/schema.json",
  "provider": "cloudflare",
  "providers": {
    "cloudflare": {
      "zoneId": "zone_abc123",
      "accountId": "acc_xyz789"
    }
  },
  "rules": [],
  "ips": []
}

Fastly Configuration

{
  "$schema": "https://doorman.griffen.codes/schema.json",
  "provider": "fastly",
  "providers": {
    "fastly": {
      "workspaceId": "workspace_abc123"
    }
  },
  "rules": [],
  "ips": []
}

Multi-Provider Configuration

{
  "$schema": "https://doorman.griffen.codes/schema.json",
  "provider": "cloudflare",
  "providers": {
    "vercel": {
      "projectId": "prj_abc123",
      "teamId": "team_xyz789"
    },
    "cloudflare": {
      "zoneId": "zone_abc123",
      "accountId": "acc_xyz789"
    },
    "fastly": {
      "workspaceId": "workspace_abc123"
    }
  },
  "rules": [],
  "ips": []
}

Root Properties

Property Type Required Description
$schema string No JSON Schema URL for validation
provider string No Default provider ("vercel", "cloudflare", or "fastly")
projectId string Vercel Only Vercel project ID
teamId string Vercel Only Vercel team ID (optional)
providers object Multi-Provider Provider-specific configurations
rules array Yes Array of firewall rules
ips array No Array of IP blocking rules
version number No Configuration version
firewallEnabled boolean No Enable/disable firewall

Rules

Rule Structure

{
  "id": "rule_block_bots",
  "name": "Block Bad Bots",
  "description": "Block malicious bots and crawlers",
  "active": true,
  "conditionGroup": [
    {
      "conditions": [
        {
          "type": "user_agent",
          "op": "sub",
          "value": "bot",
          "neg": false
        }
      ]
    }
  ],
  "action": {
    "mitigate": {
      "action": "deny"
    }
  }
}

Rule Properties

Property Type Required Description
id string No Unique rule identifier
name string Yes Human-readable rule name
description string No Rule description
active boolean Yes Whether rule is enabled
conditionGroup array Yes Array of condition groups (OR logic)
action object Yes Action to take when rule matches

Condition Groups

Condition groups use OR logic between groups and AND logic within groups:

{
  "conditionGroup": [
    {
      "conditions": [
        { "type": "path", "op": "pre", "value": "/admin" },
        { "type": "method", "op": "eq", "value": "POST" }
      ]
    },
    {
      "conditions": [
        { "type": "ip_address", "op": "eq", "value": "192.168.1.1" }
      ]
    }
  ]
}

This translates to: (path starts with "/admin" AND method equals "POST") OR (IP equals "192.168.1.1")

Condition Types

Type Description Vercel Cloudflare Fastly
host Hostname
path URL path
method HTTP method
header HTTP header ✅ Requires a key
query Query parameter ✅ Requires a key
cookie Cookie value ✅ Requires a key
user_agent User agent string
ip_address IP address
geo_country Country code
geo_continent Continent code
geo_city City name
protocol Protocol
scheme URL scheme
environment Deployment environment
region Vercel region

On Fastly, header/query/cookie conditions translate to a multival condition block rather than a plain single condition — see Fastly Setup.

Operators

Operator Description Vercel Cloudflare Fastly
eq Equals
pre Starts with ⚠️ Approximated (wildcard like, not a true prefix match)
suf Ends with ⚠️ Approximated (wildcard like, not a true suffix match)
sub Contains
inc Is any of (array)
re Regex match ⚠️ Enterprise
ex Exists ⚠️ Only on header/query/cookie multival conditions
nex Does not exist ⚠️ Only on header/query/cookie multival conditions

Actions

Action Description Vercel Cloudflare Fastly
log Log only ⚠️ No dedicated action — maps to allow
deny Block request
allow Allow request ❌ (use bypass)
challenge CAPTCHA challenge
bypass Skip other rules ⚠️ No equivalent — maps to allow
rate_limit Rate limiting ✅ Requires a pre-existing signal — see Fastly Setup
redirect HTTP redirect

Rate Limiting

{
  "action": {
    "mitigate": {
      "action": "rate_limit",
      "rateLimit": {
        "requests": 100,
        "window": "60s"
      }
    }
  }
}

Redirect

{
  "action": {
    "mitigate": {
      "action": "redirect",
      "redirect": {
        "location": "https://example.com/blocked",
        "permanent": false
      }
    }
  }
}

IP Blocking Rules

{
  "ips": [
    {
      "id": "ip_block_suspicious",
      "ip": "192.168.1.100/32",
      "hostname": "suspicious-host",
      "action": "deny",
      "notes": "Blocked due to suspicious activity"
    }
  ]
}
Property Type Required Description
ip string Yes IP address or CIDR range
hostname string No Hostname for documentation
action string Yes Action (currently only "deny")
notes string No Notes about the block

Environment Variables

Vercel

VERCEL_TOKEN="your_vercel_token"
VERCEL_PROJECT_ID="prj_abc123"
VERCEL_TEAM_ID="team_xyz789"

Cloudflare

CLOUDFLARE_API_TOKEN="your_api_token"
CLOUDFLARE_ZONE_ID="zone_abc123"
CLOUDFLARE_ACCOUNT_ID="acc_xyz789"

Fastly

FASTLY_API_TOKEN="your_api_token"
FASTLY_WORKSPACE_ID="workspace_abc123"

Provider Selection

DOORMAN_PROVIDER="cloudflare"  # or "vercel" or "fastly"

Best Practices

  1. Use descriptive names for rules and IPs
  2. Add descriptions to explain rule purposes
  3. Group related conditions logically
  4. Use CIDR notation for IP ranges
  5. Order rules by frequency (most common first)
  6. Test rules in staging before production
  7. Start with log actions before blocking
  8. Keep backups of working configurations

Related Pages

Clone this wiki locally