# GDPR Data Subject Request Endpoints

Owner: trust & safety team Last reviewed: 2026-07-20

Registry of per-domain endpoints that fulfil GDPR data-subject rights (Articles
15-21). This is the index trust & safety uses to respond to DSARs
(data-subject-access-requests) within the 30-day statutory window.

Pair this with [pii-inventory.md](pii-inventory.md) — that doc lists what data
each domain holds; this doc lists how to read it out or delete it.

## Article 15 — Right of access (export)

| Domain    | Endpoint                                           | Returns                                                                                 | Owner          |
| --------- | -------------------------------------------------- | --------------------------------------------------------------------------------------- | -------------- |
| yemaya    | `GET /api/account/export`                          | JSON bundle: user, sessions, audit logs, oauth links                                    | yemaya team    |
| iris      | `GET /api/account/export` (proxied through yemaya) | + consent records, continuity states, memory scopes                                     | iris team      |
| lilith    | `POST /v1/account/data-export` (async)             | Async job; returns download URL                                                         | lilith team    |
| aphrodite | `POST /api/v1/account/data-export` (async)         | Includes financial records (10 yr scope)                                                | aphrodite team |
| tara      | `GET /api/account/export`                          | + ritual session history                                                                | tara team      |
| veritas   | n/a (no end-user data)                             | —                                                                                       | —              |
| maat      | `GET /api/account/export`                          | Admin / board user data only                                                            | maat team      |
| oshun BFF | `POST /v1/data-rights/exports` (async)             | Scoped JSON bundle, including Metis continuity state; excludes internal review packages | oshun team     |

**Status:** as of 2026-07-20, the maat, yemaya, and Oshun BFF endpoints are
implemented and gated behind auth. The Oshun BFF serves completed bundle bytes
from its durable export authority. The lilith async export was designed but not
yet shipped (tracked separately). The aphrodite endpoint exists but the
financial-export portion needs PCI review before going live.

## Article 17 — Right to erasure (deletion)

| Domain    | Endpoint                                        | Behaviour                                                                                                                                                                                                                                                                       | Owner          |
| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| yemaya    | `DELETE /api/account`                           | Soft-deletes user; schedules hard-delete after 90 d                                                                                                                                                                                                                             | yemaya team    |
| iris      | `DELETE /api/account/memories`                  | Per-scope deletion; cascades into continuity_states                                                                                                                                                                                                                             | iris team      |
| lilith    | `POST /v1/account/deletion-request` (async)     | Async; broadcasts to all dependent services                                                                                                                                                                                                                                     | lilith team    |
| aphrodite | `POST /api/v1/account/deletion-request` (async) | Cannot delete PCI-scoped financial records until 10 yr retention; tombstones the user-identifying fields                                                                                                                                                                        | aphrodite team |
| tara      | `DELETE /api/account`                           | Cascades into ritual sessions, continuation states                                                                                                                                                                                                                              | tara team      |
| maat      | `DELETE /api/account` (admin self-deletion)     | Same shape as yemaya                                                                                                                                                                                                                                                            | maat team      |
| oshun BFF | `POST /v1/data-rights/deletions` (async)        | Scheduled signed fan-out; customer Themis appeals, DSA packages, and citation-drift decisions reconcile pending cross-store outcomes, then redact and fence the exact subject; Metis tutor state is erased; BYOM/operator-inbox/incident/citation reviewer identity is redacted | oshun team     |

The Oshun BFF executes signed deletion fan-out only when the event bus and
attestation signer are configured; otherwise the request remains scheduled and
does not receive a fabricated completion receipt.

Metis BYO-material operator decisions are canonical internal, non-exportable
`review_package` records rather than learner-visible content. Signed account
erasure pseudonymizes the exact reviewing operator reference, removes that
operator's free-text rationale, and retains the minimized governance record for
seven years subject to legal holds and retention exceptions before physical
purge. The current partition stores no authoritative source-to-learner ownership
mapping, so this is not a claim that learner erasure deletes a reviewed source.

General operator-inbox decisions are also canonical internal, non-exportable
`review_package` records. Signed account erasure pseudonymizes the exact
reviewer, removes that reviewer's rationale and authored assignment, and scrubs
exact assignee-value matches from adjacent records. The minimized governance
record remains subject to the same seven-year legal-hold/retention-exception-
aware lifecycle before physical purge. The assignee is currently a free-form
display label, not an authoritative operator-directory mapping, so this does not
claim broader assignee-account deletion.

The shared operator-incident lifecycle is an internal, non-exportable
`review_package`. Signed account erasure domain-pseudonymizes exact lifecycle
actors and acknowledgements, removes details authored by that operator, clears
an exact current assignee match, scrubs exact assignee references in adjacent
history, and persists a subject fence even when no incident matched. The
minimized package remains for seven years subject to legal holds and retention
exceptions; expiry replaces the retained pseudonym with a non-linkable purge
marker. The six-item incident catalog and assignee labels are currently
fixture-backed, so this is not an operator-directory identity or canonical
external incident-ingestion claim.

Citation-drift terminal resolutions and per-source classifications are also
internal, non-exportable `review_package` records. Before profile erasure, any
durable pending terminal decision is reconciled against the exact terminal
operator-incident authority. Erasure then pseudonymizes the exact reviewer,
removes reviewer-authored rationale and searchable-audit correlation, and
persists independent resurrection fences for both partitions. The minimized
records remain for seven years subject to legal holds and retention exceptions;
expiry irreversibly removes the retained pseudonym-linked rows while preserving
the fence. The two snapshots and the incident ledger are ordered but are not an
atomic cross-document transaction.

Customer Themis moderation appeals are exportable `support_case` records. The
customer read API exposes a decided verdict and rationale without internal
reviewer identities. Signed account erasure first replays any durable pending
outcome into the internal DSA aggregate, then pseudonymizes both stores and
removes appellant, statement, and verdict narrative. The Themis case remains
subject to five-year retention; the DSA `review_package` remains subject to
seven-year retention, in each case with legal-hold and retention-exception
evaluation before physical purge. This ordered reconciliation does not create an
atomic transaction across the two snapshot documents.

**Tombstone semantics** are documented in
[../releases/v1/specs/v1-tombstone-semantics.md](../releases/v1/specs/v1-tombstone-semantics.md).

## Article 16 — Right to rectification

User profile rectification flows through the normal account settings UI on each
domain. There's no special endpoint registry because the same write endpoints
that create the data accept updates.

If a user disputes data they cannot rectify themselves (e.g., a disputed
transaction or a chat-moderation decision), the trust & safety team handles it
via the internal admin UI; the audit log captures the change.

## Article 18 — Right to restriction of processing

| Domain             | Mechanism                                               |
| ------------------ | ------------------------------------------------------- |
| lilith / aphrodite | Per-consent-record withdrawal (immediate)               |
| iris               | Memory scope opt-out (per scope)                        |
| Sitewide marketing | Cookie banner → consent service → propagated everywhere |

## Article 20 — Right to data portability

The Article-15 export endpoints above produce machine-readable JSON suitable for
portability. Format documented in:

- `libs/contracts/src/common/customer-data-export.ts` — canonical export schema
  across domains.

## Article 22 — Automated decision-making safeguards

V1 services that use automated decision-making (moderation, recommendation):

| Domain    | Service        | Human-review path                                                                           |
| --------- | -------------- | ------------------------------------------------------------------------------------------- |
| lilith    | svc-moderation | Appeals route in svc-moderation/src/appeal-routes.ts                                        |
| iris      | recommendation | Manual feedback loop in iris/api conversation feedback                                      |
| oshun BFF | moderation     | Customer `/v1/themis/appeals`; independent triage/decision under `/v1/admin/themis/appeals` |

## Process

1. DSAR received via privacy@oshun.dev (or in-product flow).
2. Trust & safety creates a Linear ticket within 1 business day.
3. Identity verified against `users.email` + a second factor (MFA challenge or a
   manual signature for high-sensitivity requests).
4. Domain-by-domain export / deletion executed via the endpoints above; ticket
   logs each step.
5. Bundle delivered to the user via the same channel they used to request,
   encrypted at rest in S3 with a per-request key (and a 7-day download link).
6. Ticket closed with timestamps; preserved in the compliance archive for 7
   years.

The 30-day statutory clock pauses when waiting on user identity re-verification;
otherwise it runs continuously.
