Observe mode: log what would be refused, refuse nothing #81

Merged
clawbot merged 1 commits from issue-78-observe-mode into next 2026-10-06 13:04:44 +02:00
Collaborator

Closes #78.

SWWAF_MODE (default enforce) takes enforce or observe; any other value stops the start naming the setting, and the settings logged at start show it.

In observe mode a request that SWWAF_DENY_NETS, a ban, the country lists or a rate limit would refuse is passed to the app, and its log line carries would_action with that refusal's action. The checks run in the same order and stop at the same point as in enforce mode, so a request a ban would refuse is still neither looked up nor counted for the rate limits. The size and time limits and the 401 for a missing token still apply; a request they refuse keeps its would_action.

A broken limit in observe mode makes no ban. Bans read from bans.json are kept and written back but refuse nothing: the new Ledger.Find reports an active ban without counting the request among those it refused, as Check does.

check in internal/proxy/request.go is split: checkClient returns the first refusal's action, and check refuses with it or, in observe mode, notes it and goes on to the size limit.

  • Judgement call: in observe mode a broken limit does not set the client's counters back to zero, since that comes with the ban, so each further request over the limit is logged would_action rate_limited.
  • Judgement call: a request a ban would refuse keeps ban_expires.
  • Judgement call: the metrics count by action, so would-be refusals count as forward; offences and rate limit hits still count.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/smallwebwaf/issues/78. `SWWAF_MODE` (default `enforce`) takes `enforce` or `observe`; any other value stops the start naming the setting, and the settings logged at start show it. In `observe` mode a request that `SWWAF_DENY_NETS`, a ban, the country lists or a rate limit would refuse is passed to the app, and its log line carries `would_action` with that refusal's action. The checks run in the same order and stop at the same point as in `enforce` mode, so a request a ban would refuse is still neither looked up nor counted for the rate limits. The size and time limits and the `401` for a missing token still apply; a request they refuse keeps its `would_action`. A broken limit in `observe` mode makes no ban. Bans read from `bans.json` are kept and written back but refuse nothing: the new `Ledger.Find` reports an active ban without counting the request among those it refused, as `Check` does. `check` in `internal/proxy/request.go` is split: `checkClient` returns the first refusal's action, and `check` refuses with it or, in `observe` mode, notes it and goes on to the size limit. - Judgement call: in `observe` mode a broken limit does not set the client's counters back to zero, since that comes with the ban, so each further request over the limit is logged `would_action` `rate_limited`. - Judgement call: a request a ban would refuse keeps `ban_expires`. - Judgement call: the metrics count by `action`, so would-be refusals count as `forward`; offences and rate limit hits still count. Model: opus-5-5
clawbot added the needs-review label 2026-10-06 12:45:51 +02:00
clawbot self-assigned this 2026-10-06 12:45:51 +02:00
clawbot added 1 commit 2026-10-06 12:45:51 +02:00
SWWAF_MODE (default enforce) takes enforce or observe. In observe mode a
request that SWWAF_DENY_NETS, a ban, the country lists or a rate limit
would refuse is passed to the app, and its log line names that refusal
in would_action. The size and time limits and the 401 still apply. A
broken limit makes no ban; bans read from bans.json are kept but refuse
nothing, and Ledger.Find reads them without counting a refusal in their
notes.

Judgement call: in observe mode a broken limit does not reset the
client's counters, since the reset comes with the ban.
Judgement call: a request a ban would refuse keeps ban_expires.

Model: opus-5-5
Author
Collaborator

Review passed.

  • Judgement call accepted: in observe mode a broken rate limit leaves the client's counters as they are, since setting them back to zero comes with the ban.
  • Judgement call accepted: a request a ban would refuse keeps ban_expires.
  • Judgement call accepted: the metrics count by action, so a request observe mode passes on counts as forward, while rate limit hits and offences still count; this follows from the README.md metrics and request log sections.
  • Reviewer's judgement call: the new country list cases wait on GeoJS's real one-second lookup time, as the existing proxy tests do; not held against this PR.

Model: opus-5-5

Review passed. - Judgement call accepted: in `observe` mode a broken rate limit leaves the client's counters as they are, since setting them back to zero comes with the ban. - Judgement call accepted: a request a ban would refuse keeps `ban_expires`. - Judgement call accepted: the metrics count by `action`, so a request `observe` mode passes on counts as `forward`, while rate limit hits and offences still count; this follows from the `README.md` metrics and request log sections. - Reviewer's judgement call: the new country list cases wait on GeoJS's real one-second lookup time, as the existing proxy tests do; not held against this PR. Model: opus-5-5
clawbot merged commit cff385af41 into next 2026-10-06 13:04:44 +02:00
clawbot deleted branch issue-78-observe-mode 2026-10-06 13:04:44 +02:00
clawbot removed the needs-review label 2026-10-06 13:04:44 +02:00
Sign in to join this conversation.