Entity reference
All eight entities are ordinary Otoroshi entities: full CRUD in the admin UI, the admin API,
import/export, and Kubernetes CRDs. They share the API group waf.extensions.cloud-apim.com/v1 and
carry the usual _loc, id, name, description, tags and metadata fields.
WafConfig
waf-configs · waf.extensions.cloud-apim.com/WafConfig
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
block | boolean | true |
rulesets | string[] | [] — WafRuleset ids, applied in order before the inline rules |
rules | string[] | [] — inline rules, applied last |
inspect_input_body | boolean | true |
input_body_limit | number | null | null — meaning the 2 MB default, never unlimited |
inspect_output_body | boolean | true |
output_body_limit | number | null | null — same default |
output_body_mimetypes | string[] | [] — matched on the media type alone, wildcards allowed |
oversize_body_action | inspect_prefix | reject | inspect_prefix |
decompressed_input_body_limit | number | null | null — 64 MiB; 0 turns it off |
max_input_compression_ratio | number | null | null — 100; 0 turns it off |
undecodable_body_action | reject | inspect_raw | reject |
WafRuleset
waf-rulesets · waf.extensions.cloud-apim.com/WafRuleset
| Field | Type | Default |
|---|---|---|
enabled | boolean | true — a disabled ruleset contributes nothing to the configs referencing it |
rules | string[] | [] |
A named body of SecLang that several configs can share. See rulesets.
ThreatFeed
threat-feeds · waf.extensions.cloud-apim.com/ThreatFeed
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
url | string | "" |
method | string | GET |
headers | object | {} |
follow_redirects | boolean | true |
format | cidr_lines | csv | json_array | json_path | misp | cidr_lines |
options | object | {} |
refresh_interval_seconds | number | 3600 |
timeout_millis | number | 30000 |
max_entries | number | 2000000 |
weight | number | 50 |
action | block | monitor | monitor |
tag | string | feed:<id> |
catalog_ref | string | null | null |
Format options
| Format | Option | Default |
|---|---|---|
csv | column | 0 |
csv | separator | , |
csv | skip_header | false |
json_array | field | — |
json_path | path | required |
CrowdSecBouncer
crowdsec-bouncers · waf.extensions.cloud-apim.com/CrowdSecBouncer
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
lapi_url | string | http://127.0.0.1:8080 |
api_key | string | "" |
poll_interval_seconds | number | 10 |
timeout_millis | number | 10000 |
scopes | string[] | ["ip", "range"] |
origins_filter | string[] | [] |
weight | number | 90 |
action | block | monitor | block |
tag | string | crowdsec |
push_enabled | boolean | false |
push_machine_id | string | "" |
push_password | string | "" |
push_scenario | string | cloud-apim/otoroshi-reputation |
push_interval_seconds | number | 10 |
push_max_batch | number | 50 |
push_with_decision | boolean | false |
push_decision_duration | string | 4h |
push_waf_detections | boolean | false |
push_waf_monitored | boolean | false |
AsnDatabase
asn-databases · waf.extensions.cloud-apim.com/AsnDatabase
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
url | string | https://iptoasn.com/data/ip2asn-v4.tsv.gz |
gzip | boolean | true |
format | iptoasn_tsv | iptoasn_tsv |
refresh_interval_seconds | number | 86400 |
timeout_millis | number | 120000 |
max_entries | number | 1500000 |
categories | AsnCategory[] | cdn (0), vpn (30), hosting (15) |
AsnCategory
| Field | Type | Default |
|---|---|---|
name | string | — |
weight | number | 0 |
action | block | monitor | monitor |
tag | string | asn:<name> |
org_contains | string[] | [] — case-insensitive substrings of the organisation name |
asns | number[] | [] — explicit AS numbers, matched first |
The list is ordered: the first matching category wins. See ASN classification.
GeoDatabase
geo-databases · waf.extensions.cloud-apim.com/GeoDatabase
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
url | string | https://download.db-ip.com/free/dbip-country-lite-{yyyy}-{MM}.mmdb.gz |
username | string | — · basic auth, the account id for MaxMind |
password | string | — · basic auth, the license key for MaxMind |
headers | object | {} |
refresh_interval_seconds | number | 86400 |
timeout_millis | number | 300000 |
max_size_mb | number | 512 — once extracted |
attribution | string | IP Geolocation by DB-IP |
attribution_url | string | https://db-ip.com |
Any MaxMind DB file, raw, gzipped or in a tar.gz. See Geolocation.
ThreatPolicy
threat-policies · waf.extensions.cloud-apim.com/ThreatPolicy
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
dry_run | boolean | true — records, enforces nothing |
tiers | ThreatTier[] | log at 40, tarpit at 70, ban at 90 |
exemptions | string[] | [] — addresses and CIDRs that bypass the fabric |
ban_identity | auto | ip | apikey | auto |
waf_block_weight | number | 50 |
challenge_provider | string | null | null — required by a challenge tier |
slow_refusal_millis | number | 0 — how long a refusal is held before it is sent |
ThreatTier
| Field | Type | Default |
|---|---|---|
min_score | number | — |
action | log | challenge | throttle | tarpit | deny | ban | log |
tarpit_millis | number | 3000 |
ban_for_seconds | number | 3600 |
status | number | 403 |
throttle_quota | number | 20 — requests a throttle tier lets through per window |
throttle_window_seconds | number | 10 |
An unrecognised action degrades to log, never to deny. An action is accepted only once something
implements it: one with no module behind it would be a tier that silently does nothing.
BotPolicy
bot-policies · waf.extensions.cloud-apim.com/BotPolicy
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
signatures | BotSignature[] | the 27 built-in ones |
rules | BotRule[] | allow search and monitoring, monitor ai, monitor seo at weight 10 |
verify_known_bots | boolean | true — forward-confirmed reverse DNS |
verified_bypass | boolean | true — a verified crawler is let through |
impersonator_weight | number | 60 — what a failed verification is worth |
impersonator_action | allow | monitor | deny | deny |
unknown_bot_weight | number | 0 |
deny_status | number | 403 |
robots_extra | string | "" — appended to the generated robots.txt |
llms_txt | string | "" |
BotRule
| Field | Type | Default |
|---|---|---|
target | category:<name> | name:<bot> | * | * |
action | allow | monitor | deny | monitor |
weight | number | 0 |
Categories are search, ai, seo and monitoring. There is no challenge action here on
purpose — give the rule a weight that reaches a challenge tier in the threat policy, so the
decision stays in one place. See verified crawlers.
ChallengeProvider
challenge-providers · waf.extensions.cloud-apim.com/ChallengeProvider
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
kind | pow | vendor | pow |
difficulty_floor | number | 18 — leading zero bits at the low end |
difficulty_ceiling | number | 24 — reached by a high-scoring caller |
challenge_ttl_seconds | number | 300 |
clearance_ttl_seconds | number | 1800 |
cookie_name | string | cloud-apim-clearance |
secret | string | "" — falls back to the extension secret |
bind_ip / bind_ua | boolean | true — clearance is not transferable |
title / message | string | interstitial copy |
kind: vendor adds preset_ref, widget_script_url, widget_html, response_field,
verify_url, site_key and secret_key. The Challenge presets page fills those in for
Friendly Captcha, captcha.eu, Turnstile and hCaptcha. See challenges.
HoneypotPolicy
honeypot-policies · waf.extensions.cloud-apim.com/HoneypotPolicy
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
paths | string[] | /.env, /.git/config, … |
weight | number | 100 |
action | monitor | deny | ban | deny |
ban_for_seconds | number | 86400 |
status | number | 404 — a decoy should look like it does not exist |
canaries | CanaryToken[] | [] |
CanaryToken
| Field | Type | Default |
|---|---|---|
value | string | — |
description | string | "" |
where | any | header | path | query | any |
This one is evaluated before routing, from the global configuration — it has no route plugin. See honeypots.
AlertRule
alert-rules · waf.extensions.cloud-apim.com/AlertRule
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
trigger | incident | ban | burst | incident |
min_score | number | 70 — incident: the highest score it reached |
min_count | number | 1 — incident: the decisions it folds |
enforced_only | boolean | true — incident and burst: count only what was enforced |
categories | string[] | [] — every category |
routes | string[] | [] — every route, by id or name |
burst_threshold | number | 100 |
burst_window_seconds | number | 60 |
cooldown_seconds | number | 900 — one alert per key within it, cluster-wide |
channel | AlertChannel | Slack |
AlertChannel
| Field | Type | Default |
|---|---|---|
kind | slack | teams | pagerduty | webhook | event | slack |
url | string | "" — PagerDuty's Events API v2 when empty |
routing_key | string | "" — PagerDuty only |
headers | object | {} — webhook only |
timeout_millis | number | 10000 |
See alerting.
MalwareScanner
malware-scanners · waf.extensions.cloud-apim.com/MalwareScanner
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
kind | clamd | icap | clamd |
host | string | 127.0.0.1 |
port | number | 3310 for clamd, 1344 for ICAP |
service | string | avscan — ICAP only |
icap_mode | respmod | reqmod | respmod |
timeout_millis | number | 30000 |
max_file_size | number | 26214400 — keep it under what the scanner accepts |
See malware scanning.
ApiContract
api-contracts · waf.extensions.cloud-apim.com/ApiContract
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
spec | string | an example — the OpenAPI 3.0 or 3.1 document, JSON or YAML |
base_path | string | "" — the path of the contract's first server |
See API contracts. A route names its own under the metadata key
cloud-apim-api-contract.
RuleFeed
rule-feeds · waf.extensions.cloud-apim.com/RuleFeed
| Field | Type | Default |
|---|---|---|
enabled | boolean | true |
url | string | "" — https://, or file: |
headers | object | {} |
trusted_keys | string[] | [] — Ed25519 public keys, PEM or base64 |
allow_unsigned | boolean | false |
packs | string[] | [] — every pack of the feed |
refresh_interval_seconds | number | 3600, at least 60 |
timeout_millis | number | 30000 |
promotion_delay_seconds | number | 0 |
Each pack of an installed version is a WafRuleset with the id rule-feed_<feed>_<pack>, tagged
managed. See rule feeds.
headers on a feed, api_key / push_password on a bouncer, and an alert rule's channel url,
routing_key and headers, all go through Otoroshi's secret filling. Use vault references rather than literal values.