← Blog
tutorials

GDPR pro vývojáře softwaru | Co skutečně potřebujete implementovat

Průvodce GDPR zaměřený na vývojáře. Pokrývá technické požadavky, vzorce zpracování dat a rozhodnutí na úrovni kódu, která musíte udělat.

Ryveris Team ·
GDPR pro vývojáře softwaru | Co skutečně potřebujete implementovat

GDPR je v platnosti od roku 2018, ale většina průvodců pro vývojáře se stále zaměřuje na právní teorii. Tento průvodce je jiný. Pokrývá technické požadavky, kód, který potřebujete napsat, a architektonická rozhodnutí, díky kterým je soulad praktický místo bolestivého.

Pokud váš software ukládá, zpracovává nebo se dotýká osobních údajů lidí v EU, vztahuje se to na vás. Nezáleží na tom, kde sídlí vaše firma.

Přehled GDPR pro vývojáře

Přeskočte 99 článků. Zde je, co GDPR znamená pro vaši kódovou základnu:

  1. Shromažďujte jen to, co potřebujete. Neukládejte data “pro případ, že by se hodila.”
  2. Řekněte uživatelům, co děláte s jejich daty. A když je to vyžadováno, získejte jejich souhlas.
  3. Umožněte uživatelům přístup k datům, jejich export a smazání. Potřebujete na to API endpointy.
  4. Udržujte data v bezpečí. Šifrování, řízení přístupu, auditní logy.
  5. Hlaste úniky rychle. Máte 72 hodin na oznámení úřadům po zjištění úniku.
  6. Dokumentujte vše. Vaše zpracovatelské činnosti, bezpečnostní opatření, datové toky.

To je praktické shrnutí. Zbytek tohoto průvodce ukazuje, jak implementovat každý požadavek.

7 klíčových technických požadavků

1. Správa souhlasů

Souhlas musí být svobodně udělený, konkrétní, informovaný a jednoznačný. Předem zaškrtnutá políčka se nepočítají. Spojený souhlas (“souhlasím se vším”) se nepočítá. Odvolání musí být stejně snadné jako udělení souhlasu.

Co vybudovat

Systém souhlasů potřebuje tři komponenty:

  • Úložiště záznamů o souhlasech. Pro každého uživatele sledujte, s čím souhlasil, kdy a jak.
  • Mechanismus kontroly souhlasu. Před zpracováním dat pro konkrétní účel ověřte, že uživatel má aktivní souhlas.
  • Mechanismus odvolání. Umožněte uživatelům odvolat souhlas prostřednictvím vašeho UI a okamžitě zastavte zpracování.

Databázové schéma

CREATE TABLE user_consents (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES users(id),
  consent_type VARCHAR(100) NOT NULL,
  granted BOOLEAN NOT NULL,
  granted_at TIMESTAMPTZ,
  revoked_at TIMESTAMPTZ,
  ip_address INET,
  user_agent TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_user_consents_lookup
  ON user_consents (user_id, consent_type, granted);

Ukládejte kompletní historii. Nikdy nemažte ani nepřepisujte záznamy o souhlasech. Když uživatel odvolá souhlas, vložte nový řádek s granted = false a nastavte revoked_at. To vám dává auditní stopu.

Middleware pro kontrolu souhlasu

Zde je Express middleware, který kontroluje souhlas před zpracováním požadavku:

import { Request, Response, NextFunction } from "express";
import { db } from "./database";

interface ConsentRequirement {
  type: string;
  required: boolean;
}

function requireConsent(consentType: string) {
  return async (req: Request, res: Response, next: NextFunction) => {
    const userId = req.user?.id;

    if (!userId) {
      return res.status(401).json({ error: "Authentication required" });
    }

    const consent = await db.query(
      `SELECT granted FROM user_consents
       WHERE user_id = $1 AND consent_type = $2
       ORDER BY created_at DESC
       LIMIT 1`,
      [userId, consentType]
    );

    if (!consent.rows[0]?.granted) {
      return res.status(403).json({
        error: "Consent required",
        consentType,
        message: `You must grant "${consentType}" consent to use this feature.`,
        consentUrl: `/settings/privacy`,
      });
    }

    next();
  };
}

// Usage
app.post(
  "/api/newsletter/subscribe",
  requireConsent("marketing_emails"),
  subscribeHandler
);

app.post(
  "/api/analytics/track",
  requireConsent("usage_analytics"),
  trackHandler
);

2. Přístup k datům a export (právo na přístup)

Uživatelé mají právo požádat o kopii všech osobních údajů, které o nich máte. Musíte je poskytnout v běžně používaném, strojově čitelném formátu. JSON nebo CSV vyhoví.

Co vybudovat

Endpoint, který shromáždí všechna osobní data uživatele ze všech tabulek a služeb a zabalí je do stahovatelného souboru.

interface DataExport {
  exportedAt: string;
  user: {
    profile: Record<string, unknown>;
    activity: Record<string, unknown>[];
    consents: Record<string, unknown>[];
    communications: Record<string, unknown>[];
  };
}

app.get("/api/me/data-export", authenticate, async (req, res) => {
  const userId = req.user.id;

  const [profile, activity, consents, communications] = await Promise.all([
    db.query("SELECT id, email, name, created_at FROM users WHERE id = $1", [
      userId,
    ]),
    db.query(
      "SELECT action, metadata, created_at FROM user_activity WHERE user_id = $1 ORDER BY created_at DESC",
      [userId]
    ),
    db.query(
      "SELECT consent_type, granted, granted_at, revoked_at FROM user_consents WHERE user_id = $1 ORDER BY created_at DESC",
      [userId]
    ),
    db.query(
      "SELECT type, sent_at, subject FROM communications WHERE user_id = $1 ORDER BY sent_at DESC",
      [userId]
    ),
  ]);

  const exportData: DataExport = {
    exportedAt: new Date().toISOString(),
    user: {
      profile: profile.rows[0],
      activity: activity.rows,
      consents: consents.rows,
      communications: communications.rows,
    },
  };

  res.setHeader("Content-Type", "application/json");
  res.setHeader(
    "Content-Disposition",
    `attachment; filename="data-export-${userId}.json"`
  );
  res.json(exportData);
});

Tento endpoint musí pokrýt každou tabulku obsahující uživatelská data. Důkladně prověřte své schéma. Chybějící tabulka znamená neúplný export, což je selhání souladu.

3. Právo na výmaz (právo být zapomenut)

Uživatelé mohou požádat o smazání všech svých osobních údajů. Musíte vyhovět, pokud nemáte zákonnou povinnost data uchovávat (jako daňové záznamy nebo prevence podvodů).

Co vybudovat

Endpoint pro smazání, který odstraní nebo anonymizuje uživatelská data napříč všemi tabulkami. To je těžší, než to zní, kvůli cizím klíčům a datům, na kterých závisí jiné systémy.

app.delete("/api/me/account", authenticate, async (req, res) => {
  const userId = req.user.id;
  const client = await db.getClient();

  try {
    await client.query("BEGIN");

    // Anonymize data that must be retained for business records
    await client.query(
      `UPDATE orders
       SET customer_name = 'deleted', customer_email = 'deleted'
       WHERE user_id = $1`,
      [userId]
    );

    // Delete data that can be fully removed
    await client.query("DELETE FROM user_activity WHERE user_id = $1", [
      userId,
    ]);
    await client.query("DELETE FROM user_consents WHERE user_id = $1", [
      userId,
    ]);
    await client.query("DELETE FROM communications WHERE user_id = $1", [
      userId,
    ]);
    await client.query("DELETE FROM sessions WHERE user_id = $1", [userId]);

    // Anonymize the user record instead of deleting
    // This preserves referential integrity
    await client.query(
      `UPDATE users SET
        email = 'deleted-' || id || '@removed.invalid',
        name = 'Deleted User',
        phone = NULL,
        address = NULL,
        deleted_at = NOW()
       WHERE id = $1`,
      [userId]
    );

    await client.query("COMMIT");

    // Trigger deletion in external systems
    await Promise.allSettled([
      emailService.deleteSubscriber(userId),
      analyticsService.deleteUser(userId),
      searchIndex.removeUser(userId),
    ]);

    res.json({ message: "Account and personal data deleted" });
  } catch (error) {
    await client.query("ROLLBACK");
    throw error;
  } finally {
    client.release();
  }
});

Klíčová rozhodnutí:

  • Smazat vs. anonymizovat. Záznamy potřebné pro účetnictví (objednávky, faktury) by měly být anonymizovány. Vše ostatní smažte.
  • Externí systémy. Data odeslaná službám třetích stran musí být smazána i tam.
  • Časování. GDPR říká “bez zbytečného odkladu.” Dokončete smazání do 30 dnů. Pro většinu systémů to udělejte okamžitě.

4. Minimalizace dat

Shromažďujte a ukládejte pouze data, která skutečně potřebujete pro uvedený účel. Pokud žádáte telefonní číslo, ale uživatelům nikdy nevoláte, neměli byste ho shromažďovat.

Praktická pravidla

  • Prověřte každé pole formuláře. U každého pole se zeptejte: “Jaká konkrétní funkce se rozbije, když ho odstraníme?” Pokud je odpověď nic, odstraňte ho.
  • Nastavte doby uchovávání. Neuchovávejte data navěky. Definujte, jak dlouho je každý typ dat potřeba, a poté je automaticky smažte.
  • Minimalizujte logování. Odstraňte osobní údaje z logových záznamů. Logujte ID uživatelů, ne jména nebo e-maily.
-- Automatic data retention with PostgreSQL
-- Run this as a scheduled job (e.g., pg_cron)
DELETE FROM user_activity
WHERE created_at < NOW() - INTERVAL '2 years';

DELETE FROM session_logs
WHERE created_at < NOW() - INTERVAL '90 days';

DELETE FROM password_reset_tokens
WHERE created_at < NOW() - INTERVAL '24 hours';

5. Šifrování

GDPR vyžaduje “přiměřená technická opatření” k ochraně osobních údajů. Šifrování je nejdůležitější.

V klidu

  • Šifrujte disk databáze. Všichni hlavní cloudoví poskytovatelé to podporují. Zapněte to a ověřte.
  • Pro vysoce citlivá pole (rodná čísla, zdravotní údaje) přidejte šifrování na úrovni aplikace navíc.
  • Šifrujte zálohy. Nešifrovaná záloha je únik čekající na příležitost.

Při přenosu

  • TLS všude. Každé spojení mezi službami, databázemi a uživateli. Bez výjimek.
  • Vynuťte HTTPS. Přesměrujte HTTP. Nastavte HSTS hlavičky.
  • Používejte TLS pro databázová připojení. PostgreSQL to nativně podporuje.
// PostgreSQL connection with TLS
import { Pool } from "pg";

const pool = new Pool({
  host: process.env.DB_HOST,
  port: 5432,
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  ssl: {
    rejectUnauthorized: true,
    ca: fs.readFileSync("/path/to/server-ca.pem").toString(),
  },
});

6. Oznámení o úniku

Pokud dojde ke kompromitaci osobních údajů, musíte oznámit příslušnému úřadu pro ochranu osobních údajů do 72 hodin. Pokud únik představuje vysoké riziko pro jednotlivce, musíte informovat i zasažené uživatele.

Co vybudovat

  • Auditní logování. Sledujte každý přístup k osobním údajům. Kdo k nim přistoupil, kdy a odkud.
  • Detekce anomálií. Upozornění na neobvyklé přístupové vzorce (hromadné exporty dat, přístup z nových IP, přístup mimo pracovní dobu).
  • Plán reakce na incidenty. Zdokumentujte, kdo co dělá, když je detekován únik. Toto není kód. Je to checklist, na kterém váš tým trénuje.
CREATE TABLE data_access_log (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL,
  accessed_by UUID NOT NULL,
  access_type VARCHAR(50) NOT NULL,
  resource_type VARCHAR(100) NOT NULL,
  resource_id UUID,
  ip_address INET,
  user_agent TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_data_access_log_user
  ON data_access_log (user_id, created_at);

CREATE INDEX idx_data_access_log_accessor
  ON data_access_log (accessed_by, created_at);

7. Privacy by Design

GDPR říká, že ochrana soukromí by měla být do systémů zabudována od začátku, ne přidána dodatečně. V praxi to znamená, že soukromí je výchozí stav.

  • Výchozí stav je soukromý. Nové funkce by měly shromažďovat minimum dat a vyžadovat opt-in pro cokoliv nad rámec základní funkce.
  • Nastavení jsou ve výchozím stavu na nejsoukromější možnost. Uživatelé, kteří se nikdy nedotknou svých nastavení, by měli mít nejvyšší ochranu soukromí.
  • Oddělte záležitosti. Nemíchejte analytická data s funkčními daty. Nepoužívejte opakovaně auth tokeny pro sledování.

Anonymizace vs. pseudonymizace

Toto nejsou totéž a rozdíl je důležitý.

  • Pseudonymizace nahrazuje identifikační informace reverzibilním tokenem. Příklad: hashování e-mailových adres. Pokud máte hashovací funkci a původní e-mail, můžete osobu znovu identifikovat. GDPR stále platí, protože opětovná identifikace je možná.
  • Anonymizace odstraňuje identifikační informace trvale. Příklad: agregovaná analytika (“1 247 uživatelů navštívilo stránku s cenami”) bez možnosti identifikovat, kteří uživatelé. GDPR se nevztahuje na skutečně anonymizovaná data.

Skutečná anonymizace je obtížná. Pokud váš “anonymní” dataset obsahuje časové razítko, město a typ zařízení, tato kombinace může někoho jednoznačně identifikovat. Buďte konzervativní.

Pokud váš web používá cookies nad rámec toho, co je nezbytně nutné, potřebujete souhlas před jejich nastavením.

Vyžaduje souhlas: analytické cookies, reklamní pixely, widgety sociálních sítí, jakýkoli sledovací skript třetí strany.

Nevyžaduje souhlas: session cookies, cookies nákupního košíku, CSRF tokeny, samotná cookie preference souhlasu.

Váš banner souhlasu by měl blokovat neesenciální cookies do udělení souhlasu, nabízet granulární volby a učinit “odmítnout vše” stejně snadné jako “přijmout vše.” Nestavte to od nuly. Nástroje jako Cookiebot zvládnou složitost. Klíčové pravidlo: žádné sledovací skripty se nespouštějí před udělením souhlasu.

Zpracovatelé dat třetích stran

Každá služba třetí strany zpracovávající data vašich uživatelů je “zpracovatel dat” podle GDPR. Za jejich soulad jste odpovědní vy.

Co ověřit

Před integrací jakékoli služby třetí strany, která se dotýká osobních údajů:

  1. Mají DPA? Smlouva o zpracování dat je povinná. Většina SaaS poskytovatelů ji zveřejňuje.
  2. Kde ukládají data? Pokud mimo EU, ověřte právní základ pro přenos.
  3. K jakým datům přistupují? Minimalizujte, co posíláte. Pokud služba potřebuje jen e-mail, neposílejte celý profil.
  4. Můžete smazat data z jejich systémů? Žádosti o smazání uživatelů musí propagovat všude.
  5. Jak řeší úniky? Jejich DPA by měla specifikovat lhůty oznámení.

Běžní zpracovatelé třetích stran k prověření

  • E-mailové služby (Resend, SendGrid, Mailchimp)
  • Analytika (Google Analytics, Mixpanel, Amplitude)
  • Sledování chyb (Sentry, Bugsnag)
  • Zpracování plateb (Stripe, Adyen)
  • Cloudový hosting (AWS, Google Cloud, Vercel)
  • Nástroje zákaznické podpory (Intercom, Zendesk)
  • AI API (OpenAI, Anthropic, Google AI)

Udržujte seznam všech zpracovatelů. Přezkoumávejte ho čtvrtletně.

Zásady uchovávání dat

Neuchovávejte osobní údaje déle, než je nutné. Definujte doby uchovávání pro každý typ dat.

Typ datDoporučená doba uchováváníDůvod
Data uživatelského účtuDokud není požadáno smazáníPotřebné pro službu
Session logy90 dníBezpečnost a ladění
Logy aktivity uživatelů1-2 rokyProduktová analytika
Support tickety3 rokyKvalita služeb
Finanční záznamy7 letDaňové/právní povinnosti
Tokeny pro reset hesla24 hodinBezpečnost
Neúspěšné pokusy o přihlášení90 dníBezpečnostní monitoring

Implementujte automatizované úklidové úlohy. Nespoléhejte na to, že si někdo vzpomene spustit skript.

GDPR checklist pro vývojáře

Použijte jako výchozí bod při budování nebo auditu systému.

Shromažďování dat

  • Každé pole formuláře má uvedený účel
  • Nejsou shromažďována zbytečná data
  • Zásady ochrany soukromí jsou odkazovány z každého bodu sběru dat
  • Souhlas je získán před zpracováním (kde je vyžadován)
  • Záznamy o souhlasech jsou uchovávány s časovými razítky

Ukládání dat

  • Šifrování databáze v klidu je zapnuto
  • TLS je vynuceno pro všechna připojení
  • Citlivá pole mají šifrování na úrovni aplikace
  • Zálohy jsou šifrovány
  • Přístup k produkčním datům je omezen a logován

Práva uživatelů

  • Endpoint pro export dat existuje a pokrývá všechny tabulky
  • Endpoint pro smazání účtu existuje a zpracovává všechna data
  • Uživatelé mohou zobrazit a odvolat souhlas ve svém nastavení
  • Smazání se propaguje do služeb třetích stran
  • Všechny žádosti o uživatelská práva jsou zodpovězeny do 30 dnů

Cookies a sledování

  • Banner pro cookie consent je implementován
  • Neesenciální cookies jsou blokovány před souhlasem
  • Volby souhlasu jsou granulární (ne vše, nebo nic)
  • “Odmítnout vše” je stejně výrazné jako “Přijmout vše”

Třetí strany

  • Všichni zpracovatelé dat jsou zdokumentováni
  • DPA jsou podepsány se všemi zpracovateli
  • Data odesílaná třetím stranám jsou minimalizována
  • Smazání dat u třetích stran je možné

Bezpečnost

  • Auditní logy sledují přístup k osobním údajům
  • Upozornění na anomálie jsou nakonfigurována
  • Plán reakce na incidenty je zdokumentován
  • Proces oznámení úniku je definován (lhůta 72 hodin)

Uchovávání

  • Doby uchovávání jsou definovány pro všechny typy dat
  • Automatizované úklidové úlohy jsou naplánované
  • Prošlá data jsou skutečně mazána (ověřte to)

Závěrečné myšlenky

Soulad s GDPR není jednorázový projekt. Je to soubor praktik vetknutých do způsobu, jakým budujete software. Technická práce je přímočará: ukládání souhlasů, export dat, endpointy pro smazání, šifrování, auditní logování. Standardní inženýring.

Těžká část je být důsledný. Je snadné zapomenout na ten logový soubor, tu analytickou událost nebo tu integraci třetí strany ukládající e-maily uživatelů. Pravidelně auditujte. Testujte svůj endpoint pro smazání. Ověřujte, že vaše exporty jsou kompletní. Budujte ochranu soukromí do svého procesu od začátku.


Potřebujete pomoc s budováním GDPR-kompatibilního softwaru nebo auditem vašich existujících systémů? Ozvěte se nám. Budujeme aplikace s ochranou soukromí na prvním místě pro evropské firmy a společnosti obsluhující uživatele z EU.

GDPRprivacysecuritycomplianceEuropedata protection

Pojďme vytvořit váš další projekt.

Rezervujte si bezplatný 30minutový hovor. Probereme vaše cíle, termíny a nejlepší přístup. Bez závazku.

Rezervovat konzultaci hello@ryveris.com