Skip to content

Personal-data export / erasure / retention policy (GDPR + PH DPA) #272

Description

@mforce

Deployment-readiness gap (#244), RECOMMENDED (market-dependent) — flagged by 2 of 3 reviewers.

Problem

The app stores third-party personal data but has no data-subject rights or retention story:

Relevant to EU/UK GDPR and the Philippines Data Privacy Act (the es/tl locales target PH/LatAm users).

Fix

Identify applicable jurisdiction/contract requirements; classify PII fields; set retention rules; define subject export and erasure vs legally-required pseudonymization (with a documented, audited exception for the append-only trail); propagate deletes into backups and telemetry. Test one full request end-to-end.

Verify

Run one DSAR export + one erasure on a staging subject; confirm the data is returned/removed everywhere except the justified audit exception.

Part of the #244 deployment-readiness audit; tracked in epic #15.

Activity

  1. changed the title [-]Deploy: personal-data export / erasure / retention policy (GDPR + PH DPA)[/-] [+]Personal-data export / erasure / retention policy (GDPR + PH DPA)[/+] on Jul 30, 2026
  2. mforce commented on Aug 16, 2026

    @mforce
    OwnerAuthor

    Cross-link: epic #530 (Phase 1.6 — Multi-farm tenancy).

    Not a slice of that epic and not blocked by it, but the two intersect in a way worth recording before either is designed further.

    #530 chooses one shared database with row-level AccountId isolation over database-per-tenant. One thing that explicitly buys, and it lands on this issue: per-tenant erasure and per-tenant export become queries, not pg_dump and DROP DATABASE. Whatever DSAR export and erasure paths this issue defines will have to be correct under the global query filter, and correct for the ~20 IgnoreQueryFilters() call sites that deliberately step outside it (#536 enumerates and justifies all of them, which is directly useful groundwork here).

    Also newly relevant once farms are separate customers rather than one farm:

  3. mforce commented on Sep 12, 2026

    @mforce
    OwnerAuthor

    New PII category from #788: connected applications and their tokens.

    #788 adds an OAuth 2.1 authorization server so MCP clients (AI assistants) can connect. That introduces personal data this issue's field classification does not yet cover, and it lands in all three of the areas named above — export, erasure, and retention.

    New data, all user-linked:

    • Authorizations — which apps a user has connected, when they approved, and what they granted. This is behavioural data about the person: it reveals which AI assistants they use and when they started.
    • Tokens — reference tokens tied to a user, with issue and expiry timestamps, and last-used if tracking lands.
    • Applications — self-registered client records. Not user PII in itself, but a dynamically-registered client can carry a user-supplied display name and redirect URIs that may identify an individual.
    • Audit provenance — Build an OAuth 2.1 authorization server (OpenIddict) so MCP clients can authenticate #788 adds first-class columns to AuditEvents recording which app acted alongside the human actor. That inherits this issue's existing ActorEmail problem: AuditEvent deliberately snapshots immutably with no mutation surface, so the same erasure-versus-pseudonymisation tension now applies to the app dimension too.

    Consequences for each of this issue's three deliverables:

    • DSAR export must include a user's connected applications and approval history. A subject access request that omits "which AI assistants have access to my account" is incomplete in an obvious way.
    • Erasure must revoke authorizations and delete tokens — not merely orphan them. An erased user whose OAuth authorization row survives is a live credential with no owner, which is worse than a data-protection gap: it is a security defect.
    • Retention needs a rule for revoked authorizations and expired tokens. Build an OAuth 2.1 authorization server (OpenIddict) so MCP clients can authenticate #788 decided connections last indefinitely until revoked, so nothing expires them on its own; a retention policy is the only thing that would.

    Sequencing: this does not block either issue. #788 ships first and should keep its data model simple; whoever implements this should treat the OAuth tables as in-scope from the start rather than retrofitting them. Worth noting that erasure touching OAuth tables is easier to build before there is production data in them.

  4. mforce commented on Sep 13, 2026

    @mforce
    OwnerAuthor

    Closing — out of scope for now, recorded as an accepted risk

    Closed by the owner on 2026-09-13 during the issue cleanup. Not done, not disproved — deliberately
    not being worked
    , and written down here so the position is a decision rather than a gap nobody
    looked at.

    What the app does today, unchanged by this close

    • Stores third-party personal data. Customer name, phone, email, address and free-text notes
      (Customer.cs); user email and display name.
    • Has no per-subject export. Only the admin farm-wide CSV export (F24: CSV export / manual backup — per-dataset CSVs, full account export (zip), self-host dump instructions #95), whose dataset list omits
      user records entirely (ExportQueries.cs).
    • Has no erasure or anonymisation path. None. A deletion request cannot be honoured by any
      supported operation.
    • Has no retention policy for any personal data.
    • Snapshots ActorEmail immutably in AuditEvent with no mutation surface, by design.

    What is being accepted

    If a data subject exercises a right of access or erasure under EU/UK GDPR or the Philippines
    Data Privacy Act
    , Cluckwork cannot service it without a hand-written SQL migration authored for
    that request. The PH exposure is the concrete one — the es/tl locales target PH users and the
    product holds Philippine customer records now.

    The two widening factors recorded in the comments above stand and get worse with time, not better:

    What should reopen this

    The cheap half, if this is ever revisited

    The build (DSAR export endpoint, erasure path, backup propagation) is large. The policy half is
    not: classify the PII fields, state retention rules, and decide erasure versus legally-required
    pseudonymisation for the append-only audit trail. That is a documentation deliverable, it is most
    of what a regulator asks to see first, and it makes the build schedulable. It was offered as a split
    during this cleanup and declined along with the rest — noted here so the option is on the record.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions