# 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:**

```wirefilter
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:**

```bash
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

```hcl
# 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.md) - API endpoints and Workers integration
- [patterns.md](patterns.md) - Firewall rules and deployment patterns
- [gotchas.md](gotchas.md) - Troubleshooting and limits
