fastapi-enciphers
Encrypted session middleware for FastAPI using enciphers.
Replaces Starlette's default signed cookie session with a fully encrypted one.
Version 3.0 supports
enciphers>=3,<4. Existing 2.x session cookies remain readable with the same key and backend. See Upgrading from 2.x and CHANGELOG.md.
Installation
python -m pip install "fastapi-enciphers>=3,<4" fastapi
Requires Python 3.11+ and Starlette 1.x. When upgrading an existing FastAPI application, use a FastAPI version that supports Starlette 1.x.
Usage
Generate a key once, store it securely, and configure CIPHER_KEY with
its decimal value. Reuse this value across restarts and workers:
python -c 'import secrets; print(secrets.randbits(128))'
from fastapi import FastAPI, Request
from fastapi_enciphers import EnciphersMiddleware
from enciphers import Backend
app = FastAPI()
app.add_middleware(
EnciphersMiddleware, backend=Backend.AES256_GCM, key_env="CIPHER_KEY"
)
@app.get("/login")
async def login(request: Request):
request.session["user_id"] = 1
return {"status": "logged in"}
@app.get("/profile")
async def profile(request: Request):
return {"user_id": request.session.get("user_id")}
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
backend |
Backend |
Backend.AES256_GCM |
Backend.AES256_GCM or Backend.XCHACHA20_POLY1305 |
key |
int or None |
random if neither key source is provided | Secret key, a random 128-bit value; mutually exclusive with key_env |
key_env |
str or None |
None | Name of the environment variable containing the key as a decimal integer |
session_cookie |
str |
"session" |
Cookie name |
max_age |
int or None |
1209600 | Cookie lifetime in seconds; None or 0 disables expiry |
path |
str |
"/" |
Cookie path |
same_site |
str |
"lax" |
SameSite flag |
https_only |
bool |
False |
Secure flag |
domain |
str |
None | Cookie domain |
If neither
keynorkey_envis provided, a random 128-bit value is generated at startup — fine for local development, but every process in a real deployment needs to share the same key, or sessions won't be portable between them.
Warning: Do not use
EnciphersMiddlewaretogether with Starlette'sSessionMiddleware.
Session expiry
With a positive max_age (the default), every session token carries
an authenticated expiry timestamp in its metadata. The timestamp is
visible but cannot be changed without invalidating the token. Decryption
enforces this expiry even if a client ignores the cookie's Max-Age
attribute. Setting max_age=None removes both; max_age=0 retains
the same behavior for compatibility. Both pass expires_at=None to
enciphers, because version 3 rejects an explicit zero timestamp.
Upgrading from 2.x
- Upgrade to
fastapi-enciphers>=3,<4, which requiresenciphers>=3,<4and Starlette 1.x. The middleware constructor is unchanged. - Keep the same key and backend: existing 2.x cookies, including non-expiring cookies, remain readable. No forced logout or key rotation is required by this migration.
max_ageis a duration in seconds;expires_atinenciphersis an absolute Unix timestamp. Existing middleware configurations withmax_age=Noneor0continue working. Any application code callingcipher.encrypt(..., expires_at=0)directly must useNoneinstead.- Upgrade every worker to pick up the upstream nonce-generation fix
for ciphers initialized before
fork.
Cookies from 0.1.x remain incompatible and start a fresh, empty session.
Development
python -m pip install -e '.[test]'
python -m pytest
Tests cover both encryption backends, existing 2.x cookies, expiry, invalid tokens, key configuration, HTTP sessions, and WebSockets.
License
Apache-2.0 — Copyright 2026 Mejlad Alsubaie
Metadata
Release files for fastapi-enciphers 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastapi_enciphers-3.0.0.tar.gz | 13.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastapi_enciphers-3.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.4 kB
Release files / fastapi_enciphers-3.0.0.tar.gz
| Download URL | fastapi_enciphers-3.0.0.tar.gz |
|---|---|
| Size | 13.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6b0f3034bd55718a1775194ffc8547fcf6720923ac6698536ccc034edfa43da0
|
|
BLAKE2b-256 checksum How to use checksums |
39468b7e14664c273c41c6d6ce7644b37ff166ca957d40fb1cc6e055ab2bb0af
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.
Transparency logRelease files / fastapi_enciphers-3.0.0-py3-none-any.whl
| Download URL | fastapi_enciphers-3.0.0-py3-none-any.whl |
|---|---|
| Size | 9.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3b136b9ba725b0eb91b7ca3df4d7b6ecd02b1d653ce309997fa24a791f240154
|
|
BLAKE2b-256 checksum How to use checksums |
92f5b984c7a8094f1911258467907a777fd0c2b85612c7a77bb2e8e166be83a6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.
Transparency log