License: Artistic-2.0 CPAN Version GitHub release (latest by date) GitHub Release Date

kwalitee codecov Coverage Status DeepWiki

GH Actions: Linux Build GH Actions: Windows Build GitHub repo size GitHub pull requests

Dancer2-Session-Pg

PostgreSQL session backend for Dancer2

VERSION

version 0.001

STATUS

Package Dancer2::Session::Pg is under development so changes in the API are possible, though not likely.

SYNOPSIS

use Dancer2::Session::Pg ();

my $engine = Dancer2::Session::Pg->new(
    dsn              => 'dbi:Pg:dbname=app;host=db',
    dbuser           => 'app_web',
    dbpass           => $ENV{'APP_DB_PASSWORD'},
    dbtable          => 'sessions',          # required
    dbschema         => 'web',               # optional; else search_path
    session_duration => 900,

    # One or more SLOTS, each pairing a key with the cipher that uses it.
    # Exactly one is active: that is the one sessions are written with, and
    # the rest stay to be read. See SECURITY for where the key comes from.
    encryption_keys => {
        0 => {
            key    => $ENV{'SESSION_KEY_0'},
            alg    => 'AES-256-GCM',
            active => 1,
        },
    },

    # Optional; see THE PRINCIPAL COLUMN for whether you want it at all.
    principal_key    => 'principal',
    principal_column => 'account_id',
);

Most applications configure this from config.yml rather than in Perl -- see "A configuration file" in Dancer2::Session::Pg. Installing the engine by hand is for when dbh has to be a coderef, something YAML cannot express, and there is a trap in doing it which "CONNECTIONS" in Dancer2::Session::Pg describes.

DESCRIPTION

Stores Dancer2 sessions in PostgreSQL, and uses PostgreSQL's own features to make that storage safer than a serialised blob in a table.

A web session is not ordinary data. It frequently carries the credentials that prove who somebody is -- with OpenID Connect, an access token and a refresh token -- so the store is worth more than the account it belongs to. Three properties follow from that, and each is provided by the database rather than by convention:

On top of that, an optional clear column beside the encrypted payload makes it possible to find and end every session belonging to one account without decrypting anything -- see "destroy_for_principal" in Dancer2::Session::Pg. Suspending an account has little effect while the suspended user's cookie still works. That column is off by default and need not exist; "THE PRINCIPAL COLUMN" in Dancer2::Session::Pg is about whether you want it.

Why this is PostgreSQL and not portable SQL

A reasonable question, since a session row is four columns and a blob. The answer is that the three guarantees above are not properties of the schema -- they are properties of statements and settings that standard SQL either does not have or does not define strongly enough to rely on.

None of this rules out a portable session store -- it rules out a portable one with these properties. A session table meant to run on several engines is a reasonable thing to want, and it is a different module from this one. This one is for the case where the session store is the most security-sensitive table in the database, and you would rather the database enforced that than your application remembered to.

REQUIREMENTS

PostgreSQL 9.5 or later, for INSERT ... ON CONFLICT DO UPDATE -- see "Why this is PostgreSQL and not portable SQL" in Dancer2::Session::Pg for why that statement and not the standard MERGE.

Perl v5.14 or later (Dancer2's required Perl as per Dancer2 v1.0.0).

💻 Contributors

GitHub Contributors Image

LICENSE

This software is copyright (c) 2026 by Mikko Johannes Koivunalho mikko.koivunalho@iki.fi.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

Terms of the Perl programming language system itself:

a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License"

The complete licenses are in the files LICENSE-Artistic-2.0 and LICENSE-GPL-3 within this repository. If these files are missing, they can be downloaded from the following urls:

* https://www.gnu.org/licenses/
* https://www.perlfoundation.org/artistic-license-20.html