Erasure requests and legal holds
Delete telemetry rows on request (GDPR right to erasure) with an audit trail.
POST /v1/projects/{prj}/deletions(DeleteTelemetry):kindisfilter(a Lucene query over logs or traces) oruser(attributesubject.key, defaultuser.idandenduser.id; logs, traces and error tags).fromis inclusive,toexclusive.preview: trueonly counts matching rows per signal.States:
pending_approval,queued,running,verifying,completed,failed,cancelled. Projects withdeletion_approval = second_admin(default) needPOST .../{id}/approvefrom a different user withManageSecurity; self-approval is 422.POST .../{id}/cancelstops a request that has not started.The janitor deletes the rows in ClickHouse, verifies none match, marks overlapping
archive_objectsaserased_at(the archiver rewrites them) and completes the request with a SHA-256 ledger hash. The request's compiled conditions stay indeletion_requests.filter;wt_query::erasure::rules_from_ledgerandpredicate_forgive rehydration the predicate that drops erased rows.traceserasure leavestrace_index_v1summaries (no payload).Audit actions:
deletion.create|approve|cancel|complete,legal_hold.create|release. Metadata holds the filter text and the subject key, never matched data or the subject value.
Legal holds
POST|GET /v1/orgs/{org}/legal-holds, DELETE .../{id} (ManageSecurity). A hold covers a project (or the whole org), optional signals and an optional filter. While active, deletions, retention shortening and project delete or purge answer 409 legal_hold (detail names the hold id). The janitor sets retention_days = 36500 on held rows hourly so TTL cannot drop them. A hold with a filter narrows only the TTL extension; overlap checks for blocking are by project and signal.