Document the 600 a minute API limit (#25)

Templates, contract, configuration, security and design docs now say 600.
Upgrading notes how to raise a pinned 300 and why the fail2ban flood jail
still sits above it.
This commit is contained in:
MrAlders0n authored and GitHub committed 2026-10-18 23:13:00 -04:00
1 parent 9de500cfa5
commit 457fde14fd
9 files changed
+31 -13

No files matched your search

+2 -2
View File
@@ -39,11 +39,11 @@ server:
# the proxy's budget. IPv6 clients share a /64 budget to prevent address rotation.
ratelimit:
enabled: true
requests_per_minute: 300
requests_per_minute: 600
# Maximum requests in a one-second sliding window, not token-bucket capacity.
# Omitted/zero defaults to requests_per_minute. Negative limits prevent startup.
# A 429 returns error.code=rate_limited and Retry-After (1 or 60 seconds).
burst: 300
burst: 600
# MeshMapper integrations (optional, require a regional or grouped-region API key).
# Your local MeshMapper regional or grouped-region admin can generate the key.
+4 -3
View File
@@ -85,9 +85,10 @@ sudo fail2ban-client set beacon-api-flood banip <phone-on-cellular> # site unr
sudo fail2ban-client set beacon-api-flood unbanip <phone-on-cellular>
```
beacon-server's own per-IP limit (`ratelimit.requests_per_minute`, 300 by default) answers first
with 429s; the flood `maxretry` of 900 is 3× that allowance. Re-derive it if you change the server
limit. Consider `bantime.increment` only after a clean week.
beacon-server's own per-IP limit (`ratelimit.requests_per_minute`, 600 by default) answers first
with 429s; the flood `maxretry` of 900 sits 1.5× above that allowance, so only a client that keeps
going after its 429s gets banned (the web app waits out Retry-After). Re-derive it if you change the
server limit. Consider `bantime.increment` only after a clean week.
## 3. Finding scrapers by hand
+2 -2
View File
@@ -40,11 +40,11 @@ server:
# the proxy's budget. IPv6 clients share a /64 budget to prevent address rotation.
ratelimit:
enabled: true
requests_per_minute: 300
requests_per_minute: 600
# Maximum requests in a one-second sliding window, not token-bucket capacity.
# Omitted/zero defaults to requests_per_minute. Negative limits prevent startup.
# A 429 returns error.code=rate_limited and Retry-After (1 or 60 seconds).
burst: 300
burst: 600
# MeshMapper integrations (optional, require a regional or grouped-region API key).
# Your local MeshMapper regional or grouped-region admin can generate the key.
@@ -40,11 +40,11 @@ server:
# the proxy's budget. IPv6 clients share a /64 budget to prevent address rotation.
ratelimit:
enabled: true
requests_per_minute: 300
requests_per_minute: 600
# Maximum requests in a one-second sliding window, not token-bucket capacity.
# Omitted/zero defaults to requests_per_minute. Negative limits prevent startup.
# A 429 returns error.code=rate_limited and Retry-After (1 or 60 seconds).
burst: 300
burst: 600
# MeshMapper integrations (optional, require a regional or grouped-region API key).
# Your local MeshMapper regional or grouped-region admin can generate the key.
+1 -1
View File
@@ -28,7 +28,7 @@ Send the key only over HTTPS.
## Rate limiting
On by default for `/api/v1/*` (not `/ws` or `/swagger`). Each client gets `ratelimit.requests_per_minute` (default 300) per minute, plus a one-second window capped at `ratelimit.burst` (defaults to the per-minute value). Clients are keyed by IP after the trusted-proxy step below; IPv6 clients share a budget per /64. Over the limit:
On by default for `/api/v1/*` (not `/ws` or `/swagger`). Each client gets `ratelimit.requests_per_minute` (default 600) per minute, plus a one-second window capped at `ratelimit.burst` (defaults to the per-minute value). Clients are keyed by IP after the trusted-proxy step below; IPv6 clients share a budget per /64. Over the limit:
```
HTTP/1.1 429 Too Many Requests
+1 -1
View File
@@ -68,7 +68,7 @@ which ones to read.
| `auth` | The admin API key, if you would rather keep it in the file than in `BEACON_API_KEY`. | You want the admin endpoints. |
| `log` | Log level and format. | You want JSON logs for a collector. |
| `server` | `trusted_proxies`: the proxy addresses allowed to tell Beacon the real client IP. | Always, if Beacon sits behind a proxy. See [Reverse proxy](reverse-proxy.md). |
| `ratelimit` | Per-client REST limits for `/api/v1/*`. On by default at 300 requests a minute. | You get 429s you did not expect. |
| `ratelimit` | Per-client REST limits for `/api/v1/*`. On by default at 600 requests a minute. | You get 429s you did not expect. |
| `meshmapper` | Import transport scopes, IATA borders, region groups and public channels from MeshMapper instead of listing them by hand, and add repeater site details to node detail. Requires a [MeshMapper API key](#meshmapper-api-key). | You are in a region MeshMapper covers. |
| `iatas` | Display names, coordinates and optional border files for airport codes. IATAs are created automatically when traffic arrives; this block only decorates them. A `borderFile` path is relative to `config.yaml`; in Docker the compose file mounts only `config.yaml`, so add a mount for the folder too (`- ./data/app/borders:/app/borders:ro` under the `app` service). | You want names on the map or a border drawn. |
| `regions` | Groups of IATAs with a name, map centre and zoom. | Always, unless MeshMapper imports them. |
+1 -1
View File
@@ -770,7 +770,7 @@ Public reads and the WebSocket need no credentials. The `/api/v1/admin/*` subtre
returns 503. It currently covers inspecting the running config and replacing CORS origins at runtime,
operator account records (no login or sessions yet), and the backup download below.
`/api/v1/*` is rate limited per client IP (`ratelimit:`, 300/min by default, IPv6 grouped by /64).
`/api/v1/*` is rate limited per client IP (`ratelimit:`, 600/min by default, IPv6 grouped by /64).
WebSocket upgrades have their own per-IP rate and concurrency limits and a same-origin check
(`websocket:`). The client IP is the TCP peer, or `X-Real-IP` when the peer is listed in
`server.trusted_proxies`; `X-Forwarded-For` and `True-Client-IP` are never trusted.
+1 -1
View File
@@ -41,7 +41,7 @@ is authenticated.
## Rate limits and bans
REST is limited to 300 requests a minute per client by default, WebSocket upgrades to 10 a
REST is limited to 600 requests a minute per client by default, WebSocket upgrades to 10 a
minute, with 5 open sockets per client. Behind a proxy none of that works until
`server.trusted_proxies` is set; see
[Reverse proxy](reverse-proxy.md#rate-limits-and-connection-caps). For repeat offenders, the
+17
View File
@@ -117,6 +117,23 @@ one, check the MeshMapper logs for successful refreshes; existing backoff still
If you use backups, leave `meshmapper.api_key` empty in the saved YAML and keep the key in
the environment. Exports refuse a nonempty saved YAML key.
## REST rate limit raised to 600
Newer builds default `ratelimit.requests_per_minute` (and `burst`) to 600 a minute instead
of 300. Opening the Map and Nodes tabs on a region of a few thousand nodes could run past
300 and leave the map half loaded. The shipped `config.yaml` templates set the value
explicitly, so an existing deployment keeps 300 until you change it:
```yaml
ratelimit:
enabled: true
requests_per_minute: 600
burst: 600
```
Then run `docker compose restart app`. If you run the [fail2ban jails](../app_config/fail2ban/README.md),
the flood jail's `maxretry` of 900 still sits above the new limit.
## Changes that need a restart
Beacon reads `config.yaml` once at startup. After editing it, run