Skip to main content

Defense Schemas

Defense Schemas let you ingest an OpenAPI 3.x or Swagger 2.0 specification for any proxy host. Aegis parses the spec and auto-generates a set of per-endpoint defense rules that define what is structurally allowed — valid paths, HTTP methods, content-types, parameter names and types, and JSON request body shape. Requests that don’t conform to the schema are blocked or logged depending on the enforcement mode. Defense schema rules are separate from WAF rules. WAF rules detect malicious payloads within requests. Defense schema rules define what a valid request looks like in the first place. Both systems run — defense schemas enforce structure, WAF rules enforce content.
Image

How It Works

                  ┌─────────────────────────────┐
  Upload spec     │                 Aegis                        │
  (file or URL)   │                                              │
       │          │  ┌───────┐    ┌───────────┐     │
      ──────►│  │  Ingestion │─►│  Defense Schema   │    │
                  │  │  (once)    │    │  Rules (stored)   │    │
                  │  └───────┘     └─┬─────────┘    │
                  │                             │ Reload          │
                  │                    ┌────────▼────┐   │
                  │                    │  Compiled Map        │   │
   Requests ──►│                     │  path → method →  │   │
                  │                    │  endpoint rule       │   │
                  │                    └──────────────┘   │
                  └──────────────────────────────┘
  1. You upload an OpenAPI or Swagger spec (file or URL)
  2. Aegis parses the spec, walks every endpoint, and generates a defense rule per path+method
  3. Rules are stored in SQLite and compiled into a fast lookup map during reload
  4. At request time, Aegis looks up the path in the map and validates the request against the matched rule
The spec is parsed once at ingestion. At runtime, it’s just a map lookup and type checks — no OpenAPI parsing on the hot path.

Supported Formats

FormatVersionDetection
OpenAPI3.0.x, 3.1.xopenapi field starts with 3.
Swagger2.0swagger field equals "2.0"
Both JSON and YAML files are supported. Format is auto-detected by content.

Ingestion

Image

From File

Upload a .json or .yaml spec file through the admin UI. Drag-and-drop or click-to-browse

From URL

Provide an HTTP/HTTPS URL to the spec. Aegis fetches, parses, and stores the spec. The URL is saved so you can refresh the schema later to pick up spec changes. Common spec URLs:
  • /openapi.json
  • /swagger.json
  • /api-docs
  • /v3/api-docs
  • /.well-known/openapi.json

What Gets Extracted

For each endpoint (path + method) in the spec, Aegis generates a defense rule containing:
ComponentSourceExample
Path patternSpec path/users/{id}/posts
HTTP methodOperationPOST
Content-typesRequest body content map (v3) or consumes (v2)application/json
Path parametersParameter definitions with in: pathid (integer)
Query parametersParameter definitions with in: querypage (integer, required)
Header parametersParameter definitions with in: headerX-Api-Version (string)
Body schemaRequest body JSON schemaProperties, types, required fields, enums

Enforcement Modes

Each defense schema has its own mode, independent of the host’s WAF mode:
ModeBehavior
EnforceBlock requests that violate the schema. Returns the appropriate HTTP status code (400, 404, 405, 415).
DetectLog violations but allow the request through. Violations appear in traffic logs with category defense_schema.
OffSchema is stored but not evaluated at runtime.

What Gets Validated

When a request arrives and matches a defense schema endpoint:
CheckHTTP CodeExample Violation
Undefined path404POST /api/v3/unknown — path not in spec
Wrong method405DELETE /users — spec only allows GET, POST
Wrong content-type415text/plain body when spec requires application/json
Missing required parameter400Query param page missing when spec marks it required
Invalid parameter type400?page=abc when spec says integer
Invalid path parameter400/users/abc when spec says {id} is integer
Missing required body field400JSON body missing email when schema requires it
Wrong body field type400"age": "twenty" when schema says integer
Extra body field (strict)400"hack": "value" not defined in schema, strict mode on
Invalid enum value400"status": "banana" when enum is ["active", "inactive"]

Options

SettingDefaultDescription
Block Undefined PathsfalseReject requests to paths not defined in the spec
Strict BodyfalseReject request body fields not defined in the schema
When Block Undefined Paths is off, requests to paths not covered by the schema pass through to the normal WAF pipeline without defense schema evaluation. When Strict Body is on, any JSON field in the request body that is not defined in the schema properties is rejected. This prevents attackers from injecting unexpected fields.

Multiple Schemas Per Host

A host can have multiple defense schemas — for example, one per API version or per microservice behind the same domain. When multiple schemas are attached to a host, they stack: the first schema that matches the request path wins. This allows versioned APIs (/api/v1/*, /api/v2/*) to each have their own spec.

Pipeline Position

Defense schema evaluation runs inside the WAF pipeline, after body size checks and before CORS validation:
WAF Mode Check


IP Checks (allowlist, timeout, blacklist)


Method Restriction


Body Size Limit


Defense Schema Evaluation  ◄── HERE


CORS Validation


Rate Limiting


WAF Rule Chain


Correlation (Mnemos)


Reverse Proxy
Defense schemas and WAF rules are independent. A request that passes defense schema validation still goes through the full WAF rule chain. A request blocked by a defense schema never reaches the WAF rules.

Lifecycle

Creation

  1. Navigate to the Defense Schemas page
  2. Click + New Schema
  3. Choose From URL or From File
  4. Select the target host and set the enforcement mode
  5. Upload or enter the URL — Aegis parses the spec and shows the generated rules
  6. Each endpoint rule can be individually enabled or disabled

Updates

  • Refresh (URL sources only): Re-fetch the spec from the original URL, regenerate rules, and preserve per-rule enabled/disabled state
  • Mode change: Switch between enforce, detect, and off at any time
  • Rule toggle: Enable or disable individual endpoint rules without deleting the schema

Deletion

Deleting a defense schema removes all its rules. This is immediate — no confirmation beyond the delete dialog. Deleting a proxy host cascades to delete all its defense schemas.

Relationship to WAF Rules

Defense Schema RulesWAF Rules
PurposeDefine valid request structureDetect malicious payloads
SourceAuto-generated from OpenAPI/Swagger specBuilt-in OWASP rules + custom authored rules
Storagedefense_schemas tablewaf_rules table
ScopePer endpoint (path + method)Per host or global
EvaluationBefore WAF rule chainAfter defense schema check
ManagementDefense Schemas pageRules page
CascadeDeleted with schema or hostIndependent lifecycle
Both systems are complementary. Defense schemas say “this endpoint expects a POST with a JSON body containing a name string and an age integer.” WAF rules say “this JSON body contains a SQL injection payload in the name field.” A properly protected host uses both.

API Reference

MethodPathDescription
GET/api/v1/defense-schemas?host_id={id}List defense schemas for a host
GET/api/v1/defense-schemas/{id}Get a defense schema with all its rules
POST/api/v1/defense-schemas/ingestIngest a new spec (file upload or URL)
PUT/api/v1/defense-schemas/{id}Update schema settings (mode, options)
DELETE/api/v1/defense-schemas/{id}Delete a defense schema and all its rules
PUT/api/v1/defense-schemas/{id}/rules/{index}Toggle or update an individual endpoint rule
POST/api/v1/defense-schemas/{id}/refreshRe-ingest from the original URL

Defense Schema Object

FieldTypeDescription
idintegerSchema ID
host_idintegerAssociated proxy host
namestringUser-provided label
spec_formatstringopenapi3 or swagger2
spec_versionstringSpec version (e.g., 3.0.3, 2.0)
spec_titlestringTitle from the spec’s info block
source_typestringfile or url
source_urlstringOriginal URL (if ingested from URL)
modestringenforce, detect, or off
block_undefinedbooleanBlock requests to paths not in the spec
strict_bodybooleanReject extra body fields not in the schema
endpoint_countintegerNumber of generated endpoint rules
schema_countintegerNumber of named schemas in the spec
rulesarrayList of DefenseSchemaRule objects
enabledbooleanWhether the schema is active

Defense Schema Rule Object

FieldTypeDescription
pathstringEndpoint path pattern (e.g., /users/{id})
methodstringHTTP method
operation_idstringOperation ID from the spec
summarystringOperation summary from the spec
enabledbooleanWhether this endpoint rule is active
content_typesarrayAllowed request content-types
parametersarrayExpected parameters with name, location, type, and constraints
body_schemaobjectExpected JSON body structure with properties, types, and required fields