GDPR tarkvaraarendajatele | Mida tegelikult tuleb rakendada
Arendajatele suunatud GDPR vastavuse juhend. Käsitleb tehnilisi nõudeid, andmekäsitluse mustreid ja kooditaseme otsuseid, mida peate tegema.
GDPR on kehtinud alates 2018. aastast, kuid enamik arendajajuhendeid keskendub endiselt õiguslikule teooriale. See juhend on erinev. See käsitleb tehnilisi nõudeid, koodi, mida peate kirjutama, ja arhitektuurilisi otsuseid, mis muudavad vastavuse praktiliseks, mitte valusaks.
Kui teie tarkvara salvestab, töötleb või puudutab EL-is elavate inimeste isikuandmeid, kehtib see teie kohta. Pole oluline, kus teie ettevõte asub.
GDPR ülevaade arendajatele
Jätke 99 artiklit vahele. Siin on, mida GDPR teie koodibaasi jaoks tähendab:
- Koguge ainult seda, mida vajate. Ärge salvestage andmeid “igaks juhuks.”
- Öelge kasutajatele, mida nende andmetega teete. Ja küsige nende luba, kui see on nõutav.
- Laske kasutajatel oma andmetele ligi pääseda, neid eksportida ja kustutada. Vajate selleks API lõpp-punkte.
- Hoidke andmed turvalisena. Krüpteerimine, juurdepääsukontrollid, auditilogi.
- Teatage rikkumistest kiiresti. Teil on 72 tundi ametiasutuste teavitamiseks pärast rikkumise avastamist.
- Dokumenteerige kõik. Teie töötlemistegevused, turvameetmed, andmevood.
See on praktiline kokkuvõte. Ülejäänud juhend näitab, kuidas iga nõuet rakendada.
7 peamist tehnilist nõuet
1. Nõusoleku haldamine
Nõusolek peab olema vabalt antud, konkreetne, teadlik ja ühemõtteline. Eeltäidetud märkeruudud ei loe. Koonddatud nõusolek (“nõustuge kõigega”) ei loe. Tagasivõtmine peab olema sama lihtne kui andmine.
Mida ehitada
Nõusolekusüsteem vajab kolme komponenti:
- Nõusolekukirjete hoidla. Iga kasutaja kohta jälgige, millega ta nõustus, millal ja kuidas.
- Nõusoleku kontrollmehhanism. Enne andmete töötlemist konkreetsel eesmärgil veenduge, et kasutajal on aktiivne nõusolek.
- Tagasivõtmise mehhanism. Laske kasutajatel nõusolek teie liidese kaudu tagasi võtta ja lõpetage töötlemine viivitamata.
Andmebaasi skeem
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);
Salvestage kogu ajalugu. Ärge kunagi kustutage ega kirjutage üle nõusolekukirjeid. Kui kasutaja võtab nõusoleku tagasi, sisestage uus rida granted = false ja määrake revoked_at. See annab teile auditiraja.
Nõusoleku kontrollimise vahevara
Siin on Express vahevara, mis kontrollib nõusolekut enne päringu töötlemist:
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. Andmetele juurdepääs ja eksport (juurdepääsuõigus)
Kasutajatel on õigus taotleda kõigi nende kohta hoitavate isikuandmete koopiat. Peate selle esitama üldkasutatvas, masinloetavas formaadis. JSON või CSV sobib hästi.
Mida ehitada
Lõpp-punkt, mis kogub kõik kasutaja isikuandmed kõigist tabelitest ja teenustest ning pakib need allalaaditavasse faili.
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);
});
See lõpp-punkt peab katma iga tabeli, mis sisaldab kasutajaandmeid. Auditeerige oma skeemi põhjalikult. Puuduv tabel tähendab puudulikku eksporti, mis on vastavuse rikkumine.
3. Kustutamisõigus (õigus olla unustatud)
Kasutajad võivad taotleda kõigi oma isikuandmete kustutamist. Peate nõusolekule vastama, välja arvatud juhul, kui teil on seaduslik kohustus andmeid säilitada (nagu maksuandmed või pettuseennetamine).
Mida ehitada
Kustutamise lõpp-punkt, mis eemaldab või anonümiseerib kasutajaandmed kõigist tabelitest. See on raskem, kui tundub, sest võõrvõtme piirangud ja andmed, millest teised süsteemid sõltuvad.
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();
}
});
Olulised otsused:
- Kustutamine vs anonümiseerimine. Raamatupidamiseks vajalikud kirjed (tellimused, arved) tuleks anonümiseerida. Kustutage kõik muu.
- Välised süsteemid. Kolmandate osapoolte teenustele saadetud andmed tuleb ka sealt kustutada.
- Ajakava. GDPR ütleb “ilma asjatu viivituseta.” Viige kustutamine lõpule 30 päeva jooksul. Enamiku süsteemide puhul tehke see koheselt.
4. Andmete minimeerimine
Koguge ja salvestage ainult andmeid, mida te tegelikult vajate määratud eesmärgil. Kui küsite telefoninumbrit, kuid kasutajatele kunagi ei helista, ei peaks te seda koguma.
Praktilised reeglid
- Auditeerige iga vormiväli. Iga välja kohta küsige: “Milline konkreetne funktsioon läheb katki, kui selle eemaldame?” Kui vastus on mitte midagi, eemaldage see.
- Määrake säilitamisperioodid. Ärge hoidke andmeid igavesti. Määratlege, kui kaua on iga tüüpi andmeid vaja, seejärel kustutage need automaatselt.
- Minimeerige logimist. Eemaldage isikuandmed logikirjetest. Logige kasutajate ID-sid, mitte nimesid või e-posti aadresse.
-- 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. Krüpteerimine
GDPR nõuab “asjakohaseid tehnilisi meetmeid” isikuandmete kaitsmiseks. Krüpteerimine on kõige olulisem.
Puhkeolekus
- Krüpteerige oma andmebaasi ketas. Kõik suuremad pilveteenuse pakkujad toetavad seda. Lülitage see sisse ja veenduge.
- Väga tundlike väljade (isikukoodid, terviseandmed) puhul lisage rakenduse taseme krüpteerimine peale.
- Krüpteerige varukoopiad. Krüpteerimata varukoopia on rikkumine ootamas juhtumist.
Edastamisel
- TLS kõikjal. Iga ühendus teenuste, andmebaaside ja kasutajate vahel. Erandeid ei ole.
- Jõustage HTTPS. Suunake HTTP ümber. Määrake HSTS päised.
- Kasutage TLS-i andmebaasiühenduste jaoks. PostgreSQL toetab seda natiivselt.
// 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. Rikkumisteade
Kui isikuandmed on kompromiteeritud, peate teavitama asjakohast andmekaitseasutust 72 tunni jooksul. Kui rikkumine kujutab üksikisikutele kõrget riski, peate teavitama ka mõjutatud kasutajaid.
Mida ehitada
- Auditi logimine. Jälgige igat isikuandmetele juurdepääsu. Kes pääses ligi, millal ja kust.
- Anomaaliate tuvastamine. Teavitage ebatavalistest juurdepääsu mustritest (massilised andmeekspordid, juurdepääs uutelt IP-delt, juurdepääs väljaspool tööaega).
- Intsidendi reageerimise plaan. Dokumenteerige, kes mida teeb, kui rikkumine avastatakse. See ei ole kood. See on kontrollnimekiri, mida teie meeskond harjutab.
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. Privaatsus disaini järgi
GDPR ütleb, et privaatsus peaks olema süsteemidesse algusest sisse ehitatud, mitte hiljem peale polditud. Praktikas tähendab see privaatsuse muutmist vaikimisi.
- Vaikimisi privaatne. Uued funktsioonid peaksid koguma minimaalselt andmeid ja nõudma nõusolekut kõigele, mis ületab põhifunktsiooni.
- Seaded on vaikimisi kõige privaatsem valik. Kasutajad, kes kunagi oma seadeid ei puuduta, peaksid saama kõrgeima privaatsuskaitse.
- Eraldage mured. Ärge segage analüütikaandmeid funktsionaalsete andmetega. Ärge taaskasutage autentimislube jälgimiseks.
Anonümiseerimine vs pseudonümiseerimine
Need ei ole sama asi ja eristamine on oluline.
- Pseudonümiseerimine asendab tuvastava teabe pööratava tokeniga. Näide: e-posti aadresside räsimine. Kui teil on räsifunktsioon ja algne e-posti aadress, saate isiku taastuvastada. GDPR kehtib endiselt, sest taastuvastamine on võimalik.
- Anonümiseerimine eemaldab tuvastava teabe jäädavalt. Näide: koondanalüütika (“1247 kasutajat külastasid hinnastaadi lehte”) ilma võimaluseta tuvastada, millised kasutajad. GDPR ei kehti tõeliselt anonümiseeritud andmetele.
Tõeline anonümiseerimine on raske. Kui teie “anonüümne” andmekogum sisaldab ajatemplit, linna ja seadme tüüpi, võib see kombinatsioon ainulaadselt isiku tuvastada. Olge konservatiivne.
Küpsiste nõusolek
Kui teie veebisait kasutab küpsiseid, mis ei ole rangelt vajalikud, vajate enne nende seadmist nõusolekut.
Nõuab nõusolekut: analüütikaküpsised, reklaamipikslid, sotsiaalmeedia vidinad, mis tahes kolmanda osapoole jälgimisskript.
Ei nõua nõusolekut: seansiküpsised, ostukorvi küpsised, CSRF tokenid, küpsiste nõusoleku eelistuse küpsis ise.
Teie nõusolekubänner peaks blokeerima mittehädavajalikud küpsised kuni nõusoleku andmiseni, pakkuma üksikasjalikke valikuid ja muutma “keeldu kõik” sama lihtsaks kui “nõustu kõigiga.” Ärge ehitage seda nullist. Sellised tööriistad nagu Cookiebot käsitlevad keerukust. Põhireegel: ükski jälgimisskript ei käivitu enne nõusoleku andmist.
Kolmanda osapoole andmetöötlejad
Iga kolmanda osapoole teenus, mis käsitleb teie kasutajate andmeid, on GDPR alusel “andmetöötleja”. Teie vastutate nende vastavuse eest.
Mida kontrollida
Enne mis tahes kolmanda osapoole teenuse integreerimist, mis puudutab isikuandmeid:
- Kas neil on DPA? Andmetöötluse leping on kohustuslik. Enamik SaaS pakkujaid avaldab oma DPA avalikult.
- Kus nad andmeid salvestavad? Kui väljaspool EL-i, kontrollige edastamise õiguslikku alust.
- Millistele andmetele neil on juurdepääs? Minimeerige saadetavat. Kui teenus vajab ainult e-posti aadressi, ärge saatke kogu profiili.
- Kas saate nende süsteemidest andmeid kustutada? Kasutaja kustutamistaotlused peavad kõikjale jõudma.
- Kuidas nad rikkumisi käsitlevad? Nende DPA peaks määrama teavitamistähtajad.
Levinud kolmanda osapoole töötlejad kontrollimiseks
- E-posti teenused (Resend, SendGrid, Mailchimp)
- Analüütika (Google Analytics, Mixpanel, Amplitude)
- Veajälgimine (Sentry, Bugsnag)
- Maksetöötlus (Stripe, Adyen)
- Pilvemajutus (AWS, Google Cloud, Vercel)
- Klienditoe tööriistad (Intercom, Zendesk)
- AI API-d (OpenAI, Anthropic, Google AI)
Hoidke nimekirja kõigist töötlejatest. Vaadake see igal kvartalis üle.
Andmete säilitamispoliitikad
Ärge hoidke isikuandmeid kauem kui vajalik. Määratlege säilitamisperioodid iga andmetüübi jaoks.
| Andmetüüp | Soovituslik säilitamine | Põhjus |
|---|---|---|
| Kasutajakonto andmed | Kuni kustutamistaotluseni | Teenuse jaoks vajalik |
| Seansilogid | 90 päeva | Turvalisus ja silumine |
| Kasutaja tegevuslogid | 1-2 aastat | Tooteanalüütika |
| Tugiteenuste piletid | 3 aastat | Teenuse kvaliteet |
| Finantsandmed | 7 aastat | Maksu-/õiguslikud kohustused |
| Parooli lähtestamise tokenid | 24 tundi | Turvalisus |
| Ebaõnnestunud sisselogimiskatsed | 90 päeva | Turvaseire |
Rakendage automatiseeritud puhastustööd. Ärge lootke, et keegi mäletab skripti käivitada.
GDPR kontrollnimekiri arendajatele
Kasutage seda lähtepunktina süsteemi ehitamisel või auditeerimisel.
Andmete kogumine
- Igal vormiväljal on määratud eesmärk
- Mittevajalikke andmeid ei koguta
- Privaatsuspoliitika on lingitud igast andmete kogumispunktist
- Nõusolek kogutakse enne töötlemist (kui nõutav)
- Nõusolekukirjed salvestatakse ajatemplitega
Andmete salvestamine
- Andmebaasi krüpteerimine puhkeolekus on lubatud
- TLS on jõustatud kõigile ühendustele
- Tundlikel väljadel on rakenduse taseme krüpteerimine
- Varukoopiad on krüpteeritud
- Juurdepääs tootmisandmetele on piiratud ja logitud
Kasutaja õigused
- Andmeekspordi lõpp-punkt eksisteerib ja katab kõiki tabeleid
- Konto kustutamise lõpp-punkt eksisteerib ja käsitleb kõiki andmeid
- Kasutajad saavad oma seadetes nõusolekut vaadata ja tagasi võtta
- Kustutamine levib kolmandate osapoolte teenustesse
- Kõigile kasutaja õiguste taotlustele vastatakse 30 päeva jooksul
Küpsised ja jälgimine
- Küpsiste nõusoleku bänner on rakendatud
- Mittehädavajalikud küpsised on enne nõusolekut blokeeritud
- Nõusoleku valikud on üksikasjalikud (mitte kõik-või-mitte-midagi)
- “Keeldu kõik” on sama silmapaistev kui “Nõustu kõigiga”
Kolmandad osapooled
- Kõik andmetöötlejad on dokumenteeritud
- DPA-d on iga töötlejaga allkirjastatud
- Kolmandatele osapooltele saadetud andmed on minimeeritud
- Andmete kustutamine kolmandatest osapooltest on võimalik
Turvalisus
- Auditi logid jälgivad juurdepääsu isikuandmetele
- Anomaaliate teavitamine on konfigureeritud
- Intsidendi reageerimise plaan on dokumenteeritud
- Rikkumisteadete protsess on määratletud (72-tunnine tähtaeg)
Säilitamine
- Säilitamisperioodid on määratletud kõigile andmetüüpidele
- Automatiseeritud puhastustööd on ajastatud
- Aegunud andmed tegelikult kustutatakse (kontrollige seda)
Lõppmõtted
GDPR vastavus ei ole ühekordne projekt. See on praktikate kogum, mis on põimitud sellesse, kuidas te tarkvara ehitate. Tehniline töö on otsekohene: nõusoleku salvestamine, andmeeksport, kustutamise lõpp-punktid, krüpteerimine, auditi logimine. Standardne inseneritöö.
Raske osa on põhjalikkus. On lihtne unustada see logifail, see analüütikasündmus või see kolmanda osapoole integratsioon, mis salvestab kasutaja e-posti aadresse. Auditeerige regulaarselt. Testige oma kustutamise lõpp-punkti. Veenduge, et teie ekspordid on täielikud. Ehitage privaatsus oma protsessi algusest peale.
Vajate abi GDPR-iga vastavusse oleva tarkvara ehitamisel või olemasolevate süsteemide auditeerimisel? Võtke ühendust. Ehitame privaatsusele suunatud rakendusi Euroopa ettevõtetele ja EL-i kasutajaid teenindavatele firmadele.