4.9 KiB
Configuration
Schema Validation 2.0 Setup
⚠️ Classic Schema Validation deprecated. Use Schema Validation 2.0.
Upload schema (Dashboard):
Security > API Shield > Schema Validation > Add validation
- Upload .yml/.yaml/.json (OpenAPI v3.0)
- Endpoints auto-added to Endpoint Management
- Action: Log | Block | None
- Body inspection: JSON payloads
Change validation action:
Security > API Shield > Settings > Schema Validation
Per-endpoint: Filter → ellipses → Change action
Default action: Set global mitigation action
Migration from Classic:
1. Export existing schema (if available)
2. Delete all Classic schema validation rules
3. Wait 5 min for cache clear
4. Re-upload via Schema Validation 2.0 interface
5. Verify in Security > Events
Fallthrough rule (catch-all unknown endpoints):
Security > API Shield > Settings > Fallthrough > Use Template
- Select hostnames
- Create rule with cf.api_gateway.fallthrough_triggered
- Action: Log (discover) or Block (strict)
Body inspection: Supports application/json, */*, application/*. Disable origin MIME sniffing to prevent bypasses.
JWT Validation
Setup token config:
Security > API Shield > Settings > JWT Settings > Add configuration
- Name: "Auth0 JWT Config"
- Location: Header/Cookie + name (e.g., "Authorization")
- JWKS: Paste public keys from IdP
Create validation rule:
Security > API Shield > API Rules > Add rule
- Hostname: api.example.com
- Deselect endpoints to ignore
- Token config: Select config
- Enforce presence: Ignore or Mark as non-compliant
- Action: Log/Block/Challenge
Rate limit by JWT claim:
lookup_json_string(http.request.jwt.claims["{config_id}"][0], "sub")
Special cases:
- Two JWTs, different IdPs: Create 2 configs, select both, "Validate all"
- IdP migration: 2 configs + 2 rules, adjust actions per state
- Bearer prefix: API Shield handles with/without
- Nested claims: Dot notation
user.email
Mutual TLS (mTLS)
Setup:
SSL/TLS > Client Certificates > Create Certificate
- Generate CF-managed CA (all plans)
- Upload custom CA (Enterprise, max 5)
Configure mTLS rule:
Security > API Shield > mTLS
- Select hostname(s)
- Choose certificate(s)
- Action: Block/Log/Challenge
Test:
openssl req -x509 -newkey rsa:4096 -keyout client-key.pem -out client-cert.pem -days 365
curl https://api.example.com/endpoint --cert client-cert.pem --key client-key.pem
Session Identifiers
Critical for BOLA Detection, Sequence Mitigation, and analytics. Configure header/cookie that uniquely IDs API users.
Examples: JWT sub claim, session token, API key, custom user ID header
Configure:
Security > API Shield > Settings > Session Identifiers
- Type: Header/Cookie
- Name: "X-User-ID" or "Authorization"
BOLA Detection
Detects Broken Object Level Authorization attacks (enumeration + parameter pollution).
Enable:
Security > API Shield > Schema Validation > [Select Schema] > BOLA Detection
- Enable detection
- Threshold: Sensitivity level (Low/Medium/High)
- Action: Log or Block
Requirements:
- Schema Validation 2.0 enabled
- Session identifiers configured
- Minimum traffic: 1000+ requests/day per endpoint
Authentication Posture
Identifies unprotected or inconsistently protected endpoints.
View report:
Security > API Shield > Authentication Posture
- Shows endpoints lacking JWT/mTLS
- Highlights mixed authentication patterns
Remediate:
- Review flagged endpoints
- Add JWT validation rules
- Configure mTLS for sensitive endpoints
- Monitor posture score
Volumetric Abuse + GraphQL
Volumetric Abuse Detection:
Security > API Shield > Settings > Volumetric Abuse Detection
- Enable per-endpoint monitoring, set thresholds, action: Log | Challenge | Block
GraphQL Protection:
Security > API Shield > Settings > GraphQL Protection
- Max query depth: 10, max size: 100KB, block introspection (production)
Terraform
# Session identifier
resource "cloudflare_api_shield" "main" {
zone_id = var.zone_id
auth_id_characteristics {
type = "header"
name = "Authorization"
}
}
# Add endpoint
resource "cloudflare_api_shield_operation" "users_get" {
zone_id = var.zone_id
method = "GET"
host = "api.example.com"
endpoint = "/api/users/{id}"
}
# JWT validation rule
resource "cloudflare_ruleset" "jwt_validation" {
zone_id = var.zone_id
name = "API JWT Validation"
kind = "zone"
phase = "http_request_firewall_custom"
rules {
action = "block"
expression = "(http.host eq \"api.example.com\" and not is_jwt_valid(http.request.jwt.payload[\"{config_id}\"][0]))"
description = "Block invalid JWTs"
}
}
See Also
- api.md - API endpoints and Workers integration
- patterns.md - Firewall rules and deployment patterns
- gotchas.md - Troubleshooting and limits