itsdangerous

A small Python toolkit for cryptographically signing data so you can trust it hasn't been tampered with when it comes back from an untrusted client.

Library
PyPI
v2.2.0
3,141 stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
46 /100 Fair
Development Activity 0
Maintenance 20
Community 64
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
84 /100 Excellent
Architecture 85
Code Quality 92
Innovation 82
Learning Curve 75

itsdangerous provides a layered API for signing and optionally serializing data so it can safely round-trip through cookies, URLs, and other untrusted channels. At the base is a Signer that HMAC-signs raw bytes with a secret key and salt; wrapped around it is a Serializer that adds pluggable JSON (or custom) encoding, so arbitrary Python objects can be signed and verified with a single dumps/loads call pair, mirroring the json module’s own interface.

Built-in variants cover the common cases web frameworks need: TimestampSigner/TimedSerializer embed a timestamp so tokens can expire after a max_age, and URLSafeSerializer/URLSafeTimedSerializer zlib-compress and base64-encode the payload so it’s safe to embed directly in a URL or cookie value. Key rotation is supported natively — pass a list of secret keys, oldest to newest, and verification tries them in reverse so old tokens keep validating during a rollover. Originally split out of Flask (which still uses it for signed session cookies), it has no runtime dependencies and is now maintained as one of the core Pallets projects alongside Flask, Jinja, Click, and Werkzeug.

What You Get

  • A Signer class that HMAC-signs raw bytes with a secret key and salt, with sign/unsign/validate methods
  • A Serializer wrapper that signs arbitrary Python objects via a pluggable data serializer (JSON by default)
  • TimestampSigner/TimedSerializer for tokens that expire after a configurable max_age
  • URLSafeSerializer/URLSafeTimedSerializer that zlib-compress and base64-encode payloads for safe use in URLs and cookies
  • Built-in key rotation via a list of secret keys, verified newest-first so old tokens keep working during rotation
  • A small, structured exception hierarchy (BadSignature, SignatureExpired, BadPayload, etc.) that preserves the original payload and signing date for debugging

Common Use Cases

  • Signing Flask/Django-style session cookies so tampering is detectable server-side
  • Generating expiring email-confirmation or password-reset tokens embedded in a URL
  • Issuing short-lived API tokens that don’t require a database lookup to verify
  • Passing signed state through a redirect or webhook callback without a server-side session store
  • Rotating a compromised or aging secret key without invalidating tokens already issued to users

Under The Hood

Architecture

The codebase is layered by responsibility: encoding.py provides base64/int helpers, exc.py defines a small exception hierarchy (BadData to BadSignature to BadTimeSignature/SignatureExpired, plus BadPayload and BadHeader), and signer.py defines a SigningAlgorithm/HMACAlgorithm pair plus the Signer class handling key derivation strategies (concat, django-concat, hmac, none) and key-rotation via a secret_keys list tried oldest-to-newest. serializer.py wraps a Signer to add pluggable payload serialization (defaulting to json) with dumps/loads, and iterates fallback_signers when unsigning to support migrating signing schemes without breaking old tokens. timed.py extends Signer into TimestampSigner (embeds a base64 timestamp) and Serializer into TimedSerializer (adds max_age expiry checks), while url_safe.py composes a URLSafeSerializerMixin (zlib compression plus base64 encoding, using a compact JSON serializer from _json.py) with Serializer/TimedSerializer via multiple inheritance to produce URLSafeSerializer and URLSafeTimedSerializer. This is composition over duplication: cryptographic verification, payload encoding, and expiry logic are each isolated behind small, independently testable classes.

Tech Stack

Pure Python 3.10+ with zero runtime dependencies, relying only on stdlib (hashlib, hmac, base64, zlib, json). Packaged with flit_core via pyproject.toml, with uv managing dependency groups for dev, docs, tests, and typing. Linting runs through ruff (bugbear, pyflakes, isort, pyupgrade rule sets), static typing is enforced with strict mypy and pyright, and the test matrix runs via tox/tox-uv across Python 3.10-3.13 and PyPy 3.11. Documentation is built with Sphinx using the Pallets Sphinx theme, and releases publish to PyPI via GitHub Actions using trusted publishing.

Code Quality

Tests live under tests/test_itsdangerous/, covering encoding, signer, serializer, timed, and URL-safe behavior with plain pytest functions and freezegun for deterministic timestamp assertions; coverage configuration targets branch coverage. Typing is comprehensive — a py.typed marker, PEP 604 unions throughout, and a Protocol-based type for pluggable serializers — checked under mypy --strict and pyright. Error handling is deliberate rather than swallowed: the exception hierarchy carries structured context (the failed payload, the signing date) instead of just a message, and signature comparison uses hmac.compare_digest to avoid timing attacks. Style is enforced via ruff and pre-commit hooks, with CI running the full suite across multiple Python versions.

API Design The public API favors progressive disclosure: URLSafeSerializer(secret_key, salt).dumps(obj) covers the common case in one line, while the lower-level Signer/TimestampSigner classes expose raw sign/unsign primitives for callers who don’t want JSON at all. Key rotation and fallback_signers are both documented, low-boilerplate escape hatches — no subclassing required to support a secret-key rollover or a legacy token format. Method naming mirrors the standard json module’s dumps/loads convention, and every public method carries a docstring with version-change history. The main friction point is that verification failures surface as a small hierarchy of exceptions rather than a single boolean, though validate() convenience methods cover the common “is this still good” check without a try/except.

Used by 15 apps in this directory

Python
62%
Apache 2.0

Polar

Developer Tools · Ecommerce · Invoicing Finance

10,410

Open source payments infrastructure that turns software into a business — subscriptions, usage-based billing, digital products, and merchant-of-record compliance in one platform.

View details
90
Repo Health
82
Technical
66
Dependency
Built with
Python 62%
TypeScript 31%
Updated 6 days ago
Python
45%
Other

Redash

Analytics · Data Engineering

28,849

Redash lets anyone connect to 35+ SQL and NoSQL data sources, write a query in the browser, and turn the result into a shared dashboard — no separate BI suite required.

View details
91
Repo Health
74
Technical
61
Dependency
Built with
Python 45%
JavaScript 29%
TypeScript 19%
Updated 1 weeks ago
TypeScript
98%
Apache 2.0

rowboat

AI Assistants · AI Development

18,060

Build, test, and deploy multi-agent AI workflows with a visual editor, RAG data sources, MCP tool integration, and a production-ready REST API.

View details
88
Repo Health
72
Technical
65
Dependency
Built with
TypeScript 98%
Updated 6 days ago
Python
59%
AGPL 3.0

Speakr

AI Assistants

4,112

Self-hosted AI transcription with speaker diarization, smart tagging, and multi-user collaboration — your recordings stay on your infrastructure.

View details
84
Repo Health
79
Technical
70
Dependency
Built with
Python 59%
HTML 21%
JavaScript 17%
Updated 6 days ago
C
74%
AGPL 3.0

TDengine

Databases

25,168

A high-performance, open-source time-series database built in C for IoT, connected vehicles, and industrial monitoring workloads, with built-in stream processing, caching, and data subscription.

View details
97
Repo Health
71
Technical
65
Dependency
Built with
C 74%
C++ 19%
Updated 1 weeks ago
Go
54%
AGPL 3.0

Uptrace

Devops · Monitoring

4,305

Unified open-source APM that collects OpenTelemetry traces, metrics, and logs into a single self-hosted platform backed by ClickHouse.

View details
71
Repo Health
70
Technical
65
Dependency
Built with
Go 54%
Vue 34%
Updated 1 weeks ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers