How do I set up a positive security model for an API (allowed endpoints, methods, parameters)?
Short answer
The positive model is set up with page types: every endpoint is a page type (an exact path or a glob such as /api/v1/users/*), the allowed methods are defined in the Allowed Methods field, and the allowed and required query parameters, headers and JSON keys are defined in the Query, Header and JSON tabs of that page type. To reject endpoints that are not in the definition, the Allowed methods value of the Any Paths rule is set to None; every request that matches no page type becomes a 24-point Allowed methods violation and on its own exceeds the blocking threshold at every protection level. The rule set is set up in four ways: Import (OpenAPI) from the OpenAPI definition, Analysis & Learning by learning the traffic (for an API, Comprehensive mode with the Only Browsers check mark removed; unknown or suspicious paths in the result are removed from the analysis before applying), Add manually on the Page Types screen, or the waf fw-rules and waf rule-parts commands in WEB-CLI. The allow and requirement lists are applied while Argument Checks in Checks is on, the length and depth limits while Structure Checks is on, and while the host group is in Monitor or Blocking mode; they are not applied in Learning mode. The rule is per path: POST and PUT requests coming to the same path share the checks of the same page type.
Problem: Only Defined Requests Should Reach the API
Signature scanning catches known attack patterns; however, it does not know which endpoints, which methods and which parameters an API accepts. A request made to an undefined endpoint, an unexpected parameter or a method that is not allowed (e.g. DELETE) passes because it has no signature. In the positive model, on the other hand, the expected shape of the API is defined, and every request outside this shape becomes a 24-point structural violation (What is the difference between the negative security model (signature scanning) and the positive security model?). The two models combine in the same score; signature scanning continues to work together with the positive model (hybrid security model).
Solution: 4 Methods
The methods set up the rule set from different sources; they can also be used together (e.g. importing from OpenAPI and completing what is missing manually). The prerequisites are the same in all of them: WAF is on in the vService (How do I enable WAF protection on a vService?) and, if the API is on a separate domain name, it has its own host group (How is a Host Group added; what goes into the Virtual Host Patterns field?). After the setup, the false positives that come in Monitor mode are processed into the rule set by teaching them from Event Logs (How do I allow a request that was blocked by mistake?).
| Your situation | Suitable method |
|---|---|
| The API has an OpenAPI or Swagger definition | Method 1: Import (OpenAPI) |
| There is no definition; there is API traffic or test traffic can be generated | Method 2: Learning and Analysis & Learning |
| Few endpoints; I want to write the lists manually | Method 3: Manually on the Page Types Screen |
| I want to set it up with a script or automation | Method 4: WEB-CLI |
Method 1: Import (OpenAPI) Recommended
- How it works Every path in the definition turns into a page type:
{id}templates are written as globs, operations into the Allowed Methods list, query and header parameters into the allow and requirement lists, and the field names of the body schema into the JSON, XML or form allow list. The import is merged with the existing rules. - Where it is opened Left Monitor Panel → WAF-Protected vServices → vService → WAF Management → the N page types row on the mode card of the host group → Import (OpenAPI)
- Requirement An OpenAPI 3.0 or Swagger 2.0 file (
.json,.yaml,.yml); modify permission in the WAF area - vService type HTTP
Step-by-Step Configuration
In the Left Monitor Panel → WAF-Protected vServices → vService → WAF Management tab, the pencil icon at the top right of the Checks card in the Inspection & Blocking section is clicked (Checks Edit screen). Structure Checks and Argument Checks must be checked (both are checked by default). If Max. Allowed Arguments (default 25) is smaller than the longest allow list, it is increased; a list that exceeds it is silently disabled for that rule.
If a change was made, Edit is clicked; if there is no change, the window is closed.
On the WAF Management tab, the N page types row below the mode card of the API's host group is clicked; the Page Types tab opens with the name of the host group (accessing the screen).
Export on the toolbar is clicked; the rule set is downloaded as a JSON file. Since the import replaces the existing rules with the same path, this backup is the only way back.
Import (OpenAPI) on the toolbar is clicked and the definition file is selected from the file picker that opens (import steps).
The Are you sure? question is confirmed with Yes. When the operation finishes, the "OpenAPI import: N path applied" notification appears; if there are warnings (e.g. dropped regex patterns), they are listed in the notification. There is no separate deployment step. The limits of the conversion (nested JSON fields, required fields): Can I generate API protection rules automatically from my OpenAPI definition?
In the Page Types list, the italic Any Paths row is selected and Edit on the toolbar is clicked (Editing the Any Paths rule).
Allowed Methods = None is selected. After this setting, every request that matches no page type (including the paths probed by external monitoring systems, static files and documentation pages) becomes a violation; these paths are first added with their own page types (Method 3).
Edit in the form is clicked; the WAF configuration is regenerated and applied. In a cluster, the change is sent to the peer device with the default auto-sync; if Manual Sync Mode is on, it is sent with Synchronize.
Verification
The paths in the definition (the templated ones as globs) appear in the list; when a rule is clicked, Allowed methods is read in the Path tab, and the allow lists in the Query and JSON tabs, of the detail panel that opens.
One rule per path; the N page types count increasedWhile the host group is in Monitor mode, a request is sent to a path that is not in the definition; the Attacks tab of the WAF Event Logs record is checked.
Command: curl -s -o /dev/null -w "%{http_code}\n" https://api.example.com/api/v1/undefined
Allowed methods (24)Method 2: Learning and Analysis & Learning
- How it worksIn Learning mode, the host group writes the API traffic to the learning log; from this log, the analysis produces a page type, a method list and parameter lists for every endpoint.
- Where it is opened Left Monitor Panel → WAF-Protected vServices → vService → WAF Management → the Analysis & Learning text on the mode card of the host group
- Requirement Modify permission in the WAF area; API traffic in the learning log (Learning mode, or in Blocking/Monitor mode, the traffic of the sources selected with Conditional Learning)
- vService type HTTP
Step-by-Step Configuration
As in steps 1–2 of Method 1, Structure Checks, Argument Checks and Max. Allowed Arguments are checked. If Argument Checks is off, the analysis does not suggest allow and requirement lists.
The host group is left in Learning mode and traffic is waited for from the real or test clients of the API (WAF Mode). If the host group is in Blocking or Monitor mode, only the traffic of trusted test sources is recorded with Conditional Learning (What is the difference between Conditional Learning and Teacher; when should I use which?).
On the WAF Management tab, the Analysis & Learning text below the mode card of the host group is clicked; the window titled New Analyze for opens (creating a new analysis).
| Field | Value for an API | Reason |
|---|---|---|
| Ignore Old Rules | Create New Rules (default) | The rule set is set up from scratch |
| Rule Creating Mode | Comprehensive (Each page is learned) (default Data based) | Every endpoint gets its own page type; together with Create New Rules, the Allowed methods value of the Any Paths rule is set to None and every access that has not been learned becomes a violation (What is the difference between the Rule Creating Mode options (Comprehensive, Data Based, Page Independent); which one should I choose?) |
| Only Browsers | The check mark is removed (checked by default) | Otherwise, the traffic of API and mobile clients that are not recognized as browsers never enters the analysis (What are the "Only Domains" and "Only Browsers" filters for?) |
| Country Filter | The countries of the API clients are added or No filter is selected | With the default Use Selected, it is only Local Networks and Turkey; requests coming from other countries do not enter the analysis |
Analyze Date is the last 3 months by default. The window opens with the selections (date range, Rule Creating Mode, filters, Only Browsers) of the analysis the user previously started for this vService; the defaults in the table apply to the first analysis.
Start Analyzing is clicked; the window closes and the progress is followed from the bar on the mode card.
When the analysis finishes, the list of past analyses is opened with the house icon on the mode card, the analysis is selected and the Analyze Page Types tab is opened with Edit, and the generated endpoints are reviewed (Can I review and edit the analysis result before applying it (Analyze Page Types screen)?).
The paths that come out of the analysis are reviewed; only the endpoints for which WAF rules will be created should remain in the list. It is recommended that unknown or suspicious paths (e.g. the addresses tried by scanning tools) be removed from the analysis manually: these paths are selected in the right pane of the Analyze Page Types screen and Exclude from Analysis is clicked; the removed paths do not produce rules.
Apply on the Analyze Page Types screen is clicked and Are you sure? is confirmed; the rules are written to the host group. Applying the result also sets the permanent Rule Creation Policy setting of the vService to the selected mode.
Verification
A rule per endpoint is read in the Page Types list, and the Allowed methods value in the Path tab of the detail panel of the Any Paths row.
Endpoints in the list · Any Paths: Allowed methods NoneMethod 3: Manually on the Page Types Screen
- How it works A page type is added for every endpoint, the methods are selected and the allow lists are written tab by tab; the Any Paths rule is closed.
- Where it is opened Left Monitor Panel → WAF-Protected vServices → vService → WAF Management → N page types → Add · the detail panel that opens when a rule is clicked
- Requirement The list of endpoints, methods and parameters; modify permission in the WAF area
- vService type HTTP
Step-by-Step Configuration
As in steps 1–2 of Method 1, Structure Checks, Argument Checks and Max. Allowed Arguments are checked.
On the WAF Management tab, the N page types row under the mode card of the host group is clicked.
Add on the toolbar is clicked (Add).
The endpoint is written in the Path field: /api/v1/users for a single path, /api/v1/users/* for an endpoint that carries a path parameter (in a glob, * matches one path segment; the trailing / is not written). Allowed Methods = Multiple Methods is selected and the methods of the endpoint (e.g. GET, POST) are checked; the default Any Methods allows every method. The OWASP box is unchecked by default; it is checked so that the path also goes through signature scanning (query, header and body scanning are independent of this box). For a glob path, the pattern is tried with the test table in the form (How do I add a new page type manually?).
Add is clicked. Steps 3–5 are repeated for every endpoint; the paths probed by external monitoring systems and static file paths are also added with these steps.
The rule is clicked in the list; in the detail panel that opens on the right, the Query tab is selected and Add Common Rule for Query is clicked (Add Common Rule for Query screen). The form opens filled with the values of the Any Paths rule.
The Allowed Query Parameters restriction is turned on and the allowed parameter names (e.g. page, size) are added; the required ones are written to the Required Query Parameters list. Name matching is case-sensitive (How do I make sure only the query parameters I allow reach a page (Allowed Query Parameters)?).
Add in the form is clicked.
In the same panel, the Header tab is selected and Add Common Rule for Header is clicked; the headers that the API expects in every request (e.g. authorization, x-api-key) are written to the Required Headers list and Add is clicked (Can I define required parameters (Required Query Parameters / Required Headers / Required Form Fields)?). This check looks at the presence of the header; it does not verify its value.
The JSON tab is selected and Add Common Rule for JSON is clicked; the Allowed JSON Keys restriction is turned on and the key paths in the body are written with dots. In nested paths, the container also enters the list: user and user.email for {"user":{"email":"…"}}. Limits such as JSON Depth are also narrowed here; Add is clicked (Can I allow only specific keys in JSON; how are nested key paths written?).
In the list, the italic Any Paths row is selected and Edit on the toolbar is clicked.
Allowed Methods = None is selected.
Edit in the form is clicked; there is no separate deployment step. In a cluster, the change is sent to the peer device with the default auto-sync; if Manual Sync Mode is on, it is sent with Synchronize.
Verification
A request is sent with a query parameter that is not in the list and the Attacks tab of the Event Logs record is checked.
Command: curl -s -o /dev/null -w "%{http_code}\n" "https://api.example.com/api/v1/users/42?debug=1"
Allowed query parameters (24)A request is sent to the endpoint with a method that is not in the list.
Command: curl -s -o /dev/null -w "%{http_code}\n" -X DELETE https://api.example.com/api/v1/users/42
Allowed methods (24)Method 4: WEB-CLI
- How it works The page type is written with
waf fw-rules add, and the field checks withwaf rule-parts add. The commands require the vService, host group and rule IDs. - Where it is opened WEB-CLI →
waf fw-rules·waf rule-parts - Requirement WEB-CLI access and modify permission in the WAF area; Structure Checks and Argument Checks on in Checks (Method 1, step 1)
- vService type HTTP
Step-by-Step Configuration
In place of <vService>, the ID of the vService is written; the ID of the host group is read from the output:
waf host-groups list poolId <vService>Path is a required field; since other -- fields are also written on the line, it is written in the --path.input form, and a value containing * is given in single quotes. The methods that can be selected in the CLI are GET, HEAD, OPTIONS, POST, PUT, PATCH, DELETE, TRACE and CONNECT. Signature scanning of the path is turned on with --argOwasp (default false):
waf fw-rules add poolId <vService> hostGroupId <group> --path.input '/api/v1/users/*' --allowedMethods.type multiple --allowedMethods.input.0 GET --allowedMethods.input.1 POST --argOwasp trueThe command gives no output when it succeeds.
waf fw-rules list poolId <vService> hostGroupId <group>In place of <rule>, the ID from step 3 is written. Since --arg is not given, the part is applied to all the parameters in the section:
waf rule-parts add poolId <vService> hostGroupId <group> ruleId <rule> loc query --queryAllowedArgs.0 page --queryAllowedArgs.1 sizeFields not written in WEB-CLI are saved with the schema defaults, and these limits differ from the form in the interface: in Query, the key count is at most 16, the key length 1–128, the total size at most 8192, and the length of each value 0–1024; on an endpoint that carries longer values, it is increased with --valueLength.val2 (loc query).
In the JSON part, Block All JSON Contents (--jsonBlockAll) comes as true by default in WEB-CLI; for an endpoint that accepts JSON, if false is not written, all JSON requests coming to this endpoint become violations. Other defaults: key length 1–32, value count (JSON Key Count) at most 1024, depth at most 8, the length of each text value 0–1024, Block Invalid JSON Contents on:
waf rule-parts add poolId <vService> hostGroupId <group> ruleId <rule> loc json --jsonBlockAll false --jsonAllowedArgs.0 user --jsonAllowedArgs.1 user.email- In the list of that step, the Any Paths rule appears as
default rule; its ID is read and the Allowed methods value is set tonone(update changes only the written field):
waf fw-rules update poolId <vService> hostGroupId <group> id <any-paths-id> --allowedMethods.type noneVerification
The parts of the rule are listed.
Command: waf rule-parts list poolId <vService> hostGroupId <group> ruleId <rule>
query and json partsCommon Mistakes
Setting Any Paths to None without defining the auxiliary paths
An Any Paths rule with Allowed methods = None counts every request without a page type as a violation; in Blocking mode, the paths probed by external monitoring systems, static files and documentation pages are also blocked. These paths are added as page types before Any Paths is closed, and the change is first tried in Monitor mode (How do I use Monitor mode to weed out false positives?).
- Forgetting the container path in the JSON list. For
user.email,usermust also be in the list; every path that is not in the list becomes a separate violation. - The list exceeding the Max. Allowed Arguments value. The list is silently disabled for that rule; the value in Checks is kept larger than the longest list.
- Expecting the checks to work in Learning mode. Allow lists and structural limits are applied only in Monitor and Blocking modes.
- Leaving the Only Browsers check mark in the analysis. The traffic of API and mobile clients does not enter the analysis; the analysis produces rules only from browser traffic.
- Not writing the
--jsonBlockAllvalue in WEB-CLI. Since the default istrue, all JSON bodies coming to the endpoint become violations. - Expecting a different body rule per method. The rule is per path; the method is restricted only with Allowed methods, and the POST and PUT bodies of the same path are checked with the same list.
- Switching directly to Blocking mode. The new rule set is first tried with real traffic in Monitor mode (When should I move from Learning to Monitor and from Monitor to Blocking?).
How it is done in the documentation
Related questions
- What is the difference between the negative security model (signature scanning) and the positive security model?
- What is the difference between the Rule Creating Mode options (Comprehensive, Data Based, Page Independent); which one should I choose?
- Can I allow only specific keys in JSON; how are nested key paths written?
- Can I generate API protection rules automatically from my OpenAPI definition?
