Sessions and vault¶
A session holds the mapping from each token to the value it replaced. Privyx uses it to restore the reply, so a request and its reply must share a session. Sessions are kept in the vault.
Which session a request uses¶
A request that carries an x-privyx-session header uses that session. Privyx
strips the header before forwarding, and the transparent proxy returns the id
it used in the response's x-privyx-session header.
Most clients never send the header, so session.strategy decides:
| Strategy | One session per | Use when |
|---|---|---|
ephemeral (default) |
Request | Requests are independent, or you are unsure. Nothing is shared between requests. |
client |
API key | One user per key, and conversations may share a mapping. |
conversation |
API key and first user message | A chat tool resends the conversation each turn. This is what privyx run uses. |
session:
strategy: conversation # or PRIVYX_SESSION_STRATEGY=conversation
With ephemeral, a multi-turn conversation is masked from scratch every turn
and shows up as many sessions. conversation keeps one session per
conversation; two conversations that open with the same first message under the
same key share one. The trade-offs are covered in
Proxy: Sessions.
To keep tokens stable across sessions and restarts regardless of strategy, set an anchor secret.
Vault backends¶
vault.type |
Survives a restart | Shared between processes | Needs |
|---|---|---|---|
memory (default) |
No | No | Nothing |
sqlite |
Yes | Same host, through the file | privyx[sqlite] |
redis |
Yes | Yes | privyx[redis] and a Redis server |
vault:
type: sqlite
dsn: /var/lib/privyx/privyx.db
vault:
type: redis
redis_url: redis://localhost:6379/0
The sqlite vault writes through a write-ahead log, kept in -wal and -shm
files beside the database. Put the database on a local disk: the log does not
work on a network file system such as NFS.
The memory vault lives inside one process, so the privyx session commands,
which run as a separate process, cannot see it. Use sqlite or redis to
inspect or prune sessions.
The vault stores original values in plain text, except with the
encrypt operator. Protect the SQLite file and the Redis
instance like any other store of personal data; see
Data handling.
Expiring sessions¶
An ephemeral session never enters the vault: it lives in the proxy's memory
for its one request and is dropped when the request finishes. Sticky sessions
(client, conversation, or a header) stay in the vault until something
removes them: in a memory vault until the process exits, in sqlite or
redis indefinitely. Set vault.ttl to expire a session after that many
seconds without a request:
vault:
type: sqlite
ttl: 604800 # a week, or PRIVYX_VAULT_TTL=604800
Set one whenever session.strategy is client or conversation: each
conversation leaves a session, with the original values it masked, and without
a TTL they pile up. docker-compose.yml sets a week.
Or clean up by hand. list and show never print original values unless you
ask:
$ privyx session list -c privyx.yaml
SESSION LAST ACTIVE CREATED MAPPINGS
demo 2026-09-27T15:29:37 2026-09-27T15:29:37 1
1 session(s) (vault: sqlite)
$ privyx session show -c privyx.yaml demo
Session: demo
Vault: sqlite
Created: 2026-09-27T15:29:37
Updated: 2026-09-27T15:29:37
Mappings: 1
<PRIVYX_EMAIL_1> → al*************om
(values masked; pass --reveal to show them)
$ privyx session prune -c privyx.yaml --older-than 7d --dry-run
prune records each deletion in the audit trail as session.deleted with
reason: prune. Expiry through ttl is not recorded.
Masking outside the proxy¶
privyx mask and privyx unmask run the same engine on a string, a file, JSON,
or JSONL. The mapping goes either to a map file or to a vault session:
privyx mask --map map.json "mail alice@example.com" # mail <PRIVYX_EMAIL_1>
privyx unmask --map map.json "hi <PRIVYX_EMAIL_1>" # hi alice@example.com
privyx mask -c privyx.yaml --session demo -i request.json --path '$.messages'
A map file is self-contained and needs no vault. --session needs a
persistent vault, since a memory vault is gone when the command exits. See
the CLI reference.