Add suspicious-signup sweep: suspend flagged signups with no activity
Watches every account flagged by IP-scrutiny or email-domain scrutiny at signup and, once it goes live, records a baseline post/follow count. A scheduled sweep (app/suspicious_sweep.py, run via cron on admin.yttrx.com) suspends any watch past SUSPICIOUS_GRACE_HOURS with zero new posts and zero new follows since that baseline; any activity clears the watch. Works whether yttrx is open-registration or requires moderator approval, since the watch starts at whichever event actually makes the account live (account.created vs account.approved), same dual handling the welcome flow already uses. Needs ABUSE_BOT_TOKEN re-minted with admin:read:accounts.
This commit is contained in:
@@ -124,14 +124,57 @@ Registering email_domain_blocks requires the `ABUSE_BOT_TOKEN` to carry the
|
||||
`admin:write:email_domain_blocks` scope in addition to its existing scopes
|
||||
(see `CLAUDE.md`).
|
||||
|
||||
## Suspicious-signup sweep
|
||||
|
||||
A scheduled companion to the two signup-scrutiny signals above (`app/suspicious_sweep.py`,
|
||||
run via `docker exec yttrx-welcomebot python -m app.suspicious_sweep`, e.g. hourly cron on
|
||||
`admin.yttrx.com`):
|
||||
|
||||
1. Any account flagged by **either** IP-scrutiny (datacenter/hosting) or
|
||||
email-domain scrutiny (disposable/high-risk) has a grace-period clock
|
||||
started the moment it goes live — `account.created` if signups are open
|
||||
(or auto-approved), `account.approved` if this instance requires
|
||||
moderator approval. Same dual-event handling the welcome flow already
|
||||
uses, so it works in either registration mode without extra config. A
|
||||
baseline snapshot of `statuses_count`/`following_count` is recorded at
|
||||
that moment (`app.main.maybe_start_suspicious_watch`, table
|
||||
`suspicious_watch`).
|
||||
2. The sweep looks for watches past `SUSPICIOUS_GRACE_HOURS` (default 24)
|
||||
and compares current counts to the baseline:
|
||||
- **Any new post or new follow** since the baseline → cleared, never
|
||||
rechecked.
|
||||
- **Zero of either** → `SUSPICIOUS_ACTION` (default `suspend`) is applied,
|
||||
the moderator is DMed, and the watch is marked resolved.
|
||||
3. Already-suspended/silenced accounts, staff (`ABUSE_SKIP_PRIVILEGED`), and
|
||||
`ABUSE_ALLOWLIST` handles are skipped exactly as elsewhere in this bot —
|
||||
the sweep reuses those same settings rather than defining its own.
|
||||
|
||||
Unlike the report-driven abuse-bot (default `silence`), this sweep defaults
|
||||
to **`suspend`** — the reasoning is that zero organic activity in a full day
|
||||
is a stronger bulk/bot-signup signal than a report alone, and Mastodon
|
||||
suspensions have a server-side undo window. It also ships **live**
|
||||
(`SUSPICIOUS_DRY_RUN=false`) rather than with the usual dry-run rollout step;
|
||||
`SUSPICIOUS_DRY_RUN=true` remains available as a kill switch if you want to
|
||||
pause it without redeploying.
|
||||
|
||||
Requires `ABUSE_BOT_TOKEN` to additionally carry the **`admin:read:accounts`**
|
||||
scope (fetches live counts + role/suspended state via
|
||||
`GET /api/v1/admin/accounts/:id`) — see `CLAUDE.md`'s moderator-token-gotcha
|
||||
section for the remint procedure.
|
||||
|
||||
Inspect the watch list: `welcomebot-suspicious` / `welcomebot-suspicious --pending`
|
||||
(see `bin/welcomebot-suspicious`).
|
||||
|
||||
## Layout
|
||||
|
||||
| Path | Purpose |
|
||||
|---|---|
|
||||
| `app/main.py` | The FastAPI app |
|
||||
| `app/suspicious_sweep.py` | Scheduled sweep: suspends flagged signups with no activity (run via cron, not the webserver) |
|
||||
| `Dockerfile`, `docker-compose.yml` | Container build + run |
|
||||
| `.env.example` | Config template (copy to `.env`, never commit) |
|
||||
| `nginx/hooks.yttrx.com.conf` | nginx site for admin.yttrx.com |
|
||||
| `bin/welcomebot-logs`, `bin/welcomebot-signups`, `bin/welcomebot-suspicious` | Ops CLIs installed to `/root/bin` on admin.yttrx.com |
|
||||
| `test_local.py` | Offline smoke test (no network) |
|
||||
|
||||
## Configuration
|
||||
@@ -172,6 +215,10 @@ Copy `.env.example` to `.env` and fill in:
|
||||
| `CHECK_MAIL_RISK_THRESHOLD` | Flag if `is_disposable` or `risk` ≥ this (default 80) |
|
||||
| `CHECK_MAIL_HOLD_WELCOME` | `true` — hold the welcome for a flagged signup until `account.approved` |
|
||||
| `CHECK_MAIL_AUTO_DOMAIN_BLOCK` | Auto-register a flagged domain into Mastodon's `Admin::EmailDomainBlock`; also gates the report-triggered override |
|
||||
| `SUSPICIOUS_SWEEP_ENABLED` | Master switch for the suspicious-signup sweep (`app/suspicious_sweep.py`) |
|
||||
| `SUSPICIOUS_GRACE_HOURS` | Hours a flagged signup has to post or follow someone before it's swept (default 24) |
|
||||
| `SUSPICIOUS_ACTION` | `suspend` (default) or `silence`, applied to a flagged signup with zero activity in the grace window |
|
||||
| `SUSPICIOUS_DRY_RUN` | `false` (ships live by design) — set `true` to log/DM only, no real action |
|
||||
|
||||
## Local test
|
||||
|
||||
@@ -272,11 +319,29 @@ Register a throwaway test account on yttrx and confirm the `@welcome` bot DMs
|
||||
it. Then delete the test account (`tootctl accounts delete` on mammut) and the
|
||||
test toot.
|
||||
|
||||
### 6. Cron for the suspicious-signup sweep (on admin.yttrx.com)
|
||||
|
||||
The sweep is not part of the always-running webhook server — it's invoked
|
||||
on a schedule via `docker exec`. `ABUSE_BOT_TOKEN` must additionally carry
|
||||
the `admin:read:accounts` scope (remint via the Rails-console snippet in
|
||||
`CLAUDE.md`, same procedure as the other scope additions) before installing
|
||||
this cron entry, or every sweep run 403s per-account:
|
||||
|
||||
```bash
|
||||
crontab -l | { cat; echo '17 * * * * docker exec yttrx-welcomebot python -m app.suspicious_sweep >> /var/log/welcomebot-suspicious-sweep.log 2>&1'; } | crontab -
|
||||
```
|
||||
|
||||
Hourly (rather than daily like the dormant-sweep) since the grace window is
|
||||
only `SUSPICIOUS_GRACE_HOURS` (default 24) — an hourly cadence keeps the gap
|
||||
between crossing the deadline and being swept small.
|
||||
|
||||
## Operations
|
||||
|
||||
```bash
|
||||
welcomebot-logs -f --abuse # convenience CLI on admin (see bin/welcomebot-logs)
|
||||
welcomebot-signups --flagged # signup-IP classification history (see bin/welcomebot-signups)
|
||||
welcomebot-suspicious --pending # suspicious-sweep watch list (see bin/welcomebot-suspicious)
|
||||
docker exec yttrx-welcomebot python -m app.suspicious_sweep # run the sweep manually
|
||||
docker compose logs -f welcomebot # watch deliveries
|
||||
docker compose restart welcomebot # after editing .env
|
||||
docker compose down && docker compose up -d --build # redeploy after code change
|
||||
|
||||
Reference in New Issue
Block a user