Secure webhook controller for AWS SNS email events.
Handles incoming webhook notifications from AWS Simple Notification Service (SNS) for email events like bounces, complaints, deliveries, opens, and clicks.
Security Features
- SNS Signature Verification: Validates authentic AWS requests
- IP Whitelist: Restricts access to AWS IP ranges
- Rate Limiting: Prevents abuse with configurable limits
- Replay Attack Protection: Timestamp verification (max 5 minutes)
- Request Size Limits: Prevents oversized payloads
- Automatic Subscription Confirmation: Handles SNS subscription setup
Supported Event Types
All 10 AWS SES email event types are supported:
- Send: Email accepted by AWS SES for sending
- Reject: Email rejected before sending (virus, content policy violation)
- Bounce: Hard and soft bounces with detailed reasons
- Complaint: Spam complaints and feedback loops
- Delivery: Successful delivery confirmations
- Open: Email open detection (AWS SES tracking pixel)
- Click: Link click tracking in emails
- Rendering Failure: Email template rendering errors
- Delivery Delay: Temporary delivery delays
- Subscription: Subscription preference updates or unsubscribes
Configuration
Security settings are stored in the database and managed via Settings:
# Settings keys (all default to true)
webhook_verify_sns_signature # Validate AWS SNS signatures
webhook_check_aws_ip # Restrict to AWS IP ranges
webhook_rate_limit_enabled # Enable rate limitingConfigure via Admin UI at /admin/settings or programmatically:
PhoenixKit.Settings.update_boolean_setting("webhook_verify_sns_signature", false)Usage
Add to your router:
# Public webhook endpoint (no authentication)
post "{prefix}/webhooks/email", PhoenixKitWeb.Controllers.EmailWebhookController, :handle
# Note: {prefix} is your configured PhoenixKit URL prefix (default: /phoenix_kit)AWS SNS Setup
- Create SNS topic for SES events
- Subscribe this endpoint to the topic
- Configure SES to publish events to the topic
- The controller will automatically confirm subscriptions
Example Webhook Payload
%{
"Type" => "Notification",
"Message" => Jason.encode!(%{
"eventType" => "bounce",
"mail" => %{"messageId" => "abc123"},
"bounce" => %{
"bounceType" => "Permanent",
"bouncedRecipients" => [%{"emailAddress" => "user@example.com"}]
}
})
}
Summary
Functions
Main webhook handler for AWS SNS notifications.