NAME
PAGI::Middleware::Session::Store::Cookie - Encrypted client-side session store
SYNOPSIS
use PAGI::Middleware::Session::Store::Cookie;
my $store = PAGI::Middleware::Session::Store::Cookie->new(
secret => 'at-least-32-bytes-of-secret-key!',
);
DESCRIPTION
Stores session data encrypted in the client cookie itself using AES-256-GCM (authenticated encryption). No server-side storage is needed.
The set() method returns the encrypted blob (not the session ID). The get() method accepts the encrypted blob and returns the decoded session data, or undef if decryption/verification fails.
Limitations: Cookie size is limited to ~4KB. Large sessions will fail. Session revocation requires server-side state (e.g., a blocklist).
Note: This module will be extracted to a separate CPAN distribution in a future release.
METHODS
new
my $store = PAGI::Middleware::Session::Store::Cookie->new(
secret => 'at-least-32-bytes-of-secret-key!',
);
Creates a new cookie session store. The secret parameter is required and is used to derive the AES-256 encryption key via SHA-256.
get
my $data = await $store->get($encrypted_blob);
Decrypts and decodes the blob. Returns a Future resolving to the session hashref, or undef if the blob is invalid, tampered, or cannot be decoded.
set
my $transport_value = await $store->set($id, $data);
Encrypts the session data and returns a Future resolving to the encrypted blob. This blob is what gets passed to State::inject() for storage in the response cookie. Nothing is stored server-side.
delete
await $store->delete($id);
No-op for cookie stores (client manages cookie lifetime). Returns a Future resolving to 1.
SECURITY
Session data is encrypted with AES-256-GCM, which provides both confidentiality (data cannot be read) and authenticity (data cannot be tampered with). The encryption key is derived from the secret via SHA-256.
Each encryption uses a random 12-byte IV, so the same session data produces different ciphertext each time.
IV Generation
The encryption IV is generated from /dev/urandom when available (all modern Unix/Linux/macOS systems). On systems without /dev/urandom, the module falls back to Perl's rand(), which is not cryptographically secure -- a runtime warning is emitted in this case. If you are running on such a system, install Crypt::URandom and the module will use it automatically.
Note: A predictable IV does not compromise the confidentiality or authenticity of AES-GCM (the key is still required), but it may allow an attacker to detect when the same session data is re-encrypted, which leaks information about session changes.
Cookie Size
HTTP cookies are limited to approximately 4KB by most browsers. Large session data will produce cookies that exceed this limit and be silently rejected by the browser. Keep session data small.
AUTHORS
John Napiorkowski
OpenAI Codex
Anthropic Claude
LICENSE
This software is Copyright (c) 2026 by John Napiorkowski.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
For the full license text, see:
https://www.perlfoundation.org/artistic-license-20.html
SEE ALSO
PAGI::Middleware::Session::Store - Base store interface
PAGI::Middleware::Session - Session management middleware