pyspnego

SPNEGO, NTLM, Kerberos, and CredSSP authentication for Python, with native SSPI/GSSAPI wrapping and a raw-token debug parser.

Library
PyPI
v0.12.2
65stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
58/100Fair
Development Activity56
Maintenance60
Community44
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture82
Code Quality90
Innovation75
Learning Curve75

pyspnego implements the SPNEGO/Negotiate authentication mechanism for Python, giving a single client()/server() API that transparently wraps the platform’s native SSPI (Windows) or GSSAPI (Linux/macOS) implementation while falling back to pure-Python NTLM and a simplified Negotiate wrapper when a full GSSAPI stack isn’t available. It supports Kerberos, NTLM, Negotiate, and CredSSP protocols, and is the authentication engine behind projects like pywinrm and smbprotocol that need to talk to Windows services (SMB, WinRM, HTTP Negotiate) from any OS.

Beyond the authentication context objects, pyspnego ships its own ASN.1 encoder/decoder for the Kerberos/SPNEGO wire formats and pure-Python implementations of legacy NTLM cryptographic primitives (DES, MD4, RC4) for platforms where system libraries can’t provide them. A companion pyspnego-parse CLI script decodes raw NTLM/SPNEGO/Kerberos tokens into a human-readable structure, which is invaluable when debugging a failed handshake captured from the wire or a log file.

What You Get

  • A single spnego.client() / spnego.server() factory that picks the right underlying implementation (SSPI, GSSAPI, or pure-Python) automatically based on platform and requested protocol
  • Pure-Python NTLM and Negotiate implementations that work even without a system GSSAPI/Kerberos install
  • CredSSP support for RDP-style credential delegation scenarios, layered on top of the Negotiate handshake
  • A hand-rolled ASN.1 parser/encoder for SPNEGO and Kerberos wire structures with no external ASN.1 dependency
  • The pyspnego-parse CLI for decoding raw base64/hex NTLM, SPNEGO, or Kerberos tokens into readable output, including optional YAML output via ruamel.yaml

Common Use Cases

  • Authenticating an HTTP client against a server that requires Windows Negotiate/NTLM auth (e.g. IIS, Exchange, internal enterprise APIs)
  • Implementing SMB or WinRM clients that need Kerberos or NTLM session security without shelling out to platform tools
  • Building a server/acceptor that validates incoming Negotiate/NTLM/Kerberos tokens from Windows clients
  • Debugging a stalled or rejected authentication handshake by decoding the raw token bytes captured from a packet trace
  • Supporting CredSSP-based credential delegation for RDP-adjacent or remote-management protocols

Under The Hood

Architecture The library centers on ContextProxy, an abstract base defined in _context.py that exposes a uniform step/wrap/unwrap interface implemented by five concrete backends (SSPIProxy, GSSAPIProxy, NegotiateProxy, NTLMProxy, CredSSPProxy). auth.py’s _new_context() acts as the composition root: it inspects the requested protocol, any explicit NegotiateOptions flags, and which credential types were supplied, then filters out backends that can’t satisfy the combination (for example, an NTLMHash credential rules out SSPI) before instantiating the matching proxy. This is a clean strategy/factory pattern that lets callers write protocol-agnostic code against ContextProxy while the library silently swaps in the best available implementation for the current platform.

Tech Stack pyspnego targets CPython 3.9+ and is built with setuptools using a src-layout package. Its only hard dependency is cryptography; sspilib is pulled in only on Windows, and gssapi/krb5 are optional extras for Kerberos support on non-Windows platforms, with ruamel.yaml as an optional extra for YAML output from the CLI. Internally it leans heavily on dataclasses, enum, and extensive typing annotations, and implements its own ASN.1 codec and legacy cryptographic primitives rather than pulling in general-purpose ASN.1 or crypto libraries for those pieces.

Code Quality The project has an extensive test suite (19 files under tests/) covering ASN.1 encoding, CredSSP structures, context negotiation, exceptions, GSSAPI, Kerberos, the CLI entry point, NTLM, SSPI, TLS structures, and channel bindings. mypy is configured in strict mode (disallow_untyped_defs, disallow_any_unimported, disallow_incomplete_defs), ruff enforces import ordering, and a .pre-commit-config.yaml wires these into local hooks. CI runs the full matrix across Ubuntu/macOS/Windows, multiple Python versions (3.9 through 3.15-dev), and multiple GSSAPI providers (MIT, Heimdal, SSPI), with Codecov tracking coverage.

What Makes It Unique Most auth libraries either wrap one platform API or depend on a general ASN.1/crypto package; pyspnego instead reimplements the pieces those approaches would otherwise require as hard dependencies — a hand-rolled ASN.1 DER encoder/decoder for the SPNEGO/Kerberos wire format, and pure-Python DES/MD4/RC4 implementations for NTLM — so it keeps working even where a system’s crypto or GSSAPI libraries are missing or incomplete. Combined with the automatic backend-selection logic in _new_context(), this gives callers a single API that behaves consistently across Windows, Linux, and macOS with a graceful degradation path from native platform auth to pure-Python fallbacks.

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

Search