Skip to main content

Best Practices

Practical guidance for building, testing, and debugging EaaS tenant configurations.

Security Configuration

Start with Core Protections

Enable essential WAF groups first, then add more as you monitor false positives:

JSON
{
"security_config": {
  "deny_groups": [
    "SQL-INJECTION-ANOMALY",
    "XSS-ANOMALY",
    "CMD-INJECTION-ANOMALY"
  ]
}
}

Use Specific Exceptions

When adding exceptions, scope them as narrowly as possible. Combine multiple exception types (paths + IPs + ASNs) to avoid over-permitting:

JSON
{
"security_config": {
  "exceptions": {
    "SQL-INJECTION-ANOMALY": {
      "paths": ["/api/search"],
      "v4_ips": ["192.0.2.0/24"]
    }
  }
}
}

Avoid broad exceptions like exempting an entire /api/ prefix or a /0 CIDR block from all rules.

Rate Control Tiers

Security groups IPBLOCK-BURST and IPBLOCK-SUMMARY provide rate limiting. The thresholds are configured at the security policy level. Common tiers:

PostureBurst / SummaryProtection Level
Relaxed200 / 180Low — lenient, few false positives
Balanced35 / 30Moderate — good default
Protective25 / 20Substantial — some false positives expected
Strict10 / 8High — aggressive, higher false positive risk

Delivery Configuration

Rule Ordering

Most delivery features use a rule-based structure where the first matching rule wins. Order rules from most specific to least specific:

JSON
{
"caching": {
  "rules": [
    {
      "matchAll": { "paths": ["/api/v2/users/*"] },
      "args": { "bypass": true }
    },
    {
      "matchAll": { "paths": ["/api/*"] },
      "args": { "ttl_seconds": 300 }
    },
    {
      "args": { "ttl_seconds": 3600 }
    }
  ]
}
}

In this example: user API requests bypass cache, other API requests cache for 5 minutes, everything else caches for 1 hour. If the broad /api/* rule were first, the specific /api/v2/users/* rule would never fire.

Match Condition Efficiency

  • Prefer prefix matching (paths_startswith) over wildcard matching (paths_wildcard) when possible — it's faster.
  • Use matchAll (AND) for common cases. Use matchAny (OR) only when you genuinely need "any of these conditions."
  • Keep match arrays reasonable. Each match condition supports up to 100 values, but smaller arrays evaluate faster.

Simple vs Rule-Based

Some features accept both a simple value and a rule-based structure. Use the simple form when you don't need conditional logic:

JSON
// Simple: applies to all requests
{ "connectTimeout": 5000 }

// Rule-based: different timeout for different paths
{
"connectTimeout": {
  "rules": [
    {
      "matchAll": { "paths": ["/slow-api/*"] },
      "args": { "value": 30000 }
    }
  ]
}
}

Testing Your Configuration

1. Validate Against the Schema

Before deploying, validate your tenant JSON:

  • Online: Paste your config into the Tenant Validator
  • CLI: Use check-jsonschema with the schema file:
pip install check-jsonschema
check-jsonschema --schemafile tenant-schema.json my-tenant.json
  • IDE: Point your editor's JSON Schema validation at the schema file for real-time feedback.

2. Use Debug Headers

EaaS supports debug response headers that reveal how the edge processed your request. Add the debug header to your request:

curl -s -D - -o /dev/null \
-H "x-eaas-debug: <your-debug-key>" \
https://your-tenant-hostname.example.com/test-path

The debug key is configured via the PMUSER_EAAS_DEBUG_KEY variable in your Property Manager configuration. Contact your Akamai representative if you don't know your debug key.

3. Bypass the Tenant Cache

The EdgeWorker caches tenant files briefly (approximately 3 minutes). When testing configuration changes, bypass the cache to force a fresh read:

curl -s -D - -o /dev/null \
-H "x-eaas-debug: <your-debug-key>" \
-H "x-bypass-lru: true" \
https://your-tenant-hostname.example.com/test-path

4. Test on Staging First

Always test configuration changes on the Akamai staging network before activating on production. Use --resolve to point your request at the staging IP:

curl --resolve "your-hostname.example.com:443:<staging-ip>" \
-H "x-eaas-debug: <your-debug-key>" \
https://your-hostname.example.com/test-path

Debug Response Headers

When the x-eaas-debug header is included in your request, the edge returns these response headers:

General

HeaderDescription
x-eaas-tenant-logSummary log line: GRN, deny reason, sub-request GRN, LRU cache object size, sub-request status code
x-eaas-route-usedWhich conditional origin was used by the route feature

Caching

HeaderDescription
x-eaas-edgeworker-ttlTTL value set by the EdgeWorker
x-eaas-cache-matchWhether a caching rule was triggered. Values: no-store, bypass, or TTL in seconds
x-eaas-honor-originWhether origin cache-control headers are being honored
x-eaas-must-revalidateWhether must-revalidate is enabled
x-eaas-internal-ttlActual TTL on the edge. -1 means not cacheable
x-eaas-content-sourceWhere the response was served from (cache, origin, etc.)
x-eaas-current-ageCurrent age of the cached object

Tenant Log Format

The x-eaas-tenant-log header value follows this format:

grn=<request-grn>,deny=<deny-reason>,srq_code=<status>,srq_grn=<subrequest-grn>,lru_obj_size=<bytes>
FieldDescription
grnGlobal Request Number — unique identifier for this request
denyWAF deny reason (empty if not denied)
srq_codeHTTP status code from the tenant file sub-request (200 = OK)
srq_grnGRN of the sub-request used to fetch the tenant file
lru_obj_sizeSize of the tenant file in the EdgeWorker's LRU cache (bytes)

Schema Limits Reference

Key limits defined in the tenant schema:

PropertyLimit
Tenant file sizeRecommended under 10KB
tenant_id (string)Max 20 characters
tenant_id (array)Max 5 entries
ttl_seconds0 — 31,536,000 seconds (0 to 1 year)
connectTimeout50 — 120,000 ms
firstByteTimeout50 — 120,000 ms
readTimeout50 — 120,000 ms
Match condition arraysMax 100 values per condition
Security exception arraysMax 50 values per exception field