Defense-grade Django middleware: session security, audit logging, and configurable request gates with hooks.
Project description
SessionArmor
Defense-grade Django middleware: session security, audit logging, and configurable request gates with hooks.
Part of the Tunet ecosystem — alongside SwapLayer and InfraGlyph.
What It Does
SessionArmor provides three drop-in Django middleware classes that harden your application's session layer:
| Middleware | Purpose |
|---|---|
SessionSecurityMiddleware |
Fingerprint binding, absolute/idle timeouts, claim drift detection |
AuditMiddleware |
Privacy-preserving security audit trail for every authenticated request |
GateMiddleware |
Base class for building cacheable conditional gates (compliance, onboarding, feature flags) |
All three are hookable — override methods to customize behavior without touching internals.
References
- NIST SP 800-53 AC-12 (Session Termination)
- NIST SP 800-53 SC-23 (Session Authenticity)
- NIST SP 800-53 AU-3/AU-12 (Audit Content/Generation)
- OWASP Session Management Cheat Sheet
Installation
pip install SessionArmor
Quick Start
# settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# ... your auth middleware ...
'session_armor.session.SessionSecurityMiddleware',
'session_armor.audit.AuditMiddleware',
# ... rest of your middleware ...
]
# Optional settings (shown with defaults)
SESSION_ABSOLUTE_TIMEOUT = 28800 # 8 hours
SESSION_IDLE_TIMEOUT = 1800 # 30 minutes
SESSION_BIND_IP = True
SESSION_BIND_USER_AGENT = True
SESSION_DETECT_CLAIM_DRIFT = True
SESSION_ARMOR_TRUSTED_PROXY_DEPTH = 1 # Number of trusted reverse proxies
Building a Gate
from session_armor import GateMiddleware
from django.shortcuts import redirect
class ComplianceGate(GateMiddleware):
gate_id = 'compliance'
cache_ttl_setting = 'COMPLIANCE_CACHE_TTL'
default_cache_ttl = 3600
fail_open = False # Block access if check fails
def check(self, request) -> bool:
return user_accepted_current_terms(request)
def on_reject(self, request):
return redirect('/accept-terms/')
Customizing Session Security
from session_armor import SessionSecurityMiddleware
class MySessionSecurity(SessionSecurityMiddleware):
exempt_paths = ('/health/', '/static/')
def get_critical_claims(self, user):
# Auth0 / OIDC claims that must not change mid-session
return [user.sub, user.organization_uuid, user.platform]
def get_login_url(self, request):
platform = getattr(request.user, 'platform', '')
return f'/{platform}/login/' if platform else '/login/'
Customizing Audit Logging
from session_armor import AuditMiddleware
class MyAudit(AuditMiddleware):
exempt_paths = ('/health/', '/static/', '/favicon.ico')
def get_user_identity(self, request):
return {
'uid': request.user.sub,
'platform': request.user.platform,
'org': request.user.organization_uuid,
}
Development
# Clone and install
git clone https://github.com/Tunet-xyz/session_armor.git
cd session_armor
pip install -e ".[dev]"
# Run tests
pytest
# Lint
ruff check src/session_armor tests
# Type check
mypy src/session_armor
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sessionarmor-0.1.0.tar.gz.
File metadata
- Download URL: sessionarmor-0.1.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dbc88c51f3428d562d8173dfb0bef1869db7c3149fee03b3c1fa6b8296f71e7
|
|
| MD5 |
17c44bf6cf49edba05a4a26393b8c96b
|
|
| BLAKE2b-256 |
ec11e73fd6e574b97f332fcec3efd67d08b1e4f01de0491e06171b48052abb71
|
Provenance
The following attestation bundles were made for sessionarmor-0.1.0.tar.gz:
Publisher:
publish.yaml on Tunet-xyz/session_armor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sessionarmor-0.1.0.tar.gz -
Subject digest:
0dbc88c51f3428d562d8173dfb0bef1869db7c3149fee03b3c1fa6b8296f71e7 - Sigstore transparency entry: 1604129905
- Sigstore integration time:
-
Permalink:
Tunet-xyz/session_armor@72985c38ccfb0e91536c29aae2ad33c74294db7d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Tunet-xyz
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@72985c38ccfb0e91536c29aae2ad33c74294db7d -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file sessionarmor-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sessionarmor-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95ab2a9574f31326d8358b9e7e6a8a0156e3cdb44f30fe8c03e41554e747ba63
|
|
| MD5 |
bed5a39770ad0c5d6548b72bf9f9f15f
|
|
| BLAKE2b-256 |
846b830dcd8084217d0d0471a3a9a84d30734c800f52c67d5728b9c753eaf0cc
|
Provenance
The following attestation bundles were made for sessionarmor-0.1.0-py3-none-any.whl:
Publisher:
publish.yaml on Tunet-xyz/session_armor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sessionarmor-0.1.0-py3-none-any.whl -
Subject digest:
95ab2a9574f31326d8358b9e7e6a8a0156e3cdb44f30fe8c03e41554e747ba63 - Sigstore transparency entry: 1604130043
- Sigstore integration time:
-
Permalink:
Tunet-xyz/session_armor@72985c38ccfb0e91536c29aae2ad33c74294db7d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Tunet-xyz
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@72985c38ccfb0e91536c29aae2ad33c74294db7d -
Trigger Event:
workflow_dispatch
-
Statement type: