Release Date: 2026-10-29
Version: 1.3.18
⚠️ Important: xmlsec1 1.3.13
This release is compatible with xmlsec1 v1.3.13, and all binary wheels (Linux, macOS, Windows) now bundle it. The previous release bundled xmlsec1 1.3.9 (Linux/macOS) and 1.3.7 (Windows).
xmlsec1 1.3.13 introduces many backward-incompatible changes (stricter defaults, rejected inputs, changed digests for some transforms). Please read the xmlsec1 changelog before upgrading: https://www.aleksey.com/xmlsec/news.html
If you upgrade from 1.3.17, the bundled library jumps several versions, so also review the xmlsec1 1.3.10–1.3.12 entries on that page.
Wheels follow the new xmlsec1 defaults, and python-xmlsec does not restore the old behavior. Source builds behave according to the libxmlsec1 version they link against.
Backward-incompatible changes
1. Only empty and same-document reference URIs are allowed by default
<dsig:Reference> URIs are now limited to URI="" and URI="#id". Any other URI (http://..., cid:..., file:///..., or a relative path such as other.xml) makes SignatureContext.sign() / verify() raise xmlsec.Error. This mostly affects code that resolves external references through xmlsec.register_callbacks.
To opt in, use the new SignatureContext.enabled_reference_uris property:
ctx = xmlsec.SignatureContext()
ctx.enabled_reference_uris = (
xmlsec.constants.TransformUriTypeEmpty
| xmlsec.constants.TransformUriTypeSameDocument
| xmlsec.constants.TransformUriTypeRemote
) # or xmlsec.constants.TransformUriTypeAny2. External URIs are rejected in encryption and KeyInfo processing
The same default (empty and same-document only) now applies to:
<enc:CipherReference URI="...">when decrypting withEncryptionContext.decrypt()<dsig:RetrievalMethod URI="...">and<dsig11:KeyInfoReference URI="...">in<dsig:KeyInfo>
python-xmlsec has no setting to widen these.
3. xmlsec.shutdown() is now process-final
Starting with xmlsec1 1.3.11, the OpenSSL backend may call OPENSSL_cleanup() during shutdown, and OpenSSL cannot be reinitialized afterwards. Calling xmlsec.init() after xmlsec.shutdown() in the same process is therefore no longer supported.
4. Other behavior changes inherited from xmlsec1 1.3.13
- Relationship transform (OOXML / OPC signatures): handling bugs were fixed, so digests can differ from those produced by older versions.
- PBKDF2: iteration counts above 1,000,000 are rejected.
- CBC decryption: a padding length of zero is rejected as invalid padding.
- Nested key depth: the
<enc:EncryptedKey>nesting limit (default 1) now also counts<enc11:DerivedKey>,<enc:AgreementMethod>and<as:EncapsulationMechanism>.
5. Python 3.9 dropped
Python 3.9 has reached end of life, so the minimum supported version is now Python 3.10.
Compatibility and Wheel Support
This release provides binary wheels that are compatible with lxml v6.1.3. The compatibility is ensured by using the same underlying libxml2 version in both python-xmlsec and lxml.
If you see the following message:
lxml & xmlsec libxml2 library version mismatch
then lxml was built against a different libxml2 version than python-xmlsec. Either upgrade lxml to v6.1.3, or build both packages from source against the same libxml2. See the new troubleshooting section in the docs for details.
Wheel Build Configuration
Linux and macOS Wheels
libxml2v2.14.6libxsltv1.1.43xmlsec1v1.3.13zlibv1.3.2libiconvv1.19opensslv3.6.5
Windows Binary Wheels
iconvv1.19-1libxml2v2.11.9-8libxsltv1.1.45opensslv3.5.9xmlsecv1.3.13zlibv1.3.2
Noticeable changes
- Support for xmlsec1 1.3.13 (build and runtime fixes), and xmlsec1 1.3.13 is bundled in all wheels (#435)
- New API:
SignatureContext.enabled_reference_uris, plus the constantsTransformUriTypeNone,TransformUriTypeEmpty,TransformUriTypeSameDocument,TransformUriTypeLocal,TransformUriTypeRemoteandTransformUriTypeAny(#435) - Fixed builds with dynamic crypto loading (e.g. Homebrew, MacPorts, distro packages) against xmlsec1 1.3.13 (#434, #435)
- New wheels for Python 3.15 (#430, #432)
- Dropped Python 3.9 (#430)
- Fixed
template.create()raisingSystemErrorbecause of a wrong argument parser signature (#405, #407) - Bumped lxml to 6.1.3
- Packaging metadata moved from
setup.cfgtopyproject.toml - Refactored the static dependency builder, and CI now caches the dependency archives (#401, #420)
- Documentation updates, including troubleshooting for the libxml2 mismatch error (#418, #424)
Acknowledgements
Special thanks to
- @MichaelMVS for fixing the
template.createkeyword list
New Contributors
- @MichaelMVS made their first contribution in #405
Full Changelog: 1.3.17...1.3.18