Encrypted session interface for Quart using enciphers.
Replaces Quart's default signed cookie session with a fully encrypted one.
Version 3.0 requires
enciphers>=3,<4. Existing 2.x session cookies remain readable with the same key and backend. See Upgrading from 2.x and CHANGELOG.md.
python -m pip install "quart-enciphers>=3,<4"from quart import Quart, session
from quart_enciphers import EnciphersSession
app = Quart(__name__)
EnciphersSession(app)
@app.route("/login")
async def login():
session["user_id"] = 1
return "logged in"from quart import Quart
from quart_enciphers import EnciphersSession
es = EnciphersSession()
def create_app():
app = Quart(__name__)
es.init_app(app)
return app| Key | Type | Default | Description |
|---|---|---|---|
ENCIPHERS_BACKEND |
str |
"AES256_GCM" |
"AES256_GCM" or "XCHACHA20_POLY1305" |
ENCIPHERS_KEY |
int |
random | Secret key, a 128-bit value |
ENCIPHERS_KEY_ENV |
str |
None | Name of an environment variable containing the key as a decimal integer |
Set at most one of ENCIPHERS_KEY and ENCIPHERS_KEY_ENV, before
calling EnciphersSession(app) or init_app(app). Generate a key once
with secrets.randbits(128) and persist it for production use.
For example, with CIPHER_KEY set to the stored key's decimal value:
from quart import Quart
from quart_enciphers import EnciphersSession
app = Quart(__name__)
app.config["ENCIPHERS_KEY_ENV"] = "CIPHER_KEY"
app.config["ENCIPHERS_BACKEND"] = "AES256_GCM"
EnciphersSession(app)If no
ENCIPHERS_KEY/ENCIPHERS_KEY_ENVis provided, a random key 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.
If session.permanent is set (giving the cookie an Expires attribute), the
same expiry is also bound inside the encrypted token itself — a copy of
the cookie can't be replayed past that point even if a client ignores
the cookie's own expiration. A non-permanent session cookie (the
default) uses expires_at=None, so the token has no embedded expiry.
- Upgrade
quart-enciphersto 3.x; it now requiresenciphers>=3,<4. Update any explicitenciphers<3pins in your application as well. - Keep the same
ENCIPHERS_KEY(or environment value) andENCIPHERS_BACKEND. The token format and key derivation are unchanged, so existing 2.x sessions survive the upgrade without a new login. - Explicit
ENCIPHERS_KEY=0is now honored; previous releases silently replaced it with a random key. Use a persisted random 128-bit key in deployments. Sessions created using the old random fallback cannot be read with the newly honored zero key. - The
EnciphersSessionAPI and configuration keys are unchanged.enciphers3 rejectsencrypt(..., expires_at=0); this interface already passesNonefor non-permanent sessions and Unix timestamps for permanent sessions. If your application callsencryptdirectly, replace zero expiries withNoneand review the upstream migration notes. - Upgrade all workers to receive the upstream fix for nonce generation
after
fork.
Cookies from quart-enciphers 0.1.x are still incompatible and open as
empty sessions; users with those cookies need to log in again.
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -e .
python -m unittest discover -s tests -vTests exercise both encryption backends with real Quart requests,
including expiry, invalid cookies, and fixed tokens created by
enciphers 2.0.0. The 3.0.0 wheel was tested on Python 3.11–3.14.
Build the wheel and source distribution locally with:
python -m pip install hatchling
python -m hatchling buildArtifacts are written to dist/.
Apache-2.0 — Copyright 2026 Mejlad Alsubaie