Noru

Deriving Your Article 30 RoPA From the Codebase

How to generate a GDPR Article 30 record of processing from source code instead of maintaining it by hand: what to annotate, which fields derive cleanly, which require human judgement, and how the register stays current as the system changes.

By Noru3 min readPublished

You derive an Article 30 record from your codebase by annotating personal data where it is defined — in models, schemas and migrations — against a shared privacy taxonomy, then materialising those annotations into register entries. Roughly two thirds of what Article 30 asks for is observable from code and infrastructure: the categories of personal data, the systems holding them, the recipients and subprocessors, the transfer destinations and the security measures. The remaining third — purposes, lawful basis, retention rationale — is judgement, and should be reviewed and attributed to a person rather than inferred. The result is a register that changes when the system changes, which is the property manual maintenance cannot provide.

Why the manual register structurally fails

A record of processing describes what your systems do with personal data. Your systems change every time you deploy. A register maintained by hand is therefore accurate on the day someone updates it and progressively wrong afterwards, and the rate of decay is set by your release cadence rather than by anyone's diligence.

That is not a discipline problem to be solved with reminders. It is a structural mismatch between an artefact updated a few times a year and a system that changes daily. The fix is to derive the artefact from the system.

What Article 30 asks for, and where each field comes from

Article 30 sets out what a controller's record must contain. Sorting those requirements by where the answer actually lives is the whole design exercise.

Derivable from code and infrastructure

  • Categories of personal data — from annotated fields in models, schemas and migrations.
  • Categories of data subjects — from the entity the annotated fields hang off: customer, employee, end user of a customer.
  • Categories of recipients — from the vendors and services the code sends data to, plus declared subprocessors.
  • Third-country transfers — from hosting regions, service endpoints and CDN configuration.
  • General description of security measures — from the controls already evidenced for your security framework.

Human judgement, recorded not inferred

  • Purposes of processing — why this data is processed, which is intent and cannot be read off a schema.
  • Lawful basis, and the legitimate interests balancing test where that is the basis relied on.
  • Retention periods and the rationale behind them.
  • Controller versus processor role for each activity, which follows from contracts rather than code.

Annotating personal data where it lives

The practical mechanism is a manifest that sits next to the code it describes, declaring which fields carry personal data and how they classify. Keeping it in the repository rather than a separate system means it goes through code review, it moves when the field moves, and a field added without an annotation is visible as an omission.

The classification itself should use an open vocabulary rather than a vendor's proprietary schema. Describing a column as a contact email in a standard taxonomy means the same annotation can answer GDPR, CCPA and other regimes, and survives a change of tooling. Fideslang is one such taxonomy, maintained by the non-profit standards consortium IAB Tech Lab, with published data categories, data subjects and data uses — see the fideslang specification.

Materialising the register

Once annotations exist, a pipeline step pushes them on merge, and the register is materialised from the accumulated manifests. Two properties matter here. First, materialise on a schedule rather than generating on demand, so you keep a versioned history of what the register said in March. Second, treat the human-judgement fields as sticky: a re-derivation should carry forward the reviewed lawful basis rather than blanking it, and flag when the underlying facts changed enough that the judgement should be revisited.

What good drift handling looks like

The value of derivation is not the first register — it is the second one. When an engineer adds a phone number column, the register should gain an entry with no purpose and no lawful basis, and that gap should appear as work assigned to whoever owns that processing activity. When a service starts calling a new vendor, the recipients list should change and a transfer assessment should be raised if the vendor is outside the EEA.

Compare that with the manual alternative, where the same two changes are invisible until someone happens to notice during an annual review, or until a regulator asks a question nobody can answer.

What this does not solve

Derivation gives you completeness and currency on the factual layer. It does not tell you whether your lawful basis is sound, whether your retention period is defensible, or whether the processing is proportionate. Those remain judgements a supervisory authority will attribute to a person, and the register should record who made them and when — which is what accountability under Article 5(2) actually requires.

If you want to see a register derived from your own repositories, you can explore it at noru.tech.

Primary sources

FAQ

Privacy & GDPR questions answered

Talk to us

Can an Article 30 record really be generated from code?

The factual layer can: categories of personal data, systems, recipients, transfer destinations and security measures are all observable. Purposes, lawful basis and retention are judgements that should be reviewed by a named person and recorded, not inferred.

What exactly gets annotated?

The fields that carry personal data, where they are defined — models, schemas, migrations — classified against a taxonomy. The annotation lives in the repository so it moves with the code and goes through review.

Does this mean sending our source code to a vendor?

It means analysing code to identify where personal data is handled. What the register needs is the resulting metadata — fields, classifications, vendors, transfers — not the source itself. Ask any vendor precisely what leaves your environment and what is retained.

What happens to the lawful basis when the register is re-derived?

It should be carried forward, not blanked. A good implementation treats reviewed judgements as sticky and flags when the underlying facts have changed enough that the judgement needs revisiting.

Does this work if we have several legal entities?

It should. Article 30 obligations attach per controller, so the same underlying annotations need to produce a separate register per entity. Check that whatever you use models entities rather than assuming one organisation.

What about data that never appears in our code, like a spreadsheet in HR?

Derivation covers systems you build. Data held in third-party SaaS still needs to enter the register, usually through integrations with those systems or through a reviewed manual entry. The point of derivation is to shrink the manual surface, not to pretend it is zero.