CodeHerderSearch⌘KRequest access →

Self-hosted retention and data subject requests

How long each class of data is kept, the setting that changes it, and how to answer a data subject request, with backup residue.

Your organization runs the install, so your organization answers data subject requests. This page gives you the retention schedule and a procedure to follow. CodeHerder deletes data on a schedule. You can change most schedules.

How data is erased

Three paths erase data. Each row below names the path that applies.

  1. Sweep. The server deletes a row when its period ends. The setting column controls the period.
  2. Workspace delete. Archive the workspace first. A delete of a workspace that is not archived fails with 409 not_archived. Then run ch workspace delete. The delete is permanent. It removes the rows of the workspace and its child workspaces. It queues the attachment objects for deletion from the object store.
  3. Person erase. Run ch human erase. See Handle a data subject request.

These defaults are a starting point. Your organization approves its own retention schedule.

Retention by data class

Each row names a class of data, its default period, and the setting that changes it. A setting is an environment variable on the server. A period of 0 turns the sweep off for most settings. Read the setting’s line in the configuration reference before you use 0. A setting that the schedule marks “read at server start” needs a restart. Every other setting is read on each sweep.

Data Default Setting What you may change Erased by
Session exit tail (the last terminal output) 30 days after the session ends CH_SESSION_EXIT_TAIL_RETENTION_DAYS The period. 0 disables. Sweep after the period
Execution observations 90 days CH_EXECUTION_OBSERVATION_RETENTION_DAYS The period. 0 disables. Sweep after the period
Session resource usage 90 days CH_SESSION_RESOURCE_USAGE_RETENTION_DAYS The period. 0 disables. Sweep after the period
Survey responses 365 days. A pending invitation stays. CH_SURVEY_RESPONSE_RETENTION_DAYS The period. 0 disables. Sweep after the period
Calibration corpora 365 days CH_CALIBRATION_CORPUS_RETENTION_DAYS The period. 0 disables. Sweep after the period
Agent questions 365 days after the answer. An open question stays. CH_AGENT_QUESTION_RETENTION_DAYS The period. 0 disables. Sweep after the period
Messages 365 days CH_MESSAGE_RETENTION_DAYS The period. 0 disables. Sweep, workspace delete or person erase
Task comments 730 days CH_TASK_COMMENT_RETENTION_DAYS The period. 0 disables. Sweep, workspace delete or person erase (text becomes [erased])
Workspace invitations 90 days after acceptance, revocation or expiry. A live invitation stays. CH_WORKSPACE_INVITATION_RETENTION_DAYS The period. 0 disables. Sweep after the period
Sandboxes 30 days after the sandbox is done or abandoned CH_SANDBOX_TERMINAL_RETENTION_DAYS The period. A value of 0 or less keeps the default. Sweep after the period
Attempt outcomes and effort 400 days CH_ATTEMPT_OUTCOME_RETENTION_DAYS The period. 0 or less disables. Sweep after the period
Trial runs 400 days CH_SHADOW_RUN_RETENTION_DAYS The period. 0 or less disables. Sweep after the period
Compositions and outcomes 730 days CH_COMPOSITION_RECORD_MAX_AGE_DAYS The period. Sweep after the period
Events (activity and audit log) 180 days. Device metric events: 7 days. Audit and milestone events are not pruned by the metrics sweep. CH_EVENTS_MAX_AGE_DAYS, CH_EVENTS_METRICS_RETENTION_DAYS Both periods. Sweep after the period
Raw cost rows 90 days CH_COST_RAW_RETENTION_DAYS, CH_COST_EVENTS_MAX_AGE_DAYS Both periods. 0 disables. Cost totals stay. Sweep after the period
Server metrics 30 days CH_SERVER_METRICS_RETENTION The period. Sweep after the period
Device metrics history 7 days CH_DEVICE_METRICS_HISTORY_RETENTION_DAYS The period. 0 disables. Read at server start. Sweep after the period
Audit trace state 48 hours for an open span CH_OTEL_SPAN_MAX_AGE The span age. Sweep after the period
Agent notifications 30 days delivered, 7 days pending CH_NOTIFICATION_DELIVERED_RETENTION_DAYS, CH_NOTIFICATION_PENDING_RETENTION_DAYS Each period. 0 disables. Read at server start. Sweep after the period
Outbound webhook deliveries 30 days. A pending row stays. CH_WEBHOOK_DELIVERY_RETENTION_DAYS The period. 0 disables. Use 1 day or more. Sweep after the period
Inbound webhook deliveries 30 days CH_INBOUND_WEBHOOK_DELIVERY_RETENTION_DAYS The period. 0 disables. Sweep after the period
Session API keys 30 days after a session key is revoked CH_SESSION_API_KEY_RETENTION_DAYS The period. 0 disables. Read at server start. Sweep after the period
Attach grants 7 days past expiry (revoked rows) CH_ATTACH_GRANT_RETENTION_DAYS The period. 0 disables. Read at server start. Sweep after the period
Device token last remote IP 90 days after the token was last seen CH_DEVICE_TOKEN_REMOTE_IP_RETENTION_DAYS The period. 0 disables. Sweep after the period
Idempotency cache 1 hour CH_IDEMPOTENCY_RETENTION The period. Read at server start. Sweep after the period
Pending registrations and email changes 24 hours CH_PENDING_IDENTITY_RETENTION_HOURS Lengthen only. The server floors it at 24 hours. Sweep after the period
Shared document change log 30 days CH_SHARED_DOC_CHANGES_RETENTION_DAYS The period. 0 disables. Sweep after the period
MCP OAuth clients 7 days CH_MCP_OAUTH_CLIENT_MAX_AGE_DAYS The period. Sweep after the period
Agent-created (ephemeral) workspaces 72 hours, unless a person joined CH_EPHEMERAL_WORKSPACE_TTL_HOURS The period. Sweep after the period
Short protocol windows (OAuth requests and grants, upload staging) Minutes to 24 hours none Nothing. These bound a security window. Expiry of the window

The server also keeps a terminal attach buffer in its own memory. It ends after 6 hours idle. CH_ATTACH_RING_IDLE_TTL is a server setting that changes it. A server restart clears it.

These classes have no timer. They stay until you delete the owner:

Data Kept until Erased by
Tasks, task fields and their history; session records; repositories; workflows, stages and skills; optimization data; reports; alerts; wiki pages; attachments; cost totals The workspace is deleted. Archive hides an item. It does not delete it. Workspace delete
People and access (humans, members, memberships, teams) The person is erased. See Handle a data subject request. Person erase
Devices and AI accounts The workspace of the device owner is deleted. Archive hides a device. It does not delete it. A device stays when another workspace it serves is deleted. Workspace delete of the owner’s home workspace. The device’s AI accounts and tokens go with it.
Secrets and credentials (variables, launch configurations, device tokens, SSO connections, webhook endpoints) You revoke, rotate or delete them. Revoke, rotate or delete
Branding, SSO and import configuration The workspace is deleted. Workspace delete
The authentication audit log and the instance audit log The instance is deleted. No sweep prunes them. None. It lasts for the life of the instance.
The revocation journal The instance is deleted. Nothing prunes it. None. It lasts for the life of the instance.

Every class above stays in the stores listed in Erased data in backups until each store expires it. That is the backup residue of every class.

Server log retention is a separate setting. See Self-hosted log retention and access for the log classes.

Data on devices

The device keeps its own copies. The transcript archive keeps 7 days. Set CH_TRANSCRIPT_ARCHIVE_RETENTION_DAYS on the device to change it. 0 keeps the archive. The device log files keep up to 8 MB (CH_LOCAL_LOG_BUDGET_MB). Worktrees stay on the device until you remove them. See What a device keeps.

Handle a data subject request

Follow these steps in order. You need instance operator rights.

  1. Find the person’s data.
    • Run ch member list in each workspace. Match on email or member id.
    • Run ch member show <ref>. Run ch member tasks <ref> --role filed and --role worked.
    • Run ch task list --created-by <uuid>.
    • Search messages and comments the person wrote.
    • Search the instance audit log and the authentication audit log for the person’s email.
  2. Export. Run ch workspace export <workspace> --out <file>.zip for each workspace the person belongs to. The archive holds the workspace’s records and attachments. It leaves out secret values, transcripts and launch configurations. The archive covers the whole workspace. Pick out the person’s rows before you release anything. These rows are members, humans, invitations, events by the person, comments and messages.
  3. Review work product. The erase keeps task titles and text, wiki pages and attachments, because the team owns them. Edit or archive personal text before you erase.
  4. Erase. Run ch human erase <ref> for a dry run. Read the row counts. Then run ch human erase <ref> --apply --yes. The erase refuses a person who owns a device or device token, operates an agent, owns a persona wiki page, holds a live API key, has a live session, or holds a membership outside their home account. Revoke or transfer each one first. ch human revoke-all revokes credentials. Deprovision removes access. See Offboard a person. The erase removes the member and human rows, the messages the person sent and the keys that hang from the member. It replaces the person’s comment text with [erased] and removes personal keys from their events. The erase cannot be undone.
  5. Identity provider step. Read identityDeletion in the erase response.
    • Cognito mode. The server deletes the Cognito user after the database commit. The value is deleted. If the value is failed, delete the user by hand. The response names the subject. The server role needs cognito-idp:AdminDeleteUser. See Grant the lifecycle permissions.
    • OIDC mode. The value is not_managed. The user is your corporate identity. CodeHerder does not delete it. Whether to delete or keep it is your decision, because the person may still work for you. Write the decision in the DSAR record. The erased member does not come back if the person signs in again.
  6. Handle what the erase does not reach.
    • Revoke pending invitations to the person’s email.
    • Remove the person from webhook receivers, SIEM and log stores under your own rules.
    • Remove device-side data (see above).
    • Instance audit log rows for an erased operator stay. This is the audit trail.
  7. Keep a record. Write the request date, the person, the workspaces, the export files, the erase response, the identity provider action and the date the last backup expires.

Erased data in backups

An erase changes the live database only. Erased rows stay in each of these stores until the store expires them.

Store How long the erased data stays
RDS automated backups and point-in-time recovery Until the backup retention period ends. You set it. Seven days is a common start. See Back up the database.
Manual RDS snapshots and pg_dump files Until you delete them.
Attachments bucket, older object versions and replicas Until your lifecycle rule expires them. The erase keeps the live object.
Server, proxy and database logs The journald or log store retention. See Self-hosted log retention and access.
Webhook receivers and audit receivers The receiver’s retention.
Revocation journal It holds the person id and a time only. It holds no name or email. Keep it at least as long as your longest backup.
Device transcript archive 7 days by default.
Cognito user pool The pool is not part of the database restore. If you roll the pool back, delete the user again.

A restore brings erased rows back. After a restore, run ch instance restore-fence replay --yes. It applies again each erase made after the recovery point. See Recover. The data is gone everywhere on the date the request closes plus the longest window in the table.

Last updated

CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch the work move. Costs update as it happens.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close