삭제와 소거
삭제 요청을 기한 안에 처리하세요.
Tahoe에서 읽은 데이터를 조금이라도 저장한다면, 이 페이지는 기능이 아니라 의무를 설명합니다. Tahoe는 세 종류의 삭제 신호를 알려 주며, 각각 다르게 대응해야 합니다. 하나라도 놓치면 데이터의 소유자나 데이터에 담긴 당사자가 지워 달라고 요청한 데이터가 내 사본에 그대로 남습니다.
세 가지 신호
| 신호 | 의미 | 해야 할 일 |
|---|---|---|
삭제 이벤트 (예: applicant.deleted) | Tahoe에서 레코드가 삭제되었습니다. | 해당 레코드의 사본을 삭제하세요. |
applicant.unsubscribed | 본인이 연락받지 않기를 요청했습니다. | 연락을 멈추세요. 레코드는 그대로 두고 아웃리치만 멈추세요. |
삭제(소거) 통지 (data_subject.* 이벤트와 GET /erasures) | 본인이 권리를 행사했거나, 삭제가 요구되었습니다. | 7일 안에 사본을 삭제하고, 그 사람에 대한 처리를 멈추세요. |
삭제 이벤트
삭제 이벤트는 job.deleted, application.deleted, applicant.deleted, sourced_profile.deleted, list.deleted, list_membership.removed의 여섯 가지입니다.
페이로드에는 식별자만 담기며, 삭제된 데이터는 절대 담기지 않습니다. 삭제된 채용 공고, 지원서, 지원자, 소싱한 프로필 이벤트에는 reason도 함께 옵니다. 값은 user_deleted, workspace_deleted, data_subject_erasure, retention_expiry, legal_hold_release, provider_takedown(데이터 출처나 플랫폼이 삭제를 요구한 경우), suppression 중 하나입니다.
사유에 따라 할 일이 달라지지는 않습니다. 레코드를 삭제하세요. 사유는 기록해 두세요. 그래야 나중에 레코드가 왜 사라졌는지 설명할 수 있고, 요구에 따른 삭제와 본인의 요청을 구분할 수 있습니다.
DELETIONS = {
"job.deleted": "job",
"application.deleted": "application",
"applicant.deleted": "applicant",
"sourced_profile.deleted": "sourced_profile",
"list.deleted": "list",
"list_membership.removed": "list_membership",
}
def handle_deletion(store, event):
object_type = DELETIONS[event["type"]]
item = event["data"]["object"]
reason = item.get("reason") # list events carry no reason
# Delete for real. A soft delete that keeps the personal data in a table
# that still answers queries is not a deletion.
store.purge(object_type, item["id"])
store.audit("deleted", object_type, item["id"], reason=reason)수신 거부는 범위가 좁지만, 예외가 없습니다
applicant.unsubscribed는 보관을 멈추라는 뜻이 아니라 연락을 멈추라는 뜻입니다. 고객은 계속 파이프라인을 운영하므로 지원 레코드는 유지하되, 그 사람을 다시는 아웃리치 시퀀스에 넣지 마세요.
삭제 통지: 7일의 기한
이 API에서 가장 강한 신호입니다. 두 가지 경로로 전달됩니다. 삭제 통지 피드와 data_subject.suppression_applied, data_subject.erasure_completed 이벤트입니다.
{
"object": "erasure",
"id": "ers_5Nx3jLm7Qd2s",
"action": "suppression_applied",
"reason": "data_subject_erasure",
"workspace_id": "wsp_4Kd8sPm2Qx7L",
"resources": [
{ "object": "sourced_profile", "id": "cnd_8Fj3kLm2Qd7s", "workspace_id": "wsp_4Kd8sPm2Qx7L" }
],
"action_required": "cease_processing_and_delete_your_copy",
"deadline_at": "2026-09-14T14:02:11.408Z",
"destruction_pending": true,
"destruction_reason": "retention_floor",
"at": "2026-09-07T14:02:11.408Z",
"subject_identified": false
}이 통지에서 알아 둘 네 가지:
deadline_at은 7일 뒤입니다. 이것이 주어진 기간입니다.destruction_pending: true는 Tahoe 자체가 법정 보존 규정에 따라 아직 레코드를 보관해야 한다는 뜻입니다. 일부 고용 기록은 최대 4년까지 보관해야 합니다. 그래도 내 기한은 바뀌지 않습니다.workspace_id: null은 통지가 특정 워크스페이스에 속하지 않는다는 뜻입니다. 그 사람의 데이터를 가진 모두에게 적용되므로 모든 키로 전달됩니다. 삭제 통지를 워크스페이스로 거르지 마세요.- 처리 중단 통지 없이 올 수도 있습니다. Tahoe가 레코드를 바로 파기할 수 있으면
erasure_completed만 받습니다. 어느 쪽이든 먼저 도착한 통지에 따라 삭제하세요.
def honor_erasure(store, notice):
"""Delete our copy and record that we did, within the 7-day window."""
for resource in notice["resources"]:
store.purge(resource["object"], resource["id"])
# A tombstone that keeps the person OUT: a later sync must not bring
# them back the next time they appear in a list. Store the handle
# and nothing else about them.
store.suppress_forever(resource["object"], resource["id"])
store.audit(
"erased",
notice_id=notice["id"],
reason=notice["reason"],
deadline_at=notice["deadline_at"],
)
def on_data_subject_event(store, event):
# data_subject.suppression_applied and data_subject.erasure_completed
# carry the same notice as GET /erasures, in data.object.
honor_erasure(store, event["data"]["object"])삭제 기록(툼스톤)을 남기고, 절대 만료시키지 마세요
올바른 순서로 따라잡기
리더가 멈춰 있었다면 삭제 통지 피드부터 읽으세요. 크기가 작고, 이벤트 워터마크와 별개로 자체 페이지를 넘기며, 뒤처졌을 때 가장 문제가 되는 피드입니다.
def catch_up(session, store):
# Erasures first. Reading lists and the feed may write rows, so the list
# of suppressed handles must be current BEFORE anything is written, or
# you bring back someone who asked to be removed.
consume_erasures(session, store)
drain(store)체크리스트
- 변경 피드를 읽거나 웹훅을 받으세요. 삭제는 다른 경로로는 오지 않습니다.
- 삭제 이벤트 여섯 가지를 모두 처리하세요.
*.deleted유형 다섯 가지와list_membership.removed입니다. - 보내기 전마다
unsubscribed를 확인하세요. - 삭제 통지 피드를 하루에 한 번 이상 읽으세요.
suppression_applied를 받으면erasure_completed를 기다리지 말고 삭제하세요. 레코드가 아직 남아 있다면erasure_completed를 받았을 때도 삭제하세요.- 삭제 통지를 워크스페이스로 거르지 마세요.
- 삭제한 핸들 목록을 영구히 보관하고, 절대 만료시키지 마세요.
- 무엇을, 언제, 어떤 통지에 따라 삭제했는지 기록하세요.