Security ======== ``fleche`` provides a built-in cryptographic security layer for filesystem-based storage backends (``PickleFile``, ``CloudpickleFile``, and ``DillFile``) to protect against insecure deserialization vulnerabilities. This prevents arbitrary code execution if an attacker manages to tamper with or replace the cache files. Enabling Security ----------------- Security is controlled solely via the ``FLECHE_SECRET_KEY`` environment variable. By default, if this variable is not set, the security features are **turned off**, and caches are read and written as plain serialized files. To enable security, export a hex-encoded secret key before running your application: .. code-block:: bash export FLECHE_SECRET_KEY="$(python -c 'import secrets; print(secrets.token_hex(32))')" The value must be a hex-encoded string (``[0-9a-f]+``) of any length. ``fleche`` decodes it to raw bytes before use. When enabled, ``fleche`` will compute an HMAC-SHA256 signature for all newly cached data and append it to the file as a 64-byte hex string. Upon loading, ``fleche`` separates the signature and verifies the integrity of the data. If the signature is invalid or missing entirely from a modified file, a ``KeyError`` is raised, effectively treating the entry as a cache miss. Backward Compatibility -------------------- The signing implementation is designed to be partially backward compatible. Signatures are appended to the *end* of the ``pickle`` byte stream. 1. **Unsigned to Signed:** Once security is enabled with a secret key, **all** cache entries must be signed. Existing completely unsigned cache files will fail validation and be treated as misses, requiring caches to be rebuilt securely. 2. **Signed to Unsigned:** If you disable the secret key, or a different unauthenticating instance reads the cache, the standard ``pickle`` library will successfully load the data and naturally ignore the trailing 64-byte signature. Key Rotation and Distributed Trust ---------------------------------- You can specify multiple hex-encoded keys separated by colons in the environment variable. .. code-block:: bash export FLECHE_SECRET_KEY="aabbccdd01:eeff009988:1122334455" When multiple keys are provided: * **Writing:** The *first* key in the list (``aabbccdd01``) is always used to sign new cache entries. * **Reading:** ``fleche`` will iterate through *all* keys in the list. If the cache file's signature matches *any* of the configured keys, the data is accepted. This allows you to seamlessly rotate compromised or old keys without invalidating your existing cache, and it allows you to load and trust data generated by other known ``fleche`` installations.