---
path: /legal/dpa
surface: customer
domain: onboarding-public
auth: anon
source: apps/oshun/web/src/app/legal/dpa/page.tsx
status: walked
last_walked:
  '2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data
  (2xx), console/page-errors, expected content, screenshot verified; manual
  screen-reader and real telemetry-delivery checks pending. Evidence:
  WALKTHROUGH/results/runtime-sweep-2026-05-29.md; 2026-06-28 public-legal-pages
  Playwright pass covered anonymous routing, exact section inventory, legal nav
  matrix/active states, TOC/back-to-top/print shell controls, 390 px
  no-overflow, 44 px touch targets, offline-after-load stability, no telemetry
  hooks, and axe; 2026-06-30 public-legal-pages Playwright pass added DPA
  mailto/profile/EDPB link semantics. Manual AT pass and real telemetry delivery
  remain pending.'
---

# Legal · Data Processing Agreement

## Purpose

GDPR/UK-GDPR Data Processing Agreement for users in the EU/EEA/UK. Eleven
numbered sections covering controller/processor definitions, data-subject
rights, legal bases, security, sub-processors, transfers, breach notification,
DPO, and supervisory authority. Rendered through `LegalPageShell`.

## Entry points

- Footer link "DPA" on `/welcome` and `/landing`
- Sidebar nav from other `/legal/*` pages
- Cross-reference from `/legal/privacy` international-transfers section
- Direct URL / bookmark — yes (anon)

## Layout regions

`page.tsx` defines `SECTIONS`: `introduction`, `definitions`, `scope-purpose`,
`subject-rights`, `legal-basis`, `security`, `sub-processors`,
`international-transfers`, `breach-notification`, `dpo`,
`supervisory-authority`.

- **Header (shell)**: minimal brand + back link
- **Sticky sidebar**: cross-legal nav + 11-entry TOC
- **Main article**: h1 "Data Processing Agreement", `data-legal-date` "Last
  updated: February 21, 2026", eleven numbered sections including:
  - Definitions (Controller/Processor/Personal Data/Sub-processor)
  - Six data-subject rights (access, rectification, erasure, restriction,
    portability, object) keyed to GDPR articles
  - Four legal bases (Art 6(1)(b), 6(1)(a), 6(1)(f), 6(1)(c))
  - Security measures (TLS 1.3, AES-256, 72-hour breach SLA)
  - Sub-processor objection window (30 days)
  - International transfers (SCCs, Schrems II TIAs)
  - DPO contact: `dpo@oshun.app`
  - Supervisory-authority reference
- **Floating control**: back-to-top button

## States

- [x] **Loading** — N/A; static
- [x] **Default** — all eleven sections render
- [x] **TOC click / active section** — clicking a TOC button scrolls to that
      section and marks it `data-active="true"`; passive scroll-spy remains
      `IntersectionObserver`-driven
- [x] **Back-to-top visible** — the shared 44 px control appears after scrolling
      and returns the user near the document start
- [x] **Narrow viewport (≤ 768px)** — sidebar collapses and avoids horizontal
      overflow at 390 px
- [x] **Print** — shell strips chrome
- [x] **Offline after load** — once loaded, the URL, heading, section inventory,
      and active legal nav state remain stable when the browser context goes
      offline
- [x] **Gated** — N/A; anonymous-readable

## Interactions

### Cross-legal sidebar nav

- [x] **Each `LEGAL_NAV` link** — sibling legal page navigation, active state,
      and at least 44 px mobile target

### On-this-page TOC

- [x] **Each TOC button** (11) — `scrollIntoView` to that section and immediate
      active state after click

### Back-to-top

- [x] **"↑"** — smooth-scroll to top when visible

### Body content

- [x] **DPA request email** — `privacy@oshun.app` in Data Subject Rights links
      to `mailto:privacy@oshun.app?subject=OSHUN%20DPA%20Request`
- [x] **Profile data-management path** — "profile settings" links to `/profile`
      so the referenced in-product account path is explicit
- [x] **Sub-processor objection email** — the objection mechanism links to
      `mailto:privacy@oshun.app?subject=Sub-processor%20Objection`
- [x] **DPO email** — `dpo@oshun.app` links to `mailto:dpo@oshun.app`
- [x] **Supervisory-authority reference** — the European Data Protection Board
      website text links to
      `https://www.edpb.europa.eu/about-edpb/about-edpb/members_en` with
      `target="_blank"` and `rel="noopener noreferrer"`

## Data & contracts

- **Reads**: none — static text
- **Writes**: none
- **Caching**: SSR static; loaded-route offline stability is asserted. Cold
  offline navigation / per-legal SW path caching is not asserted, and current
  `sw.js` does not path-cache `/legal/*`.
- **Auth**: anon (in middleware `PUBLIC_PREFIXES`)
- **Metadata**: `title: 'Data Processing Agreement'`,
  `description: 'Data Processing Agreement for OSHUN EU/EEA users under GDPR.'`

## Cross-references

- Sibling legal pages: [`legal-privacy.md`](./legal-privacy.md),
  [`legal-terms.md`](./legal-terms.md),
  [`legal-cookies.md`](./legal-cookies.md),
  [`legal-accessibility.md`](./legal-accessibility.md),
  [`legal-ccpa.md`](./legal-ccpa.md)
- Component sources:
  - `apps/oshun/web/src/components/legal/LegalPageShell.tsx`

## E2E coverage

- Backed by
  [`apps/oshun/web/e2e/public-legal-pages.spec.ts`](../../../apps/oshun/web/e2e/public-legal-pages.spec.ts)
  — covers anonymous access, exact eleven-section inventory, legal nav
  inventory/active state, shared TOC/back-to-top/print shell behavior, 390 px
  no-overflow, 44 px touch targets, offline-after-load stability, no telemetry
  hooks, axe, DPA request/support mailto targets, profile settings link, and the
  external EDPB supervisory-authority target plus new-tab safety attributes.

## Open questions / known gaps

- [ ] Cold offline navigation / per-legal SW cache is not asserted and current
      `sw.js` does not path-cache `/legal/*`; PWA shell cache coverage remains
      in the offline-first / PWA walkthroughs.
- [ ] No sub-processor list page exists on `/legal/*` — DPA promises "an
      up-to-date list of sub-processors" but no route serves it; confirm whether
      such a page should exist
