Documentation
AssayAccess, retention and erasure
Updated
Assay separates two kinds of data. Usage is the shape of a run: models, tokens, timings, outcomes, tool names. Content is what was said: instructions, messages, outputs, tool arguments and results, plus everything built from them, such as flags, datasets and exports. Each has its own access rule.
Who can see what
Membership and roles are managed in Assay's Settings (/settings). Only active members are admitted.
| Role | Usage | Content |
|---|---|---|
| Owner | Always | Always |
| Admin | Always | Yes by default; can be denied by an Owner |
| Member | Always | No by default; can be granted by an Owner or a content-capable Admin |
Usage access covers the dashboard, CSV and JSON tables, the risk guide and the usage MCP tools. Content access covers run trees with content, curation, datasets, exports, content search and subject erasure.
People who reach Assay through Scalpels (for example an agent relaying a call through the Scalpels MCP server) are treated as Admins if they are a team Owner or Admin, and as Members otherwise.
Override content access
Open /assay/access. The page is available to Owners, and to Admins who currently have content access. It lists every person with their role, status, usage and content access, where the content decision comes from (owner, role default or override) and whether an override is redundant because it matches the role default.
For each person you can:
- set content access to granted or denied, with an optional reason of up to 500 characters;
- Reset to role default, which removes the override.
Owners can override Admins and Members. An Admin with content access can override Members only. Nobody can override an Owner. An override is kept if the person is removed and later re-invited, but membership is always checked first: a removed person has no access whatever their override says.
Retention
The scheduler prunes data every day at 02:00, in bounded batches. The defaults:
| Data | Kept for |
|---|---|
| Run content (messages, outputs, tool data) | 30 days |
| Usage metadata | 395 days |
| Dataset items | 365 days from when the item was added, or per dataset |
| Encrypted residue of failed ingest jobs | 72 hours, never longer than run content |
A live dataset item keeps the usage metadata of its source run and that run's ancestors until the item expires, but not their content. The server-side periods can be changed; see Configuration.
Erase a subject
Erasure removes one subject's content from one application. It is done through the delete_subject MCP tool, which needs content access; there is no button for it in the web screens. See Use Assay from your agent for connecting an MCP client.
delete_subject takes the application's name (its app value) and the subject string, and runs in two phases:
- Preview. Assay reports how many runs match and what will happen. Nothing changes.
- Confirm. Assay deletes the subject's captured content and its dataset items, and replaces the subject on the remaining usage records with a tombstone of the form
deleted:<hmac>.
After erasure:
- usage totals are unchanged, so reports still add up;
- the tombstone is pseudonymous, not anonymous: the erased subject's activity can still be grouped together, just not tied back to the identifier;
- records for that subject that arrive late but happened before the erasure (queued or retried batches) are blocked from writing content back;
- new activity for the same subject after the erasure is accepted normally;
- later dataset exports no longer contain the subject's items.
Tombstones are built with the dedicated ASSAY_ERASURE_KEY that Scalpels generated during the install. Do not change or remove it: a replaced key orphans every earlier erasure, and a missing or malformed key makes Assay refuse incoming telemetry that carries a subject.
Backups and restores
Erasure does not reach infrastructure backups. Keep your database backup retention no longer than the content promise you make to your users.
Every erasure is also written to the erasure journal in the object storage bucket, outside the database. If you restore a database snapshot, reapply the journal before normal use. Run this inside the Assay environment, for example from Laravel Cloud's command runner for it, with the time the snapshot was taken:
php artisan assay:erasures:reapply --since=2026-10-01T12:00:00Z
The command replays journal entries newer than that time, 1,000 at a time by default (--limit). It reports how many entries were reapplied, how many runs were affected, and how many content rows and dataset items were deleted. If there is more to do, or an entry failed, it prints a --cursor= value; run the command again with that cursor to continue.