# Webhook Authentication Guard **Date:** 2026-03-13 ## Task Add a shared secret (`WEBHOOK_SECRET`) to the webhook endpoint so only requests with a matching `?secret=` query parameter are accepted. This prevents unauthorized parties from injecting events into the bridge. ## Changes Made ### `src/config.rs` - Added `webhook_secret()` static method to `BridgeConfig` — reads `WEBHOOK_SECRET` env var, returns `Option`. ### `src/webhook.rs` - Added `WebhookQuery` struct for axum query parameter extraction. - Added `secret: Option` field to `WebhookState`. - Updated `handle_webhook` to validate the secret before processing: returns 401 if configured secret doesn't match. - Updated `run_webhook_server` signature to accept `secret: Option`; logs a warning at startup if unset. - Added 4 integration tests using `tower::ServiceExt::oneshot`: correct secret (200), wrong secret (401), missing secret (401), no secret configured (200). ### `src/main.rs` - Reads `WEBHOOK_SECRET` via `config::BridgeConfig::webhook_secret()`. - Passes the secret to `webhook::run_webhook_server()`. ### `docker-compose.yml` - Added `WEBHOOK_SECRET=${WEBHOOK_SECRET}` to environment section. ### `config.example.toml` - Added comment documenting the `WEBHOOK_SECRET` env var. ### `README.md` - Updated webhook URL example to include `?secret=` parameter. - Added environment variables table documenting all three secrets. ### `Cargo.toml` - Added `tower` (0.5, `util` feature) as dev dependency for handler tests. ## Follow-up Items - None. All 65 tests pass.