vitrinka.docs

Retention and deletion

What is kept for how long, how a purge runs, and what it means to crypto-shred a workspace.

Recorded sessions

A deleted session is soft-deleted first and purged after a grace period: VITRINKA_RETENTION_GRACE (720h, thirty days, by default). A sweeper runs every VITRINKA_RETENTION_SWEEP (1h by default, never under a minute) and, for each session past grace, deletes its blobs under uploads/sessions/<id>/, then its event rows, then the session row — blobs first, so a crash between steps leaves something the next sweep finds again rather than an orphan. Deletes run in batches of two thousand rows. The purge also removes what the session projected: its run set and the screenshots copied into it, its journey board with cards and annotations, its OCR and search rows, and cached thumbnails.

Workspace admins can also set a maximum age under Settings → Workspace → Members → Sessions → recorded-session max age (days, 0 keeps forever; sessionMaxAgeDays at PUT /api/v1/workspace/settings). A finished session older than that is soft-deleted by the sweeper and enters the same grace window; a session still recording is left alone until it ends.

Board card trash

A deleted board card stays restorable in the trash for 30 days and is then purged with its files. The window is fixed for every workspace.

Control-plane rows

The control database enforces its own windows in SQL, one rule each and independent of one another:

RowsKept
Notifications, read or unread90 days
Settled invitations (accepted, declined, revoked or expired)365 days after settling — a pending invitation that has not expired is never touched
Waitlist entries, approved or not365 days

The audit trail is not on this list; it is kept for the life of the organization (Audit trail).

Crypto-shredding a workspace

Erasing a whole workspace destroys its wrapped data-encryption key and writes a tombstone that blocks a replacement key from being minted. Every byte sealed under that key — session payloads, blobs, cache entries, and its content inside every backup taken after the shred — is unreadable from that moment. No key material is needed for the operation: only the wrapped row and its tombstone are touched.

vitrinka shred-workspace -data /data <workspace>                                   # dry-run report
vitrinka shred-workspace -data /data <workspace> -server-stopped -execute          # the shred
vitrinka shred-workspace -data /data <workspace> -revive -accept-legacy-plaintext -server-stopped -execute

Three properties to know before running it:

  • The server must be stopped, and you assert it. A running server keeps the unwrapped key in memory for a pooled workspace and would keep serving it until that handle is evicted; -execute refuses without -server-stopped.
  • Rows and blobs are not deleted. The shred makes them unreadable; storage is reclaimed by your normal retention of the volume or bucket. Backups taken before the shred still carry the wrapped key and can reproduce the workspace until they rotate out.
  • Revive lifts the tombstone, not the key. -revive lets the workspace serve again: everything sealed under the destroyed key stays dead forever, while rows and blobs written before encryption shipped — legacy plaintext, if any — become readable again. That resurrection is why revive demands -accept-legacy-plaintext.

Every run is a dry-run report until -execute is passed. Read the report: it names the workspace by slug and id and the number of sealed rows that will die.

On this page