Skip to main content

django-sns-signals

A Django library for handling and validating AWS SNS (Simple Notification Service) webhook messages with cryptographic signature verification and Django signals.

Features

  • Cryptographic Signature Verification - Validates SNS message authenticity using AWS certificates

  • Django Signals - Fire signals for subscription, unsubscription, and notification events

  • Auto-confirmation - Automatically confirms SNS subscriptions and unsubscriptions

  • Certificate Caching - Configurable caching of AWS signing certificates (default: 24 hours)

  • Minimal Dependencies - Only requires Django and cryptography; uses Python’s standard library for HTTP

  • Type Safety - Full type hints with Python 3.10+

Installation

pip install django-sns-signals

Requirements

  • Python 3.10+

  • Django 4.2+

  • cryptography ~=46.0.0

Quick Start

1. Add to your Django URLs

# urls.py
from django.urls import path
from django_sns_signals.views import sns_webhook

urlpatterns = [
    path('sns/webhook/', sns_webhook, name='sns_webhook'),
]

2. Connect to Django Signals

# apps.py or signals.py
from django.apps import AppConfig
from django_sns_signals import sns_notification

def handle_notification(sender, notification_message, topic_arn, subject=None, **kwargs):
    """Handle SNS notifications"""
    print(f"Received from {topic_arn}: {notification_message}")
    # Your business logic here

class MyAppConfig(AppConfig):
    def ready(self):
        sns_notification.connect(handle_notification)

3. Configure SNS Topic (AWS Console)

  1. Create an SNS topic in AWS

  2. Add an HTTPS subscription with your webhook URL: https://yourdomain.com/sns/webhook/

  3. The library will automatically confirm the subscription

Configuration

Optional Settings

Add to your Django settings.py:

# Optional: Configure signing certificate cache timeout (in seconds)
# Default: 86400 (24 hours)
SNS_SIGNING_CERT_CACHE_TIMEOUT = 86400

The certificate cache timeout controls how long AWS SNS signing certificates are cached. AWS rarely rotates these certificates, so a longer cache period (24 hours or more) is safe and reduces HTTP requests.

Architecture

Core Components

SNSSignatureValidator

Validates AWS SNS message signatures using cryptographic verification:

  • Verifies certificate URLs come from amazonaws.com domain

  • Implements certificate caching using Django’s cache framework

  • Builds canonical signing strings based on message type

  • Uses RSA PKCS1v15 padding with SHA1 hash (AWS SNS standard)

sns_webhook View

Django view function that handles SNS webhook POST requests:

  • CSRF exempt (AWS cannot provide CSRF tokens)

  • Validates message signatures before processing

  • Handles three message types:

    • SubscriptionConfirmation: Auto-confirms by fetching SubscribeURL

    • UnsubscribeConfirmation: Auto-confirms unsubscription by fetching SubscribeURL

    • Notification: Processes actual SNS notifications and fires signals

  • Returns appropriate HTTP status codes (200-499 range required by SNS)

Django Signals

The library fires Django signals for each SNS message type:

sns_subscription_confirmation

Fired after successful subscription confirmation.

Signal Parameters:

  • message (dict) - Full parsed SNS message

  • raw_message (bytes) - Raw request body

  • message_id (str) - Unique message identifier

  • topic_arn (str) - Topic ARN

  • subject (str | None) - Optional subject

  • timestamp (str) - Message timestamp

  • subscribe_url (str) - Subscription confirmation URL

  • token (str) - Subscription token

sns_unsubscribe_confirmation

Fired after successful unsubscribe confirmation.

Signal Parameters:

  • message (dict) - Full parsed SNS message

  • raw_message (bytes) - Raw request body

  • message_id (str) - Unique message identifier

  • topic_arn (str) - Topic ARN

  • subject (str | None) - Optional subject

  • timestamp (str) - Message timestamp

  • subscribe_url (str) - Unsubscribe confirmation URL

  • token (str) - Unsubscription token

sns_notification

Fired when a notification is received.

Signal Parameters:

  • message (dict) - Full parsed SNS message

  • raw_message (bytes) - Raw request body

  • message_id (str) - Unique message identifier

  • topic_arn (str) - Topic ARN

  • subject (str | None) - Optional subject

  • timestamp (str) - Message timestamp

  • notification_message (str) - The actual notification payload

  • unsubscribe_url (str) - URL to unsubscribe from topic

Usage Examples

Basic Notification Handler

from django_sns_signals import sns_notification

def handle_sns_notification(sender, notification_message, topic_arn, subject=None, **kwargs):
    print(f"Topic: {topic_arn}")
    print(f"Subject: {subject}")
    print(f"Message: {notification_message}")

sns_notification.connect(handle_sns_notification)

Topic-Specific Handler

from django_sns_signals import sns_notification
import json

def handle_order_notifications(sender, notification_message, topic_arn, **kwargs):
    if 'orders' not in topic_arn:
        return  # Ignore non-order topics

    order_data = json.loads(notification_message)
    process_order(order_data)

sns_notification.connect(handle_order_notifications)

Subscription Tracking

from django_sns_signals import sns_subscription_confirmation, sns_unsubscribe_confirmation

def log_subscription(sender, topic_arn, **kwargs):
    print(f"Subscribed to: {topic_arn}")

def log_unsubscription(sender, topic_arn, **kwargs):
    print(f"Unsubscribed from: {topic_arn}")

sns_subscription_confirmation.connect(log_subscription)
sns_unsubscribe_confirmation.connect(log_unsubscription)

Security

Message Signature Validation

All SNS messages are cryptographically validated before processing:

  1. Extract SigningCertURL from SNS message

  2. Validate URL hostname ends with .amazonaws.com

  3. Fetch certificate (cached for performance)

  4. Build canonical string-to-sign based on message type

  5. Verify signature using certificate’s public key with PKCS1v15 padding and SHA1

  6. Reject message if signature invalid

The library follows AWS best practices for SNS message verification as documented in the AWS SNS Developer Guide.

Development

Setup

# Clone the repository
git clone https://github.com/newadventures/django-sns-signals.git
cd django-sns-signals

# Install in development mode
pip install -e .
pip install -r requirements_dev.txt

Running Tests

# Run tests with pytest
pytest tests/

# Or with Django's test runner
python -m django test --settings=tests.settings

# Run with coverage
pytest --cov=django_sns_signals tests/

Code Quality

# Format and lint code
ruff check src/ tests/
ruff format src/ tests/

Building the Package

# Build distribution packages
python -m build

# Check package for PyPI compliance
twine check dist/*

License

BSD-3-Clause License - see LICENSE file for details.

Support

For issues and questions, please use the GitHub issue tracker.

Metadata

Release files for django-sns-signals 0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-sns-signals 0.1
File Size Uploaded Provenance Actions
django_sns_signals-0.1.tar.gz 12.6 kB With provenance Details for django_sns_signals-0.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for django-sns-signals 0.1
File Interpreter ABI Platform Actions
django_sns_signals-0.1-py3-none-any.whl Python 3 none any Details for django_sns_signals-0.1-py3-none-any.whl

Total release size: 20.5 kB

Release files / django_sns_signals-0.1.tar.gz

Download URL django_sns_signals-0.1.tar.gz
Size 12.6 kB
Tags Source
SHA-256 checksum
How to use checksums
63eaa8bf7e1054cd2b6173f1e263d15490723001233b99c0d08167567eb27dcf
BLAKE2b-256 checksum
How to use checksums
6582b833b011fcb8935ba0a34eab50176e19ecf3fbdf444be0908580d96592b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 17, 2025.

Transparency log

Release files / django_sns_signals-0.1-py3-none-any.whl

Download URL django_sns_signals-0.1-py3-none-any.whl
Size 7.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
69364d75a6fde9c915f722d4324afc6a95992d613d232bf1c21e29b0f1db6d5f
BLAKE2b-256 checksum
How to use checksums
7d01fdf634627364c3cdc2239ab608ad3b96f3dcbb7fc0d76680ef8220f89ba6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 17, 2025.

Transparency log

Security for django-sns-signals 0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for django_sns_signals-0.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 17, 2025.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page