← Blog
tutorials

GDPR za razvijalce programske opreme | Kaj dejansko morate implementirati

Vodnik za razvijalce o skladnosti z GDPR. Pokriva tehnične zahteve, vzorce obdelave podatkov in odločitve na ravni kode, ki jih morate sprejeti.

Ryveris Team ·
GDPR za razvijalce programske opreme | Kaj dejansko morate implementirati

GDPR velja od leta 2018, vendar se večina vodnikov za razvijalce še vedno osredotoča na pravno teorijo. Ta vodnik je drugačen. Pokriva tehnične zahteve, kodo, ki jo morate napisati, in arhitekturne odločitve, ki naredijo skladnost praktično namesto boleče.

Če vaša programska oprema shranjuje, obdeluje ali se dotika osebnih podatkov ljudi v EU, to velja za vas. Ne glede na to, kje ima vaše podjetje sedež.

Pregled GDPR za razvijalce

Preskočite 99 členov. Tukaj je, kaj GDPR pomeni za vašo zbirko kode:

  1. Zbirajte le, kar potrebujete. Ne shranjujte podatkov “za vsak slučaj.”
  2. Povejte uporabnikom, kaj počnete z njihovimi podatki. In pridobite njihovo dovoljenje, ko je zahtevano.
  3. Dovolite uporabnikom dostop, izvoz in izbris njihovih podatkov. Za to potrebujete API končne točke.
  4. Varujte podatke. Šifriranje, kontrole dostopa, revizijske sledi.
  5. Hitro poročajte o kršitvah. Imate 72 ur za obvestilo organov po odkritju kršitve.
  6. Dokumentirajte vse. Vaše dejavnosti obdelave, vaše varnostne ukrepe, vaše podatkovne tokove.

To je praktičen povzetek. Preostanek tega vodnika vam pokaže, kako implementirati vsako zahtevo.

7 ključnih tehničnih zahtev

1. Upravljanje soglasij

Soglasje mora biti svobodno dano, specifično, informirano in nedvoumno. Vnaprej označena polja ne štejejo. Skupna soglasja (“strinjam se z vsem”) ne štejejo. Umik mora biti enako lahek kot podelitev soglasja.

Kaj zgraditi

Sistem soglasij potrebuje tri komponente:

  • Shramba zapisov soglasij. Za vsakega uporabnika sledite, s čim je soglašal, kdaj in kako.
  • Mehanizem preverjanja soglasja. Pred obdelavo podatkov za določen namen preverite, ali ima uporabnik aktivno soglasje.
  • Mehanizem umika. Dovolite uporabnikom preklicati soglasje prek vašega vmesnika in takoj prenehajte z obdelavo.

Shema baze podatkov

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);

Shranite celotno zgodovino. Nikoli ne brišite ali prepisujte zapisov soglasij. Ko uporabnik prekliče soglasje, vstavite novo vrstico z granted = false in nastavite revoked_at. To vam daje revizijsko sled.

Vmesna programska oprema za preverjanje soglasja

Tukaj je Express vmesna programska oprema, ki preverja soglasje pred obdelavo zahteve:

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. Dostop do podatkov in izvoz (pravica do dostopa)

Uporabniki imajo pravico zahtevati kopijo vseh osebnih podatkov, ki jih imate o njih. Zagotoviti jih morate v splošno uporabljani, strojno berljivi obliki. JSON ali CSV sta ustrezna.

Kaj zgraditi

Končno točko, ki zbere vse osebne podatke za uporabnika iz vsake tabele in storitve, nato pa jih zapakira v prenosljivo datoteko.

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);
});

Ta končna točka mora pokriti vsako tabelo, ki vsebuje uporabniške podatke. Temeljito preverite svojo shemo. Manjkajoča tabela pomeni nepopoln izvoz, kar je kršitev skladnosti.

3. Pravica do izbrisa (pravica do pozabe)

Uporabniki lahko zahtevajo, da izbrišete vse njihove osebne podatke. Morate ugoditi, razen če imate pravno obveznost za hrambo (kot so davčni zapisi ali preprečevanje prevar).

Kaj zgraditi

Končno točko za izbris, ki odstrani ali anonimizira uporabniške podatke v vseh tabelah. To je težje, kot se sliši, zaradi omejitev tujih ključev in podatkov, od katerih so odvisni drugi sistemi.

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

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

    // Anonimizacija podatkov, ki jih je treba obdržati za poslovne zapise
    await client.query(
      `UPDATE orders
       SET customer_name = 'deleted', customer_email = 'deleted'
       WHERE user_id = $1`,
      [userId]
    );

    // Izbris podatkov, ki jih je mogoče popolnoma odstraniti
    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]);

    // Anonimizacija uporabniškega zapisa namesto izbrisa
    // To ohranja referenčno integriteto
    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");

    // Sprožitev izbrisa v zunanjih sistemih
    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();
  }
});

Ključne odločitve:

  • Izbris ali anonimizacija. Zapise, potrebne za računovodstvo (naročila, računi), je treba anonimizirati. Vse ostalo izbrišite.
  • Zunanji sistemi. Podatke, poslane storitvam tretjih oseb, je treba izbrisati tudi tam.
  • Časovni okvir. GDPR pravi “brez nepotrebnega odlašanja.” Izbris dokončajte v 30 dneh. Za večino sistemov ga naredite takojšnjega.

4. Minimizacija podatkov

Zbirajte in shranjujte le podatke, ki jih dejansko potrebujete za navedeni namen. Če zahtevate telefonsko številko, a uporabnikov nikoli ne kličete, je ne bi smeli zbirati.

Praktična pravila

  • Preverite vsako polje obrazca. Za vsako polje vprašajte: “Katera specifična funkcionalnost se pokvari, če to odstranimo?” Če je odgovor nobena, ga odstranite.
  • Nastavite obdobja hrambe. Ne shranjujte podatkov za vedno. Opredelite, koliko časa je posamezna vrsta podatkov potrebna, nato jih samodejno izbrišite.
  • Minimizirajte beleženje. Odstranite osebne podatke iz zapisov dnevnika. Beležite ID-je uporabnikov, ne imen ali e-poštnih naslovov.
-- Samodejna hramba podatkov s PostgreSQL
-- Zaženite kot razporejeno opravilo (npr. 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. Šifriranje

GDPR zahteva “ustrezne tehnične ukrepe” za zaščito osebnih podatkov. Šifriranje je najpomembnejše.

V mirovanju

  • Šifrirajte disk baze podatkov. Vsi večji ponudniki oblaka to podpirajo. Omogočite in preverite.
  • Za zelo občutljiva polja (EMŠO, zdravstveni podatki) dodajte šifriranje na ravni aplikacije poleg tega.
  • Šifrirajte varnostne kopije. Nešifrirana varnostna kopija je kršitev, ki čaka, da se zgodi.

V prenosu

  • TLS povsod. Vsaka povezava med storitvami, bazami podatkov in uporabniki. Brez izjem.
  • Zahtevajte HTTPS. Preusmerite HTTP. Nastavite HSTS glave.
  • Uporabite TLS za povezave z bazo podatkov. PostgreSQL to podpira že v osnovi.
// PostgreSQL povezava s 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. Obveščanje o kršitvah

Če so osebni podatki ogroženi, morate obvestiti pristojni organ za varstvo podatkov v 72 urah. Če kršitev predstavlja visoko tveganje za posameznike, morate obvestiti tudi prizadete uporabnike.

Kaj zgraditi

  • Revizijsko beleženje. Sledite vsakemu dostopu do osebnih podatkov. Kdo je dostopal, kdaj in od kod.
  • Zaznavanje anomalij. Opozorila ob nenavadnih vzorcih dostopa (množični izvozi podatkov, dostop z novih IP naslovov, dostop zunaj poslovnih ur).
  • Načrt odziva na incidente. Dokumentirajte, kdo kaj stori, ko je zaznana kršitev. To ni koda. Je kontrolni seznam, ki ga vaša ekipa vadbi.
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. Zasebnost po zasnovi

GDPR pravi, da mora biti zasebnost vgrajena v sisteme od začetka, ne privijačena pozneje. V praksi to pomeni, da je zasebnost privzeta.

  • Privzeto je zasebno. Nove funkcionalnosti naj zbirajo minimalno podatkov in zahtevajo privolitev za karkoli prek temeljne funkcije.
  • Nastavitve so privzeto na najbolj zasebni možnosti. Uporabniki, ki nikoli ne dotaknejo svojih nastavitev, morajo imeti najvišjo zaščito zasebnosti.
  • Ločite zadeve. Ne mešajte analitičnih podatkov s funkcionalnimi podatki. Ne ponovno uporabljajte avtentikacijskih žetonov za sledenje.

Anonimizacija ali psevdonimizacija

To ni ista stvar in razlika je pomembna.

  • Psevdonimizacija nadomesti identifikacijske informacije z reverzibilnim žetonom. Primer: zgoščevanje e-poštnih naslovov. Če imate zgoščevalno funkcijo in izvirni e-poštni naslov, lahko ponovno identificirate osebo. GDPR še vedno velja, ker je ponovna identifikacija mogoča.
  • Anonimizacija trajno odstrani identifikacijske informacije. Primer: zbirna analitika (“1.247 uporabnikov je obiskalo stran s cenami”) brez možnosti identifikacije, kateri uporabniki. GDPR ne velja za resnično anonimizirane podatke.

Resnična anonimizacija je težka. Če vaš “anonimni” nabor podatkov vključuje časovni žig, mesto in vrsto naprave, ta kombinacija morda edinstveno identificira nekoga. Bodite konzervativni.

Soglasje za piškotke

Če vaša spletna stran uporablja piškotke prek tistega, kar je strogo potrebno, potrebujete soglasje pred njihovo nastavitvijo.

Zahteva soglasje: analitični piškotki, oglaševalski piksli, gradniki družbenih medijev, katerikoli skript za sledenje tretjih oseb.

Ne zahteva soglasja: sejni piškotki, piškotki nakupovalne košarice, CSRF žetoni, sam piškotek za nastavitev soglasja za piškotke.

Vaš pasica za soglasje mora blokirati nebistvene piškotke, dokler ni soglasje podano, ponuditi natančne izbire in narediti “zavrni vse” enako enostavno kot “sprejmi vse.” Ne gradite tega od začetka. Orodja kot Cookiebot obvladajo kompleksnost. Ključno pravilo: nobena skripta za sledenje se ne sproži pred podelitvijo soglasja.

Tretji obdelovalci podatkov

Vsaka storitev tretje osebe, ki obdeluje podatke vaših uporabnikov, je “obdelovalec podatkov” po GDPR. Vi ste odgovorni za njihovo skladnost.

Kaj preveriti

Pred integracijo katerekoli storitve tretje osebe, ki se dotika osebnih podatkov:

  1. Ali imajo DPA? Pogodba o obdelavi podatkov je obvezna. Večina SaaS ponudnikov jih objavlja javno.
  2. Kje shranjujejo podatke? Če zunaj EU, preverite pravno podlago za prenos.
  3. Do katerih podatkov dostopajo? Minimizirajte, kar pošiljate. Če storitev potrebuje le e-poštni naslov, ne pošiljajte celotnega profila.
  4. Ali lahko izbrišete podatke iz njihovih sistemov? Zahteve za izbris uporabnikov se morajo razširiti povsod.
  5. Kako obravnavajo kršitve? Njihov DPA mora določati časovne okvire za obveščanje.

Pogosti tretji obdelovalci za pregled

  • E-poštne storitve (Resend, SendGrid, Mailchimp)
  • Analitika (Google Analytics, Mixpanel, Amplitude)
  • Sledenje napak (Sentry, Bugsnag)
  • Obdelava plačil (Stripe, Adyen)
  • Oblačno gostovanje (AWS, Google Cloud, Vercel)
  • Orodja za podporo strankam (Intercom, Zendesk)
  • AI API-ji (OpenAI, Anthropic, Google AI)

Vzdržujte seznam vseh obdelovalcev. Pregledujte ga četrtletno.

Politike hrambe podatkov

Ne shranjujte osebnih podatkov dlje, kot je potrebno. Opredelite obdobja hrambe za vsako vrsto podatkov.

Vrsta podatkovPredlagano obdobje hrambeRazlog
Podatki uporabniškega računaDo zahteve za izbrisPotrebni za storitev
Dnevniki sej90 dniVarnost in odpravljanje napak
Dnevniki aktivnosti uporabnikov1-2 letiAnalitika izdelka
Zahtevki podpore3 letaKakovost storitev
Finančni zapisi7 letDavčne/pravne obveznosti
Žetoni za ponastavitev gesla24 urVarnost
Neuspeli poskusi prijave90 dniVarnostno spremljanje

Implementirajte samodejna opravila čiščenja. Ne zanašajte se na to, da se bo nekdo spomnil zagnati skripto.

GDPR kontrolni seznam za razvijalce

Uporabite to kot izhodišče pri gradnji ali reviziji sistema.

Zbiranje podatkov

  • Vsako polje obrazca ima naveden namen
  • Nepotrebni podatki se ne zbirajo
  • Politika zasebnosti je povezana z vsake točke zbiranja podatkov
  • Soglasje je zbrano pred obdelavo (kjer je zahtevano)
  • Zapisi soglasij so shranjeni s časovnimi žigi

Shranjevanje podatkov

  • Šifriranje baze podatkov v mirovanju je omogočeno
  • TLS je zahtevan za vse povezave
  • Občutljiva polja imajo šifriranje na ravni aplikacije
  • Varnostne kopije so šifrirane
  • Dostop do produkcijskih podatkov je omejen in beležen

Pravice uporabnikov

  • Končna točka za izvoz podatkov obstaja in pokriva vse tabele
  • Končna točka za izbris računa obstaja in obravnava vse podatke
  • Uporabniki lahko pregledajo in umaknejo soglasje v svojih nastavitvah
  • Izbris se razširi na storitve tretjih oseb
  • Na vse zahteve uporabnikov za pravice se odzovete v 30 dneh

Piškotki in sledenje

  • Pasica za soglasje o piškotkih je implementirana
  • Nebistveni piškotki so blokirani pred soglasjem
  • Izbire soglasja so natančne (ne vse ali nič)
  • “Zavrni vse” je enako vidno kot “Sprejmi vse”

Tretje osebe

  • Vsi obdelovalci podatkov so dokumentirani
  • DPA so podpisani z vsakim obdelovalcem
  • Podatki, poslani tretjim osebam, so minimizirani
  • Izbris podatkov pri tretjih osebah je mogoč

Varnost

  • Revizijski dnevniki sledijo dostopu do osebnih podatkov
  • Opozorila o anomalijah so konfigurirana
  • Načrt odziva na incidente je dokumentiran
  • Postopek obveščanja o kršitvah je opredeljen (72-urni rok)

Hramba

  • Obdobja hrambe so opredeljena za vse vrste podatkov
  • Samodejna opravila čiščenja so razporejena
  • Potečeni podatki se dejansko brišejo (preverite to)

Zaključne misli

Skladnost z GDPR ni enkraten projekt. Je nabor praks, vtkan v način gradnje programske opreme. Tehnično delo je preprosto: shranjevanje soglasij, izvoz podatkov, končne točke za izbris, šifriranje, revizijsko beleženje. Standardno inženirstvo.

Težji del je temeljitost. Enostavno je pozabiti na tisto datoteko dnevnika, tisti analitični dogodek ali tisto integracijo tretje osebe, ki shranjuje e-poštne naslove uporabnikov. Redno revidirajte. Testirajte svojo končno točko za izbris. Preverite, ali so vaši izvozi popolni. Vgradite zasebnost v svoj proces od začetka.


Potrebujete pomoč pri gradnji programske opreme, skladne z GDPR, ali reviziji obstoječih sistemov? Stopite v stik. Gradimo aplikacije z zasebnostjo na prvem mestu za evropska podjetja in podjetja, ki služijo uporabnikom v EU.

GDPRprivacysecuritycomplianceEuropedata protection

Zgradimo vaš naslednji projekt.

Rezervirajte brezplačen 30-minutni klic. Pogovorili se bomo o vaših ciljih, časovnici in najboljšem pristopu. Brez obveznosti.

Rezervirajte uvodni klic hello@ryveris.com