Spun out of the #248 crew review (finding F3).
handle_webhook calls record_rejection for every missing/invalid bearer before any rate-limit token is consumed (the bucket is deliberately taken only after JWT verification, triton-chat-msteams/src/lib.rs). On a public webhook path a background scanner generates one audit line per request, diluting/evicting real entries from whatever tails /v1/audit.
This is pre-existing behaviour on /msteams/webhook (already a public webhook on agent-lab); #248's opt-in /api/messages just makes the canonical, heavily-scanned path available.
Fix: a small dedicated bucket for auth-rejection audit emission (keyed on "unauthenticated reject"), emitting one line per window plus a suppressed-count field, while still returning 401 on every request. Applies to all chat adapters with a public inbound route, not just msteams.
Severity: medium (observability/ops, not a security bypass — 401 is still returned on every request).
Spun out of the #248 crew review (finding F3).
handle_webhookcallsrecord_rejectionfor every missing/invalid bearer before any rate-limit token is consumed (the bucket is deliberately taken only after JWT verification,triton-chat-msteams/src/lib.rs). On a public webhook path a background scanner generates one audit line per request, diluting/evicting real entries from whatever tails/v1/audit.This is pre-existing behaviour on
/msteams/webhook(already a public webhook onagent-lab); #248's opt-in/api/messagesjust makes the canonical, heavily-scanned path available.Fix: a small dedicated bucket for auth-rejection audit emission (keyed on "unauthenticated reject"), emitting one line per window plus a suppressed-count field, while still returning 401 on every request. Applies to all chat adapters with a public inbound route, not just msteams.
Severity: medium (observability/ops, not a security bypass — 401 is still returned on every request).