# Privacy and deletion runbook

Development draft, reviewed against the implementation on 16 October 2026. The owner must complete actual controller/operator identity, processing locations, processors, transfer safeguards, retention and request-handling contacts before launch. No policy page or checklist establishes compliance by itself.

## Data and purposes

| Data | Purpose and proposed basis for owner review | Current behavior |
|---|---|---|
| Preferred name, email, password hash, verification/security settings | Requested account/service contract; assessed security interests where appropriate | Fortify-managed authentication; encrypted TOTP/recovery secrets; no DOB or identity documents |
| Broad route/stage, optional municipality, non-SFI dates, task/checklist statuses | Requested relocation-planning service | Private owner records and selected task-status sharing only |
| Terms version/time and adult attestation | Record the service agreement and eligibility policy | No blanket Privacy consent; adult attestation collects no birth date |
| Price/offer snapshots, minimal Stripe identifiers, contract/payment/access/refund dates, receipt email | Service performance and separately assessed statutory financial obligations | Financial records remain separate when an account is erased; no relocation details sent to Stripe |
| Support/privacy requests | Respond to requests and fulfil applicable obligations | Category, encrypted reply email, reference and receipt time; no narrative/document collection |
| Minimal deletion ledger | Reapply erasure during restore | Email HMAC with a stable independent key, deletion time; no full profile |
| Password hash prefix | Compromised-password screening | Laravel Pwned Passwords range lookup sends five SHA-1 hash characters with padding requested; full password/profile is not sent; unavailable screening fails visibly |

There are no passport/personnummer/case-reference/banking/health fields or upload endpoints accepting files. Users can mark “Personnummer received” without entering the number. SFI stores status only; exports and calendar/reminder services exclude SFI dates. No external LLM, scanning, government submission or live case tracking exists.

Local storage is the designated development database and private Laravel storage. Actual production host, email/backup providers, access locations, subprocessors and DPAs are unresolved. Stripe is the proposed hosted payment processor; Pwned Passwords is the implemented password-range endpoint. Do not claim production storage is in the EU until the selected arrangements establish it. Review third-party terms and applicable transfers. Complete a processing record, controller/processor analysis, security-interest assessment and risk/DPIA screening.

## Rights handling

The basic export is free and streamed after reauthentication; it creates no retained download artifact. It contains the user's profile, journey and document-checklist data. A formal access/portability request can require additional financial/security/support records; do not misrepresent the basic planning export as an exhaustive rights-response package. Settings permits profile correction and account closure. Help/privacy-request routes record requests without inviting sensitive details.

Assign a responsible owner and monitor the minimal request queue. Verify identity proportionately, using existing verified account/email control where possible; never ask for an identity-document upload by default. Track receipt, scope, lawful exceptions and response. Generally act within one month; assess any permitted extension and communicate it under the applicable rules. Review the official [IMY rights guidance](https://www.imy.se/en/organisations/data-protection/this-applies-accordning-to-gdpr/the-data-subjects-rights/) and current law for the case. Inform relevant recipients/providers about corrections/erasure where required.

## Account closure and deletion

Account closure, purchase withdrawal and GDPR erasure are distinct. A customer can submit purchase withdrawal without logging in, including after closure through purchase-reference/email verification. The account-closure UI directs customers to withdrawal before erasing the journey, but does not require it.

`AccountService` deletes active user/task/checklist records and sessions, cascades sharing permissions, removes reset tokens, and records a minimal deletion marker. Queued task messages contain only record IDs and recheck record existence/entitlement before sending; deleted records therefore do not trigger reminders. Generated exports are streamed and leave no stored file. Purchase/withdrawal records retain only financial/notice data needed to resolve obligations; a user deletion sets the purchase's user reference to null. Receipt and withdrawal notices continue independently of relocation-profile deletion.

Support requests are a separate minimal case register; resolve and prune them under the owner-approved case-retention policy. Do not retain unrelated journey information for accounting. Configure provider deletion, email retention and restricted financial retention against actual statutory requirements. Exact service/log/support/financial/backup retention periods remain unresolved owner/legal decisions; none are invented here.

Before restoring a backup, merge the up-to-date deletion ledger into the isolated restore, keep its independent HMAC key, run `swedenstart:apply-deletions`, verify cascade/session/message behavior, then reconcile current Stripe states and notices. Keep the ledger outside the same point-in-time backup so a restore cannot erase knowledge of a deletion. This procedure requires an actual operational rehearsal before launch.

## Incidents

Record discovery/awareness time, systems/data affected and containment. Restrict access, preserve redacted evidence, rotate affected credentials through controlled procedures, and assess risk. The operator must determine whether notification is required; not every incident is reportable. When applicable, notify IMY without undue delay and generally within 72 hours of awareness, and inform affected individuals where the legal threshold is met. Use current [IMY breach guidance](https://www.imy.se/en/organisations/data-protection/this-applies-accordning-to-gdpr/personal-data-breaches/). Assign incident ownership and escalation before launch.

## Cookies and tracking

The application sets necessary Laravel session/request-forgery cookies and an optional user-selected persistent authentication cookie. Inspect deployed names, TTLs and secure attributes; local sessions use the configured 120-minute lifetime. No analytics, advertising, session replay, marketing consent or data-selling features are present. The sample journey stores no visitor progress. Third-party pages open with `noreferrer`; no account/journey information is placed in their URLs.

Assess actual hosted Checkout and provider behavior before finalizing the cookie inventory. Optional tracking added later must remain blocked until required consent, with an equally accessible refusal path. The current no-banner approach relies on necessary cookies only; review [PTS cookie guidance](https://pts.se/internet-och-telefoni/kakor-cookies/) for the actual deployed setup.
