Athena — valideerleeftijd/compliance/dpia.md

DPIA — Data Protection Impact Assessment

Project: valideerleeftijd Version: 1.0 Date: 2026-03-27 Status: Draft Owner: GloryLabs


1. Project Description

What does this system do? valideerleeftijd is a PSD2-powered age verification API that allows client companies to verify whether an end user meets a minimum age requirement. The user is redirected to their bank via OAuth2 PKCE (using a PSD2 AISP provider such as Tink/Klarna Open Banking), where the bank returns the user's birth date. The API calculates the user's age, returns a boolean result (meets minimum age: yes/no) to the client, and immediately discards the birth date. No birth date or other PII beyond the active session is ever stored.

Why is a DPIA required?

  • [x] New technologies or innovative use of existing technologies — use of PSD2 / Open Banking for identity verification is an innovative application of financial data infrastructure
  • [x] Automated decision-making / profiling — the system makes an automated eligibility determination based on calculated age
  • [x] Processing of data of vulnerable persons — potential processing for age-gating of alcohol, gambling, or adult content platforms means minors may be the subject of the verification

2. Data Inventory

Personal data processed

| Category | Data fields | Purpose | Legal basis (Art. 6) | Retention | |----------|------------|---------|----------------------|-----------| | Session data | Session ID (UUID), minimum age requirement, client redirect URI | Track active verification flow, route callback | Art. 6(b) — contract with client; Art. 6(a) — user consent | 15 minutes (Redis TTL), then auto-deleted | | Verification result | Boolean (age requirement met: true/false) | Return result to client | Art. 6(a) — user consent; Art. 6(b) — contract with client | Returned in API response only; not stored | | Bank birth date (transient) | Date of birth as returned by bank AISP API | Age calculation (in-memory only, never written to disk or DB) | Art. 6(a) — user consent | Zero — discarded immediately after calculation |

Special categories (Art. 9 GDPR)

| Category | Data fields | Explicit consent obtained? | |----------|------------|---------------------------| | None | Birth date is used transiently for calculation only and is not a special-category data point under Art. 9; no health, biometric, or other Art. 9 data is processed | N/A |

Data subjects

| Group | Estimated count | Vulnerable? | |-------|----------------|-------------| | End users (consumers verifying age) | Potentially thousands per day depending on client volume | Possibly — depends on client use case (e.g. alcohol, gambling, adult content); minors who fail verification are precisely the group protected | | Client company employees / developers | Small number — API key holders only | No |


3. Data Flows

Collection

Data originates from two sources: (1) the client application, which initiates a verification request supplying a minimum age threshold and redirect URI; (2) the user's bank, which returns a birth date via the PSD2 AISP API after the user authenticates via OAuth2 PKCE.

Processing

  1. Client sends verification request → API generates a UUID session ID, stores {session_id, minimum_age, redirect_uri} in Redis with a 15-minute TTL.
  2. User is redirected to the PSD2 bank OAuth2 PKCE authorisation flow.
  3. On callback, the bank access token is used to call the AISP API and retrieve the birth date.
  4. Birth date is used in-memory to calculate age; result (boolean) is produced.
  5. Birth date is immediately discarded (never written to any persistent store).
  6. Boolean result is returned to the client via the redirect URI. Session entry is deleted or expires after 15 minutes.

Storage

Only the Redis session store holds data, encrypted at rest and in transit, with a strict 15-minute TTL. No database records or logs containing PII are written. Session IDs are UUIDs and not linked to any individual identity beyond the active flow.

Transfer

Birth date is fetched from the PSD2 bank provider (Tink/Klarna Open Banking) under a processor relationship. The bank's AISP API response travels over TLS. No birth date is forwarded to the client — only the boolean result. Redis is used as an in-process cache and does not expose data externally.

Deletion

Redis session data is auto-expired after 15 minutes via TTL. The birth date is never persisted and is discarded in memory immediately after the age calculation. There is no manual deletion step required because no long-lived personal data is stored.


4. Necessity & Proportionality

Is the processing necessary for the stated purpose? Yes. Age verification requires access to a reliable, authoritative source of birth date. PSD2 AISP is the most reliable available mechanism short of identity document checks. The birth date is the minimum data point needed to calculate age; no other personal information from the bank is requested or used.

Could the purpose be achieved with less data or less intrusive means? The birth date is processed transiently and never stored, which already represents maximum data minimisation. An alternative would be for the bank to return only a boolean age comparison result, but this functionality is not universally available from PSD2 providers. The current design (calculate in-memory, discard immediately) achieves the same privacy outcome.

Is the retention period proportionate? Yes. The 15-minute Redis TTL covers only the duration of the OAuth2 redirect flow. Birth date is never retained at all. The boolean result is returned once and not stored.


5. Risk Assessment

| Risk | Likelihood (1-5) | Impact (1-5) | Score | Mitigation | |------|-----------------|--------------|-------|------------| | Unauthorised access to Redis session | 2 | 3 | 6 | Redis protected by auth, network-level access control, no birth date stored in Redis | | Data breach / leak of birth date | 1 | 5 | 5 | Birth date never persisted; in-memory only; TLS on all connections | | Data loss (session lost before result returned) | 2 | 2 | 4 | 15-minute TTL sufficient for flow; error handling returns meaningful failure to client | | Unlawful processing (no valid consent) | 2 | 4 | 8 | User explicitly initiates bank OAuth2 login; PSD2 AISP consent obtained at bank level; consent recorded in session | | Inaccurate data (wrong birth date from bank) | 1 | 3 | 3 | Bank is authoritative source; age calculation is deterministic; no correction possible but error rate is negligible | | Profiling / discrimination | 1 | 4 | 4 | Only a boolean is returned; no age, no birth date, no profile is built or retained | | API key compromise (client impersonation) | 2 | 3 | 6 | API keys hashed and stored securely; rate limiting 100 req/min; key rotation process in place |

Residual risk after mitigation: Low


6. Technical & Organisational Measures

  • [x] Encryption at rest — Redis encrypted at rest
  • [x] Encryption in transit (TLS 1.2+) — all API endpoints and bank AISP calls over TLS 1.3
  • [x] Access control (role-based) — API key authentication for client companies; internal admin access role-restricted
  • [x] Audit logging — request/response logs at API gateway level (no PII in logs); session IDs only
  • [x] Data minimisation applied — only session ID, minimum age, redirect URI stored; birth date never persisted
  • [x] Pseudonymisation / anonymisation where possible — boolean result is effectively anonymised; session IDs are random UUIDs
  • [x] Automated deletion after retention period — Redis TTL enforces 15-minute expiry automatically
  • [x] Processor agreements (DPA) in place with third parties — DPA with Tink/Klarna Open Banking required; Redis cloud provider DPA required
  • [ ] Breach notification procedure in place — to be formalised
  • [ ] Staff trained on data protection — to be scheduled

7. Third-Party Processors

| Processor | Country | Processing activity | DPA in place? | |-----------|---------|---------------------|--------------| | Tink / Klarna Open Banking | Sweden / EU | PSD2 AISP — retrieval of birth date from user's bank on behalf of the controller | To be confirmed | | Redis (cloud provider, e.g. Redis Cloud / AWS ElastiCache) | EU (preferred) / configurable | In-memory session storage | To be confirmed |


8. Data Subject Rights

| Right | How it is fulfilled | |-------|---------------------| | Access (Art. 15) | No personal data is stored beyond the 15-minute session. After session expiry there is no data to provide. During session, session ID is held; user can request information about active processing via privacy contact. | | Rectification (Art. 16) | Birth date is not stored; the source of truth is the bank. Users who believe their bank data is incorrect must contact their bank. | | Erasure (Art. 17) | Automatic — all data auto-deleted at session expiry (15 min) or earlier. No action required; no long-lived data exists. | | Restriction (Art. 18) | User can withdraw consent by not completing the bank OAuth2 flow; session expires automatically if not completed. | | Portability (Art. 20) | Not applicable — only a transient session token and a boolean result are processed; no substantive personal data profile is held. | | Object (Art. 21) | Processing is based on explicit user consent (Art. 6a); user may object by not initiating or not completing the bank login flow. |


9. DPO / Legal Consultation

DPO consulted: Not applicable — GloryLabs does not meet the threshold for mandatory DPO appointment; however legal review is recommended given the use of financial data via PSD2. Date: 2026-03-27 Outcome: Pending legal review of PSD2 AISP consent chain and adequacy of transient processing approach.

Prior consultation with AP required (Art. 36)? No — residual risk is Low after mitigations; prior AP consultation not required.


10. Approval

| Role | Name | Date | Signature | |------|------|------|-----------| | Author | GloryLabs | 2026-03-27 | | | Reviewer | | | | | Approver | | | |


11. Review History

| Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0 | 2026-03-27 | GloryLabs | Initial version |

Reacties

Nog geen reacties