One picture of where the data comes from, what happens to it, where it rests, and who can see it. Drawn at kickoff, agreed with the client, updated whenever the answer changes. If a box on this diagram is not in the access register and the Art. 30 register, one of the three is wrong.
Last updated: [DATE] · Agreed with: [NAME]
Diagram
flowchart LR
subgraph SRC["Sources — client-owned"]
S1["[System / file]<br/>owner: [team]<br/>personal data: yes/no"]
S2["[System / file]<br/>owner: [team]<br/>personal data: yes/no"]
end
subgraph PROC["Processing — runs in: [client tenant / my EU infra / browser]"]
P1["Extract<br/>read-only, scope: [scope]"]
P2["Minimize<br/>drop: [columns]<br/>pseudonymise: [columns]"]
P3["Aggregate<br/>grain: [e.g. week x team]"]
end
subgraph STORE["Storage — region: [eu-region]"]
T1["[Store]<br/>encrypted at rest<br/>retention: [period]"]
T2["Output<br/>[file / dashboard]<br/>versioned"]
end
subgraph VIEW["Who sees it"]
V1["[Role / team]<br/>sees: [slice]"]
V2["[Role / team]<br/>sees: [slice]"]
end
S1 -->|TLS| P1
S2 -->|TLS| P1
P1 --> P2 --> P3 --> T1 --> T2
T2 --> V1
T2 --> V2
classDef pii stroke-dasharray: 4 3
class S1,P1 pii
Dashed border = carries personal data. Solid = it has been dropped or pseudonymised by that point. The dashed boxes should stop early in the flow — if they run all the way to the right, the minimization step is not doing its job.
Filled example (tier 2, for reference)
flowchart LR
subgraph SRC["Sources — client-owned"]
S1["SharePoint: /Ops/Exports<br/>owner: Ops team<br/>personal data: yes (operator names)"]
end
subgraph PROC["Processing — runs in: client Azure tenant"]
P1["Nightly Function<br/>read-only, Graph<br/>Files.SelectedOperations.Selected<br/>on one folder"]
P2["Drop: operator name, email<br/>Hash: employee ID"]
P3["Aggregate to week x line x defect"]
end
subgraph STORE["Storage — region: West Europe"]
T1["Blob (client sub)<br/>encrypted at rest<br/>retention: 90 days"]
T2["dashboard.html<br/>versioned, last 7 kept"]
end
subgraph VIEW["Who sees it"]
V1["Quality managers<br/>sees: all lines"]
V2["Line leads<br/>sees: own line"]
end
S1 -->|TLS| P1
P1 --> P2 --> P3 --> T1 --> T2
T2 --> V1
T2 --> V2
classDef pii stroke-dasharray: 4 3
class S1,P1 pii
Filled example (tier 2 on Google, for reference)
Source Drive: /Ops/Exports (shared drive)
Processing runs in: client Google Cloud project
Cloud Run job, nightly, service account
scope: drive.readonly on the one folder
Storage — region europe-west1 (GCS bucket, client project)
Viewers Ops team, via the client's own Google sign-in
Personal data none after the minimisation step
Retention source extract deleted 90 days after ingest
Questions this diagram has to answer
| Question | Answer |
|---|---|
| Does any data leave the client's environment? | |
| If yes, to where, and under what agreement? | |
| Where does the code run? | |
| What is the widest access held by any component? | |
| What is deleted, and when? | |
| Who can see the output, and can they see each other's slice? | |
| What breaks if I disappear tomorrow? |