Legitimate Interests Assessment¶
Facilitator Referral Attribution — Cookie + Attribution Recording¶
| Field | Value |
|---|---|
| Document ID | LIA-2026-001 |
| Processing activity | Facilitator referral attribution via HMAC-signed cookie |
| Controller | Curaway Global Health Technologies |
| Date | 2026-05-05 |
| Author / acting DPO | Srikanth Donthi (CPO/CTO, acting DPO under Curaway MVP governance) |
| Companion DPIA | docs/compliance/dpia-facilitator-referral-attribution.md (DPIA-2026-001) |
| Related issue | #656 |
| Status | Draft — pending DPO sign-off |
1. Purpose Test¶
What is the legitimate interest?
Commission attribution to facilitators who refer patients to the Curaway platform.
Is this interest valid and genuine?
Facilitators are external licensed agents (translation, appointment coordination, pre-travel logistics) who bear patient acquisition costs and provide coordination services. Their contracts structure compensation as commission on converted referrals. Without accurate attribution of which facilitator introduced each patient:
- Facilitators cannot be compensated for services rendered — the commercial model collapses.
- Patients lose access to facilitator-mediated coordination support, which many explicitly sought when responding to facilitator outreach.
- Curaway cannot fulfil its contractual obligations to facilitator partners.
This is a recognized, established commercial purpose — commission tracking is structurally identical to affiliate attribution used across e-commerce and professional services. The ICO's LIA guidance cites "commercial interests" as a valid category of legitimate interest provided the balancing test is satisfied (ICO, Legitimate interests, 2020, pp. 8-10).
Is the interest specific?
Yes. The processing is scoped exclusively to: (a) recording which facilitator introduced which patient, and (b) enabling commission accrual. It does not extend to behavioural profiling, targeting, or any secondary use.
Conclusion (Purpose Test): PASS. The interest is genuine, specific, and recognized in commercial law and data protection guidance.
2. Necessity Test¶
Is the processing necessary to achieve the purpose, or could the same outcome be achieved with less data?
The following alternatives were evaluated:
| Alternative | Reason rejected |
|---|---|
| UTM URL parameters only | Parameters survive only for the browser tab session; lost on redirect, bookmark-and-return, or browser restart. Cross-border medical travel funnels span days to weeks — a significant fraction of conversions would be missed. |
| Server-side IP-based attribution | Requires logging patient IP addresses against facilitator IDs pre-registration. More invasive than a cookie; error-prone under NAT/CGNAT/VPN; rejected in DPIA-2026-001 §2. |
| Explicit facilitator code entry at signup | Creates friction for less tech-fluent patients — a core Curaway demographic. Failure mode: patient abandons registration when prompted for a code they do not understand. Converts attribution loss into registration drop-off. |
| No attribution | Destroys the facilitator commission model and, with it, patient access to facilitator coordination. |
Why a cookie specifically?
The cookie holds only facilitator_id and an HMAC truncated signature ({facilitator_id}.{HMAC-SHA256(facilitator_id, secret)[:16]}). Cookie composition verified at app/services/referral_link_service.py:89-101. No PII, no IP, no timestamp, no device fingerprint is embedded in the cookie payload.
Data elements evaluated:
| Data element | In cookie? | Justification |
|---|---|---|
facilitator_id (internal UUID) |
Yes | Attribution target; irreducible. |
| HMAC signature (16 hex chars) | Yes | Tamper-detection; prevents forged attribution. |
| Patient identity | No | Not collected pre-registration by design. |
| IP address | No | Rejected as invasive (see above). |
| UA / device fingerprint | No | Disproportionate; rejected. |
| Timestamp | No | Not present in cookie payload (verified in code). |
A second cookie (curaway_ref_slug) carries the raw slug value for analytics purposes. The slug is a non-personal URL-safe identifier — it identifies the link, not the patient or the facilitator's identity directly.
Pre-consent constraint (verified): Cookies are set only when has_consent is True (app/routers/public_referral.py:245). When consent has not been given, the redirect endpoint records a counter increment only — no events row, no ip_hash or ua_hash stored. This is structurally enforced in app/services/referral_link_service.py:551-556.
One-shot consumption: The curaway_ref cookie is read once by the patient-app at registration (curaway-health-navigator/apps/patient-app/src/lib/referralCookie.ts:66-80) and submitted as referred_by_facilitator_id in POST /api/v1/patients/register. The frontend clears the cookie after extraction; it does not persist beyond registration.
Conclusion (Necessity Test): PASS. The cookie approach is the minimum-data, minimum-friction approach that achieves the purpose. No less-invasive alternative preserves attribution across the full funnel.
3. Balancing Test¶
3a. Reasonable Expectations¶
The patient's journey prior to the cookie being set:
- Patient receives a referral link from a named facilitator (via WhatsApp, email, or in-person briefing). The facilitator has explicitly positioned themselves as the patient's coordinator ("click this link and I'll be your coordinator on Curaway").
- Patient clicks the link. The URL is
https://app.curaway.ai/r/{slug}— visibly a Curaway link via the facilitator's referral. - Cookie is set only if the patient has already given cookie consent; the banner/consent is presented before or alongside the redirect.
In this context, a reasonable data subject would expect: - That clicking a referral link routes them via that facilitator. - That the facilitator receives credit for the referral. - That the cookie enables this credit, not ongoing tracking.
The cookie does not enable surveillance across sessions or sites. It is a single-purpose, one-shot attribution marker.
3b. Data Minimisation and Harm Potential¶
| Consideration | Assessment |
|---|---|
| Data category | Non-special-category. facilitator_id is a business UUID. The fact that the patient is signing up to a healthcare platform is contextually implied but is not encoded in the cookie. Cookie carries no health data. |
| PII in cookie | None. facilitator_id is an internal UUID with no direct identifier. |
| Harms from misuse | Limited. Worst-case misuse: incorrect commission attribution. No health harm, no identity disclosure, no discriminatory profiling. |
| Cookie security | Secure; SameSite=Lax enforced (app/routers/public_referral.py:252-258). Cookie is not HttpOnly — intentional, because patient-app JavaScript must read it for registration submission (httponly=False, spec §5.2). This is the narrowest deviation from HttpOnly best practice; mitigated by the payload containing no PII. |
| TTL | 1 year max age. Proportionate to funnel duration; one-shot consumption at registration eliminates any practical multi-session persistence for converted patients. |
| HMAC integrity | Forged cookies are rejected by HMAC verification at POST /patients/register (app/routers/patients.py:58-68). Constant-time comparison via hmac.compare_digest. |
3c. Override Assessment — Data Subject Interests and Rights¶
Who is affected: Patients seeking cross-border medical care. This population includes vulnerable individuals (medical need, distance from provider). The processing is not special-category data (GDPR Art. 9 does not apply to a business UUID cookie). The fact of platform use is not contained in the cookie.
Override factors:
| Factor | Weight | Assessment |
|---|---|---|
| Processing is pre-consent | Mitigating | Cookie is set only after cookie consent; pre-consent click is counter-only. |
| Data minimisation achieved | Mitigating | No PII, no health data, no tracking across sites. |
| One-shot consumption | Mitigating | Cookie is cleared at registration; no ongoing data relationship from cookie alone. |
| Vulnerable population | Aggravating | Medical context warrants higher scrutiny. |
| Patient retains opt-out | Mitigating | Declining consent at registration (Step 5 of the facilitator flow) keeps case_shares empty; facilitator cannot access case content even if attribution accrued. |
| Art. 21 objection mechanism | Mitigating | Patient may submit erasure request (Art. 17) which cascades to SET NULL on patients.referred_by_facilitator_id and cases.referred_by_facilitator_id via FK constraint. |
| Rectification exclusion | Requires disclosure | Attribution is frozen at case creation (immutable per DP-C, app/services/case_service.py:19-50) to prevent commission fraud. This must be disclosed in the privacy notice and facilitator T&Cs. |
Balance conclusion: The vulnerable population flag raises scrutiny but does not tip the balance. The processing is: - Consent-gated (cookie only after consent). - Minimal (no PII, no health data in the cookie). - Time-limited and one-shot in practice. - Matched to reasonable expectations (patient clicked a labeled referral link). - Subject to full erasure and objection rights downstream.
The controller's interest in accurate commission attribution (which also serves the patient's interest in receiving facilitator coordination) is not overridden by data subject interests, rights, and freedoms.
Conclusion (Balancing Test): BALANCE FAVORS CONTROLLER, conditional on: 1. Privacy notice disclosing attribution immutability and the one-shot cookie mechanism. 2. Facilitator T&Cs disclosing last-cookie-wins attribution policy and rectification exclusion. 3. Consent mechanism being genuinely presented before cookie set (currently enforced in code; must remain a hard constraint on any future change to the consent flow).
4. Decision¶
Article 6(1)(f) — legitimate interests — is appropriate for the processing of facilitator_id via HMAC-signed cookie and the recording of referred_by_facilitator_id on patient and case records.
All three parts of the LIA balancing test are satisfied:
| Test | Result |
|---|---|
| Purpose Test | PASS — genuine, specific, recognized commercial interest |
| Necessity Test | PASS — minimum-data approach; alternatives evaluated and rejected |
| Balancing Test | FAVORS CONTROLLER — subject to disclosures listed in §3c |
This conclusion backs the legal basis stated in DPIA-2026-001 §1.
DPO sign-off:
Name: Srikanth Donthi
Title: CPO/CTO (acting DPO under Curaway MVP governance)
Date: 2026-05-05
Signature: ____________________
5. Sections Requiring Legal Review¶
| Section | Issue |
|---|---|
| §3b — Cookie not HttpOnly | httponly=False is a deliberate engineering choice (patient-app JS must read cookie). Legal counsel should confirm this is documented in the privacy notice and that the security justification (no PII in payload) is acceptable under applicable guidance (e.g., ICO cookie guidance, CNIL recommendations). |
| §3c — Attribution immutability | The rectification exclusion (DP-C) must appear in the privacy notice and facilitator T&Cs. Confirm wording with counsel. |
| §3c — Art. 17(3)(b) for commission records | Settled commission accrual records are retained anonymized under the financial audit defence. Counsel must confirm this is established under applicable jurisdiction law (India Companies Act 2013 / UK Companies Act 2006 as applicable). See also DPIA-2026-001 §9.1. |
| §2 — Slug cookie | curaway_ref_slug stores the raw slug value. Confirm slug values are never configured to contain personally identifying strings (e.g., facilitator names) — currently a process control, not a technical enforcement. |
6. Review Schedule¶
| Trigger | Action |
|---|---|
| Annual review | 2027-05-05 |
| Any change to cookie payload composition | Immediate re-assessment — specifically any change to app/services/referral_link_service.py:89-101 (sign_cookie_value) |
| Any change to consent fork logic | Immediate re-assessment — specifically app/routers/public_referral.py:205-268 (has_consent branch) |
| Any change to attribution propagation | Immediate re-assessment — app/services/patient_service.py (register_patient) or app/services/case_service.py |
| Addition of device fingerprinting or geolocation | Full LIA re-run — current LIA is valid only for the minimal cookie payload described in §2 |
| Supervisory authority guidance on cookie attribution for healthcare | Review within 30 days of guidance publication |
7. Cross-References¶
| Document | Location |
|---|---|
| Companion DPIA | docs/compliance/dpia-facilitator-referral-attribution.md |
| Multi-tenancy architecture (cross-tenant data sharing) | docs/adr/0018-multi-tenancy-platform-architecture.md |
| Go-live plan | docs/specs/facilitator-referral-flow-go-live-plan.md |
| Redirect endpoint | app/routers/public_referral.py:134-270 |
| HMAC cookie signing | app/services/referral_link_service.py:89-101 (cookie composition); app/services/referral_link_service.py:54-67 (secret resolution) |
| Registration with attribution | app/routers/patients.py:58-68 |
| Facilitator validation | app/services/patient_service.py:180-231 |
| Click recording (pre/post-consent split) | app/services/referral_link_service.py:526-583 |
| Frontend cookie consumption | curaway-health-navigator/apps/patient-app/src/lib/referralCookie.ts:66-80 |
Appendix: Factual Discrepancies Noted vs. DPIA-2026-001¶
The following discrepancies were identified during code review for this LIA. The DPIA should be updated in a separate PR.
| Claim in DPIA-2026-001 | Actual code state | File:line |
|---|---|---|
DPIA §2: "HMAC signature provides tamper-detection … The cookie payload contains only facilitator_id (a non-personal, internal UUID) and a timestamp." |
sign_cookie_value computes {facilitator_id}.{HMAC[:16]} — no timestamp is included in the cookie payload. |
app/services/referral_link_service.py:89-101 |
| DPIA §3 Step 2 (Data Flow): implies cookie is always set at redirect. | Cookie is set only when has_consent=True; pre-consent redirects are counter-only. |
app/routers/public_referral.py:244-270 |
| DPIA §3 Step 2: "counter-only event logged … no PII" — implies ip/UA are never captured. | ip_hash and ua_hash are computed at the redirect endpoint and passed to record_click; they are stored in the events row when has_consent=True. Hashed values are not raw PII but are not the same as "no logging." |
app/routers/public_referral.py:193-195; app/services/referral_link_service.py:557-583 |
DPIA does not mention curaway_ref_slug cookie. |
Two cookies are set: curaway_ref (HMAC-signed facilitator_id) and curaway_ref_slug (raw slug, analytics). |
app/routers/public_referral.py:258-268 |
This LIA was produced under issue #656 to back the Art. 6(1)(f) basis stated in DPIA-2026-001. Source references verified against code at commit HEAD on 2026-05-05.