API Armor
Overview
API Armor provides GraphQL query analysis, JSON schema validation, JWT/API-key auth validation, multi-dimensional behavioral profiling, and per-endpoint rate limiting. It is gated behind the api_armor_enabled feature flag.
GraphQL Analysis
API Armor parses GraphQL queries and extracts:
- Operation type (query, mutation, subscription)
- Depth
- Complexity
- Field count
- Alias count
- Fragment count
- Query hash
These metrics are available in Security Rule expressions and used by preset rules to block abusive queries.
JSON Schema Validation
API Armor validates request bodies against JSON schemas:
- OpenAPI spec import — parse JSON or YAML OpenAPI specs, extract per-endpoint schemas, resolve
$refreferences - Schema inference — learn schemas from observed traffic
- Schema merging — merge inferred schemas with imported schemas
- Validation rules: type, properties, required, items, minLength/maxLength, minimum/maximum, enum, pattern, additionalProperties
Auth Validation
API Armor validates authentication on API requests:
| Auth Type | Description |
|---|---|
| JWT | HS256/HS384/HS512 with issuer, audience, and expiry checks |
| API Key | Validate against configured API key lists |
| Bearer | Extract and validate bearer tokens |
Auth type is auto-detected and exposed as auth.type in Security Rules. The auth.valid boolean indicates whether validation passed.
Behavioral Profiling
API Armor tracks 7 dimensions per endpoint:
| Dimension | Description |
|---|---|
| Body structure | JSON shape of the request body |
| GraphQL metrics | Depth, complexity, field count, etc. |
| Content type | Request Content-Type |
| Auth type | Detected auth type |
| Request fingerprint | JA4 and request fingerprint subfields |
| Param keys | Query parameter names |
| Param types | Query parameter value types |
Profiles are marked “learned” after min_samples observations (default 100). When a request deviates from a learned profile, an anomaly is detected and available in Security Rule expressions.
Preset Rules
coreX Manager ships preset GraphQL security rules:
- Depth limit
- Complexity limit
- Field count limit
- Alias count limit
- Query length limit
These can be enabled with a single click and tuned per listener.
Per-Endpoint Rate Limiting
The RateLimit model has path_pattern, method, and api_armor_scoped columns for scoping rate limits to specific endpoints. This integrates with the Rate Limiting feature.
Security Rules Integration
The following fields from API Armor are available in Security Rule expressions:
- Request fingerprint subfields
- GraphQL fields (depth, complexity, field count, etc.)
- Schema validation fields
- Auth fields (
auth.valid,auth.type) - Profile anomaly fields
Conditional Body Buffering
When API Armor is enabled, http-request buffer-request and lua.api_body_parse are emitted on every listener. API_ARMOR_MAX_BODY_BYTES caps the buffer size to prevent memory exhaustion from large payloads.
Profiling Log
A Rust module writes one JSON line per request to profiling.log. The ApiArmorProfiler sampler tails the log and upserts ApiProfile rows for behavioral profiling.
Frontend
The API Armor page has 8 tabs:
| Tab | Description |
|---|---|
| Settings | Enable/disable, configure min_samples, body size limits |
| Preset Rules | Enable and configure GraphQL security presets |
| OpenAPI Specs | Import and manage OpenAPI specs |
| Schemas | View and edit JSON schemas per endpoint |
| Auth Policies | Configure JWT and API key validation |
| API Key Lists | Manage API key lists |
| Profiles | View learned behavioral profiles |
| Anomalies | View detected anomalies |
Step-by-Step: Enable API Armor
- Navigate to Protection > API Armor > Settings
- Toggle Enable API Armor on
- Set
min_samplesto 100 (or lower for faster learning) - Set
API_ARMOR_MAX_BODY_BYTESto an appropriate value (default 1MB) - Click Save and Apply Changes
Step-by-Step: Import an OpenAPI Spec
- Navigate to Protection > API Armor > OpenAPI Specs
- Click Import Spec
- Upload a JSON or YAML file, or paste the URL
- coreX Manager parses the spec, extracts per-endpoint schemas, and resolves
$refs - Review the extracted schemas in the Schemas tab
Step-by-Step: Create an Auth Policy
- Navigate to Protection > API Armor > Auth Policies
- Click Add Policy
- Select auth type: JWT
- Configure:
- Algorithm: HS256
- Secret: your HMAC secret
- Issuer:
https://auth.example.com - Audience:
api.example.com
- Save and Apply
Step-by-Step: Apply Preset Rules
- Navigate to Protection > API Armor > Preset Rules
- Enable Depth Limit and set max depth to 10
- Enable Complexity Limit and set max complexity to 1000
- Save and Apply
Step-by-Step: Finalize a Profile
- Send representative traffic to your API endpoints
- Navigate to Protection > API Armor > Profiles
- Wait for profiles to reach “learned” status (min_samples observations)
- Review the learned dimensions
- Once learned, anomalies will be detected for deviating requests
Verification
-
Check profiling log:
tail -f /app/data/profiling.logEach request should produce one JSON line.
-
Test schema validation:
# Valid request curl -k -X POST https://localhost/api/users -H "Content-Type: application/json" -d '{"name":"test"}' # Invalid request (wrong type) curl -k -X POST https://localhost/api/users -H "Content-Type: application/json" -d '{"name":123}' -
Test GraphQL depth limit:
curl -k -X POST https://localhost/graphql -H "Content-Type: application/json" -d '{"query":"{ user { posts { comments { user { posts { comments { user { posts } } } } } } } }"}'Expect a rejection if depth exceeds the preset limit.
-
Check anomalies:
- Navigate to Protection > API Armor > Anomalies
- Send a request that deviates from learned profiles
- Verify it appears in the anomalies list
Next Steps
- Security Rules — Use API Armor fields in access control rules
- Rate Limiting — Configure per-endpoint rate limits
- Risk Scoring — Score API requests based on anomalies