Skip to content

Firewall Rules API - AI Security and Content Filtering

The Firewall Rules API allows you to programmatically create and manage firewall rules that filter, block, or transform content in requests and responses based on pattern matching.

  • prompt - Apply rule to user input before sending to AI provider (currently implemented)
  • response - Apply rule to AI output before returning to user (planned feature - currently not evaluated)
  • substring - Case-insensitive substring search using stripos() (simple and fast)
  • regex - Regular expression matching with PCRE (more powerful, flexible)
    • Patterns without delimiters are auto-wrapped: \d{3} becomes /\d{3}/i
    • Patterns with delimiters are used as-is: /\d{3}/ or /\d{3}/i
    • All patterns are case-insensitive by default
  • block - Immediately reject the request with a 403 Forbidden error (stops all processing)
  • mask - Replace matched content with replacement text and continue processing
  • warn - Add warning to response metadata without modifying content

GET https://api.tokenrouter.io/v1/firewall-rules

Returns all firewall rules for the authenticated user, ordered by priority (highest first).

const response = await fetch('https://api.tokenrouter.io/v1/firewall-rules', {
headers: {
'Authorization': 'Bearer tr_...',
}
});
const { data } = await response.json();
console.log(`Found ${data.length} firewall rules`);
{
"data": [
{
"id": 1,
"user_id": 123,
"name": "Block Credit Cards",
"is_enabled": true,
"scope": "prompt",
"type": "regex",
"pattern": "/\\d{4}-\\d{4}-\\d{4}-\\d{4}/",
"action": "block",
"replacement": null,
"priority": 100,
"created_at": "2025-09-13T19:14:23.000000Z",
"updated_at": "2025-09-13T19:14:23.000000Z"
},
{
"id": 2,
"user_id": 123,
"name": "Mask Email Addresses",
"is_enabled": true,
"scope": "prompt",
"type": "regex",
"pattern": "/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/",
"action": "mask",
"replacement": "[EMAIL]",
"priority": 90,
"created_at": "2025-09-13T19:14:23.000000Z",
"updated_at": "2025-09-13T19:14:23.000000Z"
}
]
}

POST https://api.tokenrouter.io/v1/firewall-rules

Creates a new firewall rule.

ParameterTypeRequiredDescription
namestringYesHuman-readable name (max 128 chars)
is_enabledbooleanYesWhether the rule is active
scopestringYesprompt or response
typestringYessubstring or regex
patternstringYesPattern to match
actionstringYesblock, mask, or warn
replacementstringNoFor mask action (default: [redacted])
priorityintegerYesPriority (-1000 to 1000, higher = first)
const response = await fetch('https://api.tokenrouter.io/v1/firewall-rules', {
method: 'POST',
headers: {
'Authorization': 'Bearer tr_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: "Block Credit Cards",
is_enabled: true,
scope: "prompt",
type: "regex",
pattern: "/\\d{4}-\\d{4}-\\d{4}-\\d{4}/",
action: "block",
priority: 100
})
});
const { data } = await response.json();
console.log(`Created rule: ${data.name}`);
{
"name": "Mask Email Addresses",
"is_enabled": true,
"scope": "prompt",
"type": "regex",
"pattern": "/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/",
"action": "mask",
"replacement": "[EMAIL]",
"priority": 90
}
{
"name": "Warn on API Keys",
"is_enabled": true,
"scope": "prompt",
"type": "substring",
"pattern": "api_key",
"action": "warn",
"priority": 50
}

GET https://api.tokenrouter.io/v1/firewall-rules/{id}

Returns a single firewall rule by ID.

const response = await fetch('https://api.tokenrouter.io/v1/firewall-rules/1', {
headers: {
'Authorization': 'Bearer tr_...',
}
});
const { data } = await response.json();

PATCH https://api.tokenrouter.io/v1/firewall-rules/{id}

Updates an existing firewall rule. All fields are optional.

await fetch('https://api.tokenrouter.io/v1/firewall-rules/1', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer tr_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
is_enabled: false
})
});
{
"pattern": "/\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}/"
}
{
"action": "warn"
}
{
"replacement": "[REDACTED-PII]"
}

DELETE https://api.tokenrouter.io/v1/firewall-rules/{id}

Permanently deletes a firewall rule.

await fetch('https://api.tokenrouter.io/v1/firewall-rules/1', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer tr_...',
}
});
{
"success": true
}

{
"name": "Block SSN",
"is_enabled": true,
"scope": "prompt",
"type": "regex",
"pattern": "/\\d{3}-\\d{2}-\\d{4}/",
"action": "block",
"priority": 100
}

When it matches:

  • Input contains pattern like “123-45-6789”

What it does:

  • Blocks the request immediately
  • Returns 403 error with firewall message
{
"name": "Mask Phone Numbers",
"is_enabled": true,
"scope": "prompt",
"type": "regex",
"pattern": "/\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}/",
"action": "mask",
"replacement": "[PHONE]",
"priority": 85
}

When it matches:

  • Phone numbers like “(555) 123-4567”, “555-123-4567”, or “555.123.4567”

What it does:

  • Replaces the phone number with [PHONE]
  • Continues processing with masked input
{
"name": "Warn on Sensitive Topics",
"is_enabled": true,
"scope": "prompt",
"type": "substring",
"pattern": "confidential",
"action": "warn",
"priority": 60
}

When it matches:

  • Input contains “confidential” (case-insensitive)

What it does:

  • Adds a warning to the response metadata
  • Continues processing normally
{
"name": "Mask API Keys in Output",
"is_enabled": true,
"scope": "response",
"type": "regex",
"pattern": "/sk-[a-zA-Z0-9]{32,}/",
"action": "mask",
"replacement": "[API_KEY]",
"priority": 95
}

When it matches:

  • AI response contains patterns like “sk-…”

What it does:

  • Replaces API key patterns in the response
  • Protects against accidental key leakage

Example 5: Block Multiple Credit Card Formats

Section titled “Example 5: Block Multiple Credit Card Formats”
{
"name": "Block All Credit Card Formats",
"is_enabled": true,
"scope": "prompt",
"type": "regex",
"pattern": "/\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}/",
"action": "block",
"priority": 100
}

When it matches:

  • “1234-5678-9012-3456”
  • “1234 5678 9012 3456”
  • “1234567890123456”

What it does:

  • Blocks any of these credit card formats

  • Case-insensitive - “API_KEY” matches “api_key”, “Api_Key”, etc.
  • Simple search - Matches anywhere in the text
  • Fast - More efficient than regex (no compilation overhead)
  • Input normalization - Objects/arrays are JSON-encoded before matching
  • Example: Pattern “secret” matches “my-secret-key”
  • Full PCRE support - Use standard regex syntax
  • Auto-wrapping - Patterns without delimiters are wrapped automatically
    • \d{3}-\d{2}-\d{4} becomes /\d{3}-\d{2}-\d{4}/i
    • /\d{3}-\d{2}-\d{4}/ stays as-is
  • Case-insensitive by default - ‘i’ flag added automatically to wrapped patterns
  • Safe execution - Invalid regex patterns fail gracefully (no match)
  • Input normalization - Objects/arrays are JSON-encoded before matching

Examples:

  • /\d{3}-\d{2}-\d{4}/ - SSN pattern (stays as-is)
  • /[a-z]+@[a-z]+\.[a-z]+/ - Simple email (stays as-is)
  • \d{16} - Wrapped as /\d{16}/i (case-insensitive)
  • /sk-[a-zA-Z0-9]{32,}/ - API key pattern

Rules are evaluated in this order:

  1. Priority (descending) - Higher priority rules evaluated first
  2. ID (ascending) - Older rules evaluated first for same priority
  3. All matching rules apply - Multiple firewall rules can trigger for the same request
  4. Scope filtering - Only rules with scope: "prompt" are currently evaluated
Request: "My SSN is 123-45-6789"
Rule: Block on pattern /\d{3}-\d{2}-\d{4}/
Result: 403 Forbidden
Response: {
"error": {
"message": "Request blocked by firewall rule \"Block SSN\".",
"meta": {
"rule_id": 1
}
}
}

Notes:

  • Request is immediately rejected (throws RoutingException)
  • No further processing occurs
  • Error message includes rule name
  • HTTP status: 403 Forbidden
Request: "Email me at john@example.com"
Rule:
- Type: regex
- Pattern: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/
- Action: mask
- Replacement: [EMAIL]
Transformed Input: "Email me at [EMAIL]"
(Request continues to AI provider with masked input)

Notes:

  • Pattern is replaced with replacement text (default: [redacted])
  • Substring type: Uses str_ireplace() (case-insensitive)
  • Regex type: Uses preg_replace() with the pattern
  • Input can be string or array - masking applies to all string values
  • Processing continues after masking
Request: "This is confidential information"
Rule:
- Type: substring
- Pattern: confidential
- Action: warn
Response metadata includes:
{
"warnings": [
{
"code": "firewall",
"message": "Firewall rule \"Warn on Sensitive Topics\" triggered."
}
]
}

Notes:

  • Warning message is added to context with code "firewall"
  • Message format: Firewall rule "{rule_name}" triggered.
  • Request processing continues normally
  • Warnings are included in response metadata
  • Multiple warn rules accumulate multiple warnings

{
"error": {
"message": "The name field is required."
}
}
{
"error": {
"message": "Custom firewall rules require a paid plan."
}
}
{
"error": {
"message": "Firewall rule not found"
}
}
  1. Start with warnings - Test patterns with warn action first
  2. Use specific patterns - Avoid overly broad patterns that may block legitimate requests
  3. Test thoroughly - Validate regex patterns before deploying
  4. Monitor performance - Check analytics to see how often rules trigger
  5. Use appropriate scope - prompt for input filtering, response for output sanitization
  6. Set priorities carefully - Higher priority for more critical rules
  7. Combine with routing rules - Use together for complete request control