This page describes exactly what happens to each request, for administrators tuning Traffic Guard and anyone reading the event log.
Inspection pipeline
Traffic Guard runs when Omeka has loaded its plugins, before the request is routed, before any controller runs and before any page is built. Command-line runs (background jobs, scripts) are not checked. For every web request:
- If Check requests is off, the request is allowed.
- The client address is
REMOTE_ADDR, or the first entry ofX-Forwarded-Forwhen Behind a proxy is on. - Allowlist. A private or reserved address (when Always allow private networks is on), or one matching the allowlist, is allowed. Nothing is counted or logged.
- Active ban. An address with a ban in force gets a 403, admin pages included; the event is logged with the kind
banned, score 100 and signalactive_ban. - Kind of page. The path, relative to the site, is classified (below). Admin pages are allowed here, with nothing counted or logged.
- Count the request in its kind's one-minute window and read the count back.
- Score it (below). A user-agent allow rule ends here: the request is allowed and not logged.
- Decide. At or above the block score: 403. At or above the slow-down score: 429 with
Retry-After: 60. Otherwise allowed. - Ban automatically on a block, when that is on and no ban is in force.
- Log slowed-down and blocked requests, and allowed ones when Log allowed requests is on.
Any error in this pipeline is written to PHP's error log with a [TrafficGuard] prefix and the request is allowed.
Kinds of page
| Kind | Paths | Limited |
|---|---|---|
admin |
/admin and below |
No |
api |
/api and below (Omeka's REST API) |
Yes |
mcp |
/mcp and below, /.well-known/oauth-…, /.well-known/openid-configuration (MCP Server) |
Yes |
search |
/search, /items/search, and /items/browse or /collections/browse with search, advanced or query in the query |
Yes |
item |
/items/show/…, /collections/show/…, /files/show/…, /exhibits/show/… |
Yes |
global |
Everything else: the home page, browse pages, simple pages, feeds | Yes |
Each kind has its own counter, so 20 searches and 20 record pages in the same minute are counted separately. Files themselves (images, PDFs) are served by the web server without Omeka and are not counted.
Signals and weights
The score is the sum of the weights of the signals that fired, between 0 and 100. If any one signal weighs 80 or more, the score is at least 80, so a clearly bad sign cannot be diluted. Weights depend on the mode.
| Signal | Fires when | Normal | Elevated | Under attack |
|---|---|---|---|---|
ua_rule_block |
A block rule matches the user agent | 80 | 80 | 80 |
empty_ua |
The user agent is missing or blank (not checked for MCP requests) | 25 | 35 | 50 |
bot_ua_pattern |
The user agent contains a built-in bot name (not checked for MCP requests) | 30 | 40 | 60 |
rate_exceeded_soft |
The window's count is over 80 percent of the limit | 20 | 30 | 40 |
rate_exceeded_hard |
The window's count is over the limit | 30 | 45 | 60 |
deep_pagination |
The query has page greater than 50 |
15 | 20 | 30 |
excessive_search |
A search or browse page with a query string over 200 characters | 10 | 15 | 25 |
A matching allow rule is recorded as ua_rule_allow and ends scoring.
Examples in Normal mode (slow down at 40, block at 70):
- A script with
python-requestsgoing over the search limit: 30 + 30 = 60, slowed down. - The same script also asking for
?page=75: 60 + 15 = 75, blocked and banned. - A browser going over the record-page limit: 30, allowed. In Elevated mode it scores 45 and is slowed down.
MCP clients are programs by design, so their user agents are not held against them; rate limits and your own rules still apply.
Built-in bot names
Matched anywhere in the user agent, ignoring case:
masscan, zgrab, nikto, sqlmap, nmap,
python-requests, go-http-client, okhttp,
headless, phantomjs, selenium, puppeteer, playwright,
scrapy, wget/, curl/,
ahrefsbot, semrushbot, dotbot, mj12bot, blexbot, petalbot, bytespider
Search engines such as Googlebot and Bingbot are not on the list. Add a block rule for any crawler you do not want, or an allow rule for a tool you trust.