Files
agentic-dev/docs/compliance/templates/dsr-procedure.template.md

16 KiB
Raw Permalink Blame History

status, playbook-section, title, gdpr-articles, last-reviewed
status playbook-section title gdpr-articles last-reviewed
template 10 Data Subject Rights (DSR) Fulfilment Procedure
Art. 15
Art. 16
Art. 17
Art. 18
Art. 20
[FILL IN: YYYY-MM-DD]

Data Subject Rights (DSR) Fulfilment Procedure

Template status — fill every [FILL IN: …] marker before use. Cross-references below point to shipped interfaces, endpoints, and ADRs; do not change them.


1. Purpose & Scope

This procedure governs how [FILL IN: organisation name] receives, validates, fulfils, and records requests from data subjects exercising rights under GDPR Articles 1520.

Covered rights:

GDPR Article Right Shipped interface
Art. 15 + 20 Access + Portability IDataExport (dsr.export)
Art. 16 Rectification IDataRectify (dsr.rectify)
Art. 17 Erasure ("right to be forgotten") IDataDelete (dsr.delete)
Art. 18 Restriction of processing IProcessingRestriction (dsr.restrict)

See docs/guides/dsr.md for the engineering cookbook and docs/decisions/adr-025-eu-compliance-baseline.md § Epic B for the design rationale.


2. Roles & Contacts

Role Name Contact
Data Protection Officer [FILL IN: name / DPO provider] [FILL IN: contact]
DSR Coordinator [FILL IN: name] [FILL IN: contact]
Engineering contact (fulfilment) [FILL IN: name] [FILL IN: contact]

Intake channel: [FILL IN: e.g. privacy@example.com / online form URL]


3. Statutory Deadlines

Stage Deadline Extension
Acknowledge receipt [FILL IN: e.g. 5 business days]
Fulfil or refuse 1 calendar month from receipt (GDPR Art. 12(3)) Up to 2 further months for complex/numerous requests; notify subject within the first month
Notify subject of refusal 1 month

Deadline clock starts when the organisation receives the request — not when identity is verified.


4. Phase 1 — Receipt & Intake

4.1 Intake channels

Accept DSR requests via:

  • [FILL IN: primary channel, e.g. privacy form at https://example.com/privacy/request]
  • [FILL IN: secondary channel, e.g. email to privacy@example.com]
  • Any written format (GDPR does not mandate a specific form)

4.2 Logging the request

Log each incoming request immediately in [FILL IN: DSR register / issue tracker] with:

Field Value
Reference ID DSR-YYYY-NNN (sequential)
Right requested Art. 15 / 16 / 17 / 18 / 20
Channel email / form / letter
Received at ISO 8601 timestamp
Deadline received + 1 month
Status pending-verification

4.3 Acknowledgement

Send acknowledgement to the requester within [FILL IN: e.g. 5 business days] confirming:

  • Receipt of the request
  • Reference ID
  • Identity verification requirement (§ 5)
  • Statutory deadline

Template: [FILL IN: path to acknowledgement email template]


5. Phase 2 — Identity Validation

5.1 Verification requirement

GDPR Art. 12(6) permits identity verification when there is reasonable doubt. Always verify for Art. 17 (erasure) and Art. 18 (restriction). For Art. 15 (access) of clearly authenticated users, verification may be satisfied by existing session.

5.2 Verification methods

Method Acceptable for
Authenticated session in the app Art. 15, Art. 16 (low-risk fields)
Email confirmation to registered address All rights
[FILL IN: government ID / identity provider] Art. 17 cascade-hard, Art. 18

5.3 Rejected or suspicious requests

If identity cannot be verified after [FILL IN: e.g. 14 days]:

  1. Close the request with status identity-unverified.
  2. Notify the requester in writing of the outcome.
  3. Log closure in the DSR register.

6. Phase 3 — Fulfilment

6.1 Identify the subject record

Map the verified identity to the system subjectId (Payload users.id or equivalent auth collection primary key). Cross-reference compliance/data-map.yml (generated by pnpm compliance:data-map) to enumerate which collections hold personal data for this subject.

# Regenerate data map to ensure it reflects current schema
pnpm compliance:data-map

Review compliance/data-map.yml fields tagged exportable: true (Art. 15/20) and restrictable: true (Art. 18).

6.2 Art. 15 + 20 — Access and Portability

Interface: IDataExport.exportSubjectData(subjectId, format) tRPC procedure: dsr.export (query — no mutation) GDPR deadline: respond within 1 month; provide data without charge for first copy.

Invoke via the admin tRPC client or the REST endpoint wired in apps/web-next:

GET /api/gdpr/export?subjectId=<id>&format=json
GET /api/gdpr/export?subjectId=<id>&format=json-ld   # machine-readable JSON-LD

The response is a UserDataBundle:

  • data — keyed by Payload collection slug; each bucket contains asSelf (rows the subject owns) and asReference (rows merely referencing the subject)
  • auditLog — the subject's audit trail (optional; include for transparency)
  • exportedAt — ISO 8601 export timestamp for the certificate of fulfilment

Audit entry emitted: EXPORT action, resource.type: "data-subject", resource.id: subjectId.

Deliver the export to the subject via [FILL IN: secure delivery method, e.g. encrypted download link / secure email].

6.3 Art. 16 — Rectification

Interface: IDataRectify.updateSubjectField(subjectId, collection, field, value) tRPC procedure: dsr.rectify (mutation) Scope: only fields tagged custom.pii in the Payload collection config (i.e. fields indexed in compliance/data-map.yml).

POST /api/gdpr/rectify
Body: { subjectId, collection, field, value }

Steps:

  1. Confirm the field is custom.pii-tagged in compliance/data-map.yml.
  2. Confirm the new value passes Payload field validation.
  3. Invoke the procedure; the implementation emits a RESTRICT audit entry with reason: "art-16-request".
  4. Notify the subject that rectification is complete and, if data was shared with third parties, notify them per Art. 19.

Third-party notification log: [FILL IN: log location]

6.4 Art. 17 — Erasure

Interface: IDataDelete.deleteSubjectData(subjectId, mode) tRPC procedure: dsr.delete (mutation — requires authenticated admin session for cascade-hard) Returned: DeletionCertificate — retain this as evidence of fulfilment.

Mode selection:

Mode Effect Who can invoke
"soft" Redacts PII fields in owned rows; NULLs reference fields; row structure preserved Standard authenticated user or DSR coordinator
"cascade-hard" Hard-deletes owned rows where postDeletion.action === "hard-delete" per retention policy; NULLs reference fields Admin role required
POST /api/gdpr/delete
Body: { subjectId, mode: "soft" | "cascade-hard" }

Exemptions (GDPR Art. 17(3)) — erasure must be refused if data is required for:

  • Legal obligation compliance (document refusal in the DSR register)
  • Establishment, exercise, or defence of legal claims

Audit trail pseudonymization: after deletion, invoke IAuditLog.eraseSubject(actorId, "pseudonymize") via the admin tRPC to replace the subject identifier in the audit log with erased-{hash[0:16]} (sha256-salted pseudonym per ADR-018). This preserves the event record for regulatory purposes while removing the identifier.

Retention-policy overrides: check compliance/retention-policy.yml for postDeletion rules — some collections may have a grace period (postDeletion.duration: P30D) before hard deletion executes.

# View current retention policy
cat compliance/retention-policy.yml

# Regenerate from Payload field tags
pnpm compliance:retention-policy

DeletionCertificate fields to retain:

  • subjectId (or pseudonymized form)
  • mode, timestamp, reason: "art-17-request"
  • affected[] — collections and rows modified
  • auditEntryId — links to the audit log

6.5 Art. 18 — Restriction of Processing

Interface: IProcessingRestriction.setRestriction(subjectId, granted: true) tRPC procedure: dsr.restrict (mutation)

POST /api/gdpr/restrict
Body: { subjectId, granted: true }

The implementation sets processingRestrictedAt on the user record. Downstream use cases check isRestricted(subjectId) before processing personal data. The audit channel records a RESTRICT audit entry on every state change.

Grounds for restriction (Art. 18(1)):

  • Accuracy of data is contested (pending Art. 16 rectification)
  • Processing is unlawful but erasure is opposed by the subject
  • Organisation no longer needs the data but subject requires it for legal claims
  • Subject has objected (pending verification of legitimate grounds)

Notify the subject when restriction is lifted: invoke dsr.restrict with granted: false and send written notice per Art. 18(3).

Audit entry emitted: RESTRICT (on restriction) / UNRESTRICT (on lift).


7. Phase 4 — Recording & Closure

7.1 DSR register update

Update the DSR register entry (§ 4.2) with:

Field Value
Fulfilled at ISO 8601 timestamp
Outcome fulfilled / refused / partially-fulfilled
Evidence DeletionCertificate ID or export reference
Audit entry ID From AuditEntry.correlationId or auditEntryId
Status closed

7.2 Subject notification

Notify the data subject of the outcome within the Art. 12(3) deadline:

  • Fulfilment: summary of actions taken, delivery method for exports.
  • Refusal: grounds for refusal (Art. 12(4)), right to lodge complaint with SA, right to seek judicial remedy.

Template: [FILL IN: path to outcome notification template]

7.3 Third-party notification log (Art. 19)

If the corrected, erased, or restricted data was previously shared with third parties (sub-processors listed in compliance/sub-processors.yml), notify each processor of the subject's request. Record each notification in [FILL IN: third-party notification log].


Consent grant and withdrawal are distinct from Art. 17 erasure but often accompany DSR requests. The consent channel (docs/guides/consent.md) records:

Audit action Trigger
CONSENT_GRANT Subject grants consent for a category (e.g. marketing)
CONSENT_WITHDRAW Subject withdraws consent
RESTRICT Art. 18 restriction set
UNRESTRICT Art. 18 restriction lifted

If a DSR request also includes consent withdrawal, invoke IConsent.withdraw(subjectId, categories) in addition to the relevant DSR procedure. Consent withdrawal does not automatically trigger erasure — only an explicit Art. 17 request does.


9. Appendix — Command Reference

# Regenerate PII data map (enumerate affected collections and fields)
pnpm compliance:data-map

# Regenerate retention policy (check postDeletion rules before Art. 17)
pnpm compliance:retention-policy

# Regenerate sub-processor list (for Art. 19 third-party notification)
pnpm compliance:sub-processors

# Regenerate all compliance artifacts in one pass
pnpm compliance:emit-all

# Run fallow audit before closing a DSR-related PR
pnpm fallow:audit

10. Document Control

Field Value
Owner [FILL IN: DPO or DSR Coordinator]
Review cycle [FILL IN: e.g. annual or on schema change]
Next review date [FILL IN: YYYY-MM-DD]
Cross-references docs/decisions/adr-025-eu-compliance-baseline.md, docs/decisions/adr-018-audit-and-compliance.md, docs/guides/dsr.md, docs/guides/audit-and-compliance.md, docs/guides/consent.md, ../data-map.example.yml