Default request limits per minute, hour and day, sized for API use (closes #176)
check / check (push) Successful in 4m53s

The default request limits now suit programmatic use of an API, such
as an automation fleet on another host, and still catch abusive bots:

- per minute: 500, room for a fleet's busiest minute and a few first
  visits with an empty cache, and passed within seconds by a client
  firing as fast as it can;
- per hour: 30000, which a client at the minute limit for a whole
  hour reaches exactly;
- per day: 300000, passed by a crawler that keeps up 4 a second.

The byte limits and ban lengths are unchanged. SPEC.md, README.md and
docs/settings.md give the reasons; docs/gitea.md redoes the Actions
runner sums.

Judgement call: the docs/alerts.md ban example shows the minute limit.

Model: opus-5-5
This commit is contained in:
2026-11-04 21:32:59 +00:00
parent fdabf4974b
commit 776f988956
8 changed files with 88 additions and 51 deletions
+9 -9
View File
@@ -35,34 +35,34 @@ on one line:
```json
{
"instance": "fsn1app1/gitea",
"time": "2026-10-06T12:00:00.123461Z",
"time": "2026-10-06T12:00:50.123461Z",
"event": "ban",
"client": "203.0.113.9",
"netblock": "203.0.113.9/32",
"asn": "",
"as_name": "",
"country": "",
"reason": "requests per minute over the limit of 6000",
"reason": "requests per minute over the limit of 500",
"detail": {
"ban_expires": "2026-10-06T13:00:00.123Z",
"ban_expires": "2026-10-06T13:00:50.123Z",
"cause": "limit",
"notes": {
"asn": "",
"as_name": "",
"country": "",
"kind": "requests",
"limit": 6000,
"limit": 500,
"window": "minute",
"count": 6001,
"count": 501,
"request": {
"time": "2026-10-06T12:00:00.123456789Z",
"time": "2026-10-06T12:00:50.123456789Z",
"method": "GET",
"host": "app.example",
"path": "/owner/repo/commits/branch/main?page=812",
"path": "/owner/repo/commits/branch/main?page=501",
"status": 403,
"user_agent": "scraper/1.0"
},
"requests": 8210,
"requests": 501,
"refused": 0,
"earlier_bans": {
"limit": 0,
@@ -89,7 +89,7 @@ on one line:
- `asn`, `as_name` and `country`: the client's, as known when the alert was
raised. They are empty when GeoJS had not answered yet.
- `reason`: a short sentence, such as
`requests per minute over the limit of 6000` or `listed by a blocklist`.
`requests per minute over the limit of 500` or `listed by a blocklist`.
- `detail`: what is particular to the event:
- for a ban, its `cause`, `ban_expires` and `notes` (the notes are listed
under `bans.json` in [`state-files.md`](state-files.md));