DEV Community

Syden Infinity Systems
Syden Infinity Systems

Posted on

Django data protection engine: encrypted fields, GDPR-style soft delete and audit log

Django data protection engine: encrypted fields, GDPR-style soft delete and audit log

Why I built this
I was tired of spending 1–3 days wiring encryption + soft delete + audit logging every time a client mentioned “GDPR”.

This engine installs in ~5 minutes and gives you a reusable setup you can drop into future projects.

In one of my Django projects I needed a more “professional” way to handle personal data:

  • encrypt e-mail and other sensitive fields in the database;
  • support GDPR-style “right to be forgotten”;
  • keep a proper audit log of who did what and when;
  • give non-technical people a simple dashboard in Django admin.

Instead of reinventing everything from scratch, I ended up building a small reusable engine and decided to share it.

I call it Syden Compliance Engine.


What the engine does

The engine is a small layer you can plug into an existing Django project. It focuses on:

  • EncryptedCharField – a Django field that stores values encrypted in the DB and decrypts them transparently in Python.
  • GDPR-style soft delete + anonymisation – “right to be forgotten” for your data subjects.
  • Central audit log – records READ / UPDATE / DELETE actions on important models.
  • Security dashboard – a simple dashboard inside Django admin.
  • REST API – endpoints for listing and managing “data subjects”, built with Django REST Framework.

It’s not a full legal GDPR solution, just a technical building block for small SaaS / internal apps that need some structure around personal data.


Main components

1. EncryptedCharField

The engine provides a custom Django model field that encrypts string data before saving it to the database and decrypts it when you read it.

  • encryption is done using PyCryptodome (symmetric encryption);
  • the key is read from an environment variable, for example:

python
import os
from django.core.exceptions import ImproperlyConfigured

ENCRYPTION_KEY = os.environ.get("HIPAA_ENCRYPTION_KEY")
if not ENCRYPTION_KEY:
    raise ImproperlyConfigured("HIPAA_ENCRYPTION_KEY is not set.")
You can use this field for e-mail addresses, phone numbers, document IDs etc.

2. Soft delete + anonymisation

Instead of hard-deleting “data subject” records, the engine performs:

anonymisation of public identifiers,

wiping of encrypted fields,

marking the record as deleted (flags + timestamp),

writing a DELETE entry into the audit log.

This makes it easier to implement something close to “right to be forgotten” without breaking foreign keys everywhere.

3. Audit log

The audit log is a simple Django model that stores:

action type: READ / UPDATE / DELETE,

model name,

object ID,

timestamp,

optional user,

optional reason/comment.

Entries are append-only: you don’t edit or delete them from Django admin.
There is also a small dashboard in admin that shows distribution of actions and top users by activity.

Demo project

I put everything into a small demo project so you can see it in action:

Django admin with a “PatientProfile” model as a generic “data subject”;

REST API for listing and editing data subjects;

security dashboard with basic charts.

Public docs and the demo project are available here (GitHub):

👉 https://github.com/syden22/syden-compliance-engine-showcase

There are also two short demo videos linked in the README (overview and installation).

Commercial package

The full engine (ready-to-use Django project, app, migrations and commercial license) is available as a paid package on Gumroad:

👉 https://syxov.gumroad.com/l/rgzfqx

It’s mainly aimed at freelance Django developers and small teams who prefer to pay for a reusable building block instead of spending 1–3 days wiring all of this manually.

Feedback welcome

If you’ve ever had to implement:

encrypted fields in Django,

audit logging for sensitive models,

or GDPR-style soft delete / anonymisation,

I’d love to hear what you think of this approach and what you would do differently.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)