feat: audit log for data protection requests (erasure, export, restriction)#589
Open
Joe-Heffer-Shef wants to merge 5 commits into
Open
Conversation
Adds an append-only DataProtectionEvent model (UK GDPR Article 5(2) accountability) with event types for erasure, export, restriction, unrestriction, and consent withdrawal. Includes a staff-only console view at /console/data-protection/ with filtering and pagination. Removing an organisation member now automatically records a RESTRICTION event. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 tasks
…rasure-export-restriction
…rasure-export-restriction
- Fix nav active-state check ('/admin-portal/data-protection' → '/console/data-protection')
- Block QuerySet.delete() via pre_delete signal to close bulk-delete bypass on append-only model
- Replace PermissionDenied with ValueError for immutability violations (save/delete on existing records)
- Pass filter_qs context variable to simplify pagination URL construction in template
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6 tasks
Collaborator
Author
|
can we use https://pypi.org/project/django-GDPR/ instead? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #586
Summary
DataProtectionEventmodel that stores a permanent record of data protection actions (erasure, subject access export, account restriction/unrestriction, consent withdrawal). Entries survive deletion of the subject user, so identity is stored as a stable string rather than a FK. The model prevents mutations and deletes at the ORM level to enforce GDPR Article 5(2) accountability.DataProtectionService(data_protection_servicesingleton) withrecord_event(write-only, no permission gate — callers are already authorised) andlist_events(staff-only, supports filtering by event type, subject user, and date range)./console/data-protection/with event-type and subject-user-ID filtering, 25-per-page pagination, and a nav link in the admin sidebar.RESTRICTIONevent (member removed from organisation).0013_dataprotectioneventwith composite indexes on(event_type, actioned_at)andsubject_user_id.Screenshots
Data protection log with dummy data
Test plan
DataProtectionEventappend-only enforcement (save on existing instance raises, delete raises)record_eventpersists all expected fields; falls back todeleted-user-<pk>when user has no emaillist_eventsdenies non-staff; filters correctly by event typeRESTRICTIONevent attributed to the acting staff user🤖 Generated with Claude Code