OAShield is configured through the OpenAPI Generator --additional-properties
flag. This page documents the available options, the two engine flavors, and
the known limitations of request-body validation.
| Option | Default | Description |
|---|---|---|
engineFlavor |
modsecurity3 |
Target engine: modsecurity3 or coraza |
validateBodySchema |
true |
Emit request-body validation rules |
generateJsonSchema |
true |
Emit the JSON Schema file |
jsonSchemaOutputFile |
schema.json |
JSON Schema file name |
schemaRulePath |
same as jsonSchemaOutputFile |
Schema path written inside the @validateSchema rule. Coraza resolves it relative to the server process working directory, not the rules directory |
denyAction |
deny |
What happens when a rule blocks: deny, drop, redirect, or pass (detection-only: violations are logged but requests go through) |
denyStatus |
403 |
HTTP status returned on deny (100–599). With denyAction=redirect, set a 3xx — non-3xx values make the engine fall back to 302 |
denyRedirectUrl |
— | Absolute http(s) URL to redirect blocked requests to; required when denyAction=redirect |
enableLogging |
true |
Emit log,auditlog on generated rules; false emits nolog instead |
includeEngineConfig |
true |
Emit SecRuleEngine On, SecRequestBodyAccess On, and the SecDefaultAction in mainconfig.conf. Set false when your existing WAF configuration already defines these |
unknownMediaTypePolicy |
pass |
Handling of declared request media types the WAF cannot inspect (e.g. application/octet-stream, text/plain): pass lets them through after the content-type gate, block rejects them |
basePath |
auto | Path prefix for all generated path-match rules. Defaults to the path component of the spec's first servers.url (server variables match one path segment). Pass an empty string to disable prefixing |
validateXmlSchema |
false |
Generate an XSD from the models and emit @validateSchema XML rules (modsecurity3 flavor only). Off by default because current libmodsecurity3 cannot load XSDs at request time (its XXE hardening breaks the schema load, blocking all XML) and Coraza has no XML support — see docs/engine-behavior.md |
xsdOutputFile |
schema.xsd |
XSD output file name |
xsdRulePath |
same as xsdOutputFile |
XSD path written inside the @validateSchema XML rule |
Pass them comma-separated:
... generate -g modsecurity3 -i api.yaml -o out \
--additional-properties engineFlavor=coraza,schemaRulePath=rules/schema.jsonEvery generated rule uses the block action, so the actual disruptive
behavior is decided in one place: the SecDefaultAction emitted at the top of
mainconfig.conf. denyAction/denyStatus/denyRedirectUrl control that
line:
# Return 429 instead of 403
--additional-properties denyStatus=429
# Detection-only: log violations, let requests through
--additional-properties denyAction=pass
# Redirect blocked requests
--additional-properties denyAction=redirect,denyRedirectUrl=https://example.com/blocked,denyStatus=302If your ModSecurity/Coraza deployment already configures the engine (rule
engine mode, body access, default action), generate only the rules with
includeEngineConfig=false — your existing SecDefaultAction then decides
what blocking means.
Most generated rules are identical across both engines — the flavor only changes how JSON request bodies are validated.
| Flavor | JSON body validation |
|---|---|
modsecurity3 (default) |
Per-field rules generated from the OpenAPI schema: required-property presence, per-property type patterns, numeric minimum/maximum, and an ARGS_NAMES allowlist that rejects undeclared properties (additionalProperties) |
coraza |
The same per-field rules plus a @validateSchema rule that validates the raw body against the generated JSON Schema. @validateSchema is Coraza-only — ModSecurity v3's operator of the same name is XSD/XML-only |
These apply to the modsecurity3 flavor's per-field checks. Coraza's
@validateSchema additionally covers all of them:
- Type coercion: values are validated after the engine flattens JSON to
strings, so a JSON number where a free-form string is expected
(e.g.
"name": 123) is not distinguishable. requiredscope: enforced for object properties (nested ones only when their parent object is present, per JSON Schema semantics), but not per array element. An empty array satisfies a required array property only on thecorazaflavor.- Nesting depth: model nesting is flattened to 5 levels; deeper properties are covered only by the unknown-property allowlist.
- Numeric bounds on path parameters:
minimum/maximumon path parameters is enforced only lexically, via the embedded path pattern. oneOf/anyOfcomposition: enforced as the union of the member schemas. Primitive unions (including composed query/path parameters) are validated against an alternation of the member patterns; model unions validate and allowlist the properties of every branch, butrequiredproperties inside a branch are not enforced (only one branch need be present), andoneOf's exactly-one semantics are not distinguished fromanyOf.allOfmodels are validated fully (members are merged). The generated JSON Schema keeps the exactoneOf/anyOfkeywords for Coraza's@validateSchema.