All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Placeholder for upcoming changes.
This is the first stable v2 release. Version 2.0.0 was burned and should be skipped when tagging or publishing.
v2 focuses on a cleaner public API, a redesigned preset model, first-class ASGI/WSGI middleware, and stricter, safer header handling.
-
Secure.headersis now strict and read-only- v1:
headerswas a cacheddict[str, str]and silently collapsed duplicate names - v2: duplicate header names (case-insensitive) raise
ValueError - use
header_items()for multi-valued output ordeduplicate_headers()to resolve duplicates
- v1:
-
Default headers have changed
Secure.with_default_headers()now maps toPreset.BALANCED- v1 default included
Cache-Control: no-store; v2 does not - applications relying on v1 defaults should explicitly configure required headers
-
Presets redesigned
- new
Preset.BALANCED(recommended default) Preset.BASICupdated for Helmet.js parity and no longer matches v1 BASICPreset.STRICTno longer enables HSTS preload by default- cache behavior and header composition differ across presets compared to v1
- new
-
FastAPI / ASGI integration model changed in practice
- v1 relied on per-response mutation (
set_headers/set_headers_async) - v2 introduces middleware-based integration as the recommended approach
- v1 relied on per-response mutation (
-
Middleware
SecureASGIMiddlewareSecureWSGIMiddlewaresecure.middlewaremodule
-
Header pipeline helpers
allowlist_headers(...)deduplicate_headers(...)validate_and_normalize_headers(...)header_items()for ordered(name, value)output
-
New header builders and constants
CrossOriginResourcePolicyXDnsPrefetchControlXPermittedCrossDomainPoliciesMULTI_OK,COMMA_JOIN_OK,DEFAULT_ALLOWED_HEADERS- policy enums:
OnInvalidPolicy,OnUnexpectedPolicy,DeduplicateAction
Secure.with_default_headers()now returns the balanced preset- Header handling is stricter and fails fast on invalid or duplicate configurations
- Header normalization and validation are first-class operations
- Response integration is more robust across sync and async frameworks
headers_listmutations are now reflected correctly (no stale cached state)- Documentation updated to emphasize middleware usage and preset selection
-
Do not assume v1 defaults
- compare emitted headers and explicitly configure any required behavior
-
Audit any usage of
Secure.headers- treat as read-only in v2
- use
header_items()ordeduplicate_headers()when duplicates are possible
-
Move to middleware for ASGI/WSGI apps
- replace per-response
set_headers_async()calls withSecureASGIMiddlewareorSecureWSGIMiddleware
- replace per-response
-
Explicitly configure behavior that changed
- add
Cache-Controlif you relied on v1 defaults - add HSTS preload manually if required
- add
- Neither v1 nor v2 exposes
secure.__version__; use package metadata for version checks
- Improved performance of
Secure.set_headersby reducing redundant type checks. (#26)
- Full redesign of the
secure.pylibrary with modern Python (3.10+) support. - Major API overhaul for improved usability and Pythonic design.
- Enhanced support for FastAPI and asynchronous frameworks.
- Added type hints and better type annotations for a smoother developer experience.
- Refined default security headers for improved protection across web frameworks.
- Support for modern Python features such as the union operator (
|) andcached_property.
- Full redesign of Secure API.
- Removal of cookie support.
- Added type hints for better developer experience.
- Added support for FastAPI.
- Replaced Feature-Policy with Permissions-Policy (#10).
- Added support for Masonite framework.
- Added docstrings for
SecureHeadersandSecureCookie.
- Upper-cased SameSite enum to
SameSite.LAX/SameSite.STRICT. - Modified hug implementation for SecureHeaders and SecureCookie.
- Renamed
Feature.Values.AlltoFeature.Values.All_to avoid conflict with the built-inall.
- Removed trailing semicolon from Feature Policy.
- Added policy builder
SecurePoliciesinpolicies.py. - Added
Expiresheader for legacy browser support. - Added
max-agedirective toCache-Controlheader.
- Renamed
XXSargument toXXP. - Modified
set-cookieto use Flask's native method.