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!',
);

# All methods return Futures
my $blob = await $store->set('session_id', { user_id => 123 });
my $data = await $store->get($blob);
await $store->delete('session_id');

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).

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 $future = $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 $future = $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

my $future = $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 initialization vector (IV) is generated from Crypt::PRNG, which uses system sources of randomness such as /dev/urandom as a seed.

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