bruteforce, warn), an integrity change (integrity, critical), a new administrator (account, critical), a malware finding (malware, critical) and a lockdown being thrown (lockdown, critical).
How to access: GuardForge > Alerts.
Free/PRO: Pro (alerts_telegram, alerts_slack, alerts_webhook — one add-on switch turns on all three today).
Notes:
- A card per channel, no JSON. The screen used to be a textarea of raw JSON with tokens and HMAC secrets printed back in clear text. Now each channel is a card: Telegram (bot token + chat id), Slack (webhook URL), Webhook (URL + HMAC secret + optional header name, default
X-GuardForge-Signature), each with an enabled toggle, a minimum severity, a Remove button and “Add channel”. - Secrets are encrypted at rest (
bot_token,webhook_url— a Slack URL carries its secret in the path — andhmac_secret) and never printed back: the form shows••••1234. Leaving a secret field empty means “keep and re-encrypt what is there”, so the first save through the new form migrates a legacy clear-text secret without the operator doing anything. Export masks the same way; import goes through the same validation and encryption as the form. - Send test really sends, through the same dispatcher, and saves nothing. It reports the HTTP status and the first 200 bytes of the reply.
- Digest:
immediate,hourlyordaily. The hourly cron tick both flushes a due digest and releases anything held for quiet hours. Up to 500 events are held pending. - Quiet hours are a start and an end in the site’s own timezone, wrapping over midnight, off by default (22:00–07:00 when switched on). They hold ordinary alerts until morning — but
lockdownandmalwarebypass them outright, which is why every signal carries a category separate from its severity. - Minimum severity is per channel (
info<warn<critical), so the on-call phone can take criticals while the team channel takes everything. - Validation: a Telegram chat id is digits (negative allowed, for supergroups) or
@channel(5–32 characters); Slack and webhook URLs must behttps://and must pass the sharedForge_Net::is_safe_url()SSRF gate. - Alerts have their own
admin_post_guardforge_save_alertshandler rather than the generic settings path, because per-channel secrets and validation do not fit a scalar field sanitiser.