Files
dotfiles/.agents/skills/cloudflare-deploy/references/api-shield/configuration.md
2026-03-17 16:53:22 -07:00

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:

  1. Review flagged endpoints
  2. Add JWT validation rules
  3. Configure mTLS for sensitive endpoints
  4. 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