← Blogg
tutorials

GDPR för mjukvaruutvecklare | Vad du faktiskt behöver implementera

En utvecklarfokuserad guide till GDPR-efterlevnad. Täcker de tekniska kraven, datahanteringsmönster och beslut på kodnivå du behöver fatta.

Ryveris Team ·
GDPR för mjukvaruutvecklare | Vad du faktiskt behöver implementera

GDPR har gällt sedan 2018, men de flesta utvecklarguider fokuserar fortfarande på den juridiska teorin. Den här guiden är annorlunda. Den täcker de tekniska kraven, koden du behöver skriva och de arkitekturbeslut som gör efterlevnad praktisk istället för smärtsam.

Om din programvara lagrar, behandlar eller berör personuppgifter från personer i EU gäller detta för dig. Det spelar ingen roll var ditt företag är baserat.

GDPR-översikt för utvecklare

Skippa de 99 artiklarna. Här är vad GDPR innebär för din kodbas:

  1. Samla bara in det du behöver. Lagra inte data “för säkerhets skull.”
  2. Berätta för användare vad du gör med deras data. Och få deras tillstånd när det krävs.
  3. Låt användare komma åt, exportera och radera sin data. Du behöver API-ändpunkter för detta.
  4. Håll data säker. Kryptering, åtkomstkontroller, granskningsloggar.
  5. Rapportera intrång snabbt. Du har 72 timmar på dig att meddela myndigheterna efter att ha upptäckt ett intrång.
  6. Dokumentera allt. Dina behandlingsaktiviteter, dina säkerhetsåtgärder, dina dataflöden.

Det är den praktiska sammanfattningen. Resten av denna guide visar hur du implementerar varje krav.

De 7 viktigaste tekniska kraven

1. Samtyckehantering

Samtycke måste vara fritt givet, specifikt, informerat och otvetydigt. Förkryssade rutor räknas inte. Buntade samtycken (“godkänn allt”) räknas inte. Återkallande måste vara lika enkelt som att ge samtycke.

Vad du ska bygga

Ett samtyckessystem behöver tre komponenter:

  • En samtyckesjournallagring. För varje användare, spåra vad de samtyckte till, när och hur.
  • En samtyckeskontrollmekanism. Innan data behandlas för ett specifikt ändamål, verifiera att användaren har aktivt samtycke.
  • En återkallandemekanism. Låt användare återkalla samtycke via ditt gränssnitt och sluta behandla omedelbart.

Databasschema

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

Lagra hela historiken. Radera eller skriv aldrig över samtyckejournaler. När en användare återkallar samtycke, infoga en ny rad med granted = false och sätt revoked_at. Det ger dig en granskningskedja.

Samtyckeskontroll-middleware

Här är en Express-middleware som kontrollerar samtycke innan en begäran behandlas:

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. Dataåtkomst och export (rätten till tillgång)

Användare har rätt att begära en kopia av alla personuppgifter du har om dem. Du måste tillhandahålla den i ett allmänt använt, maskinläsbart format. JSON eller CSV fungerar bra.

Vad du ska bygga

En ändpunkt som samlar alla personuppgifter för en användare från varje tabell och tjänst, sedan paketerar den i en nedladdningsbar fil.

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

Denna ändpunkt måste täcka varje tabell som innehåller användardata. Granska ditt schema noggrant. En utelämnad tabell innebär en ofullständig export, vilket är ett efterlevnadsbrott.

3. Rätten till radering (rätten att bli glömd)

Användare kan begära att du raderar alla deras personuppgifter. Du måste efterleva om du inte har en laglig skyldighet att behålla dem (som skatteuppgifter eller bedrägeriförebyggande).

Vad du ska bygga

En raderingsändpunkt som tar bort eller anonymiserar användardata i alla tabeller. Det här är svårare än det låter på grund av nyckelreferenser och data som andra system är beroende av.

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

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

    // Anonymisera data som måste behållas för affärsjournaler
    await client.query(
      `UPDATE orders
       SET customer_name = 'deleted', customer_email = 'deleted'
       WHERE user_id = $1`,
      [userId]
    );

    // Radera data som kan tas bort helt
    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]);

    // Anonymisera användarposten istället för att radera
    // Det bevarar referensintegriteten
    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");

    // Utlös radering i externa system
    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();
  }
});

Viktiga beslut:

  • Radera eller anonymisera. Poster som behövs för bokföring (ordrar, fakturor) bör anonymiseras. Radera allt annat.
  • Externa system. Data som skickats till tredjepartstjänster måste raderas även där.
  • Tidslinje. GDPR säger “utan onödigt dröjsmål.” Slutför radering inom 30 dagar. För de flesta system, gör det omedelbart.

4. Dataminimering

Samla bara in och lagra den data du faktiskt behöver för ett angivet ändamål. Om du frågar efter ett telefonnummer men aldrig ringer användare bör du inte samla in det.

Praktiska regler

  • Granska varje formulärfält. För varje fält, fråga: “Vilken specifik funktion slutar fungera om vi tar bort detta?” Om svaret är ingenting, ta bort det.
  • Sätt bevarandeperioder. Behåll inte data för evigt. Definiera hur länge varje typ av data behövs, sedan radera den automatiskt.
  • Minimera loggning. Rensa personuppgifter från loggposter. Logga användar-ID, inte namn eller e-postadresser.
-- Automatisk databevarande med PostgreSQL
-- Kör detta som ett schemalagt jobb (t.ex. 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. Kryptering

GDPR kräver “lämpliga tekniska åtgärder” för att skydda personuppgifter. Kryptering är den viktigaste.

I vila

  • Kryptera din databasdisk. Alla stora molnleverantörer stödjer detta. Aktivera det och verifiera.
  • För mycket känsliga fält (personnummer, hälsodata), lägg till kryptering på applikationsnivå utöver detta.
  • Kryptera säkerhetskopior. En okrypterad säkerhetskopia är ett intrång som väntar på att hända.

Under transport

  • TLS överallt. Varje anslutning mellan tjänster, databaser och användare. Inga undantag.
  • Kräv HTTPS. Omdirigera HTTP. Sätt HSTS-headers.
  • Använd TLS för databasanslutningar. PostgreSQL stödjer detta inbyggt.
// PostgreSQL-anslutning med 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. Intrångsmeddelande

Om personuppgifter komprometteras måste du meddela relevant dataskyddsmyndighet inom 72 timmar. Om intrånget utgör en hög risk för individer måste du även meddela de berörda användarna.

Vad du ska bygga

  • Granskningsloggning. Spåra varje åtkomst till personuppgifter. Vem som fick åtkomst, när och varifrån.
  • Avvikelsedetektering. Varna vid ovanliga åtkomstmönster (massexporter av data, åtkomst från nya IP-adresser, åtkomst utanför kontorstid).
  • En incidenthanteringsplan. Dokumentera vem som gör vad när ett intrång upptäcks. Det här är inte kod. Det är en checklista som ditt team övar på.
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. Inbyggt integritetsskydd (Privacy by Design)

GDPR säger att integritetsskydd ska byggas in i system från början, inte skruvas fast i efterhand. I praktiken innebär det att göra integritet till standardinställning.

  • Standard är privat. Nya funktioner bör samla minimal data och kräva aktivt samtycke för allt utöver kärnfunktionen.
  • Inställningar har högsta integritet som standard. Användare som aldrig rör sina inställningar bör ha det högsta integritetsskyddet.
  • Separera ansvarsområden. Blanda inte analysdata med funktionsdata. Återanvänd inte autentiseringstoken för spårning.

Anonymisering vs pseudonymisering

Dessa är inte samma sak, och skillnaden spelar roll.

  • Pseudonymisering ersätter identifierande information med en reversibel token. Exempel: hashning av e-postadresser. Om du har hashfunktionen och den ursprungliga e-postadressen kan du återidentifiera personen. GDPR gäller fortfarande eftersom återidentifiering är möjlig.
  • Anonymisering tar bort identifierande information permanent. Exempel: aggregerad analys (“1 247 användare besökte prissidan”) utan någon möjlighet att identifiera vilka användare. GDPR gäller inte för verkligt anonymiserad data.

Verklig anonymisering är svår. Om din “anonyma” datamängd innehåller en tidsstämpel, en stad och en enhetstyp kan den kombinationen unikt identifiera någon. Var försiktig.

Om din webbplats använder cookies utöver vad som är strikt nödvändigt behöver du samtycke innan de sätts.

Kräver samtycke: analyticscookies, annonspixlar, sociala medier-widgetar, alla tredjepartsspårningsskript.

Kräver inte samtycke: sessionscookies, varukorgscookies, CSRF-token, själva cookiesamtyckescookien.

Din samtyckesbanner bör blockera icke-nödvändiga cookies tills samtycke ges, erbjuda detaljerade val och göra “avvisa alla” lika enkelt som “acceptera alla.” Bygg inte detta från grunden. Verktyg som Cookiebot hanterar komplexiteten. Grundregeln: inga spårningsskript körs före samtycke.

Tredjepartsbehandlare

Varje tredjepartstjänst som hanterar dina användares data är en “databehandlare” under GDPR. Du är ansvarig för deras efterlevnad.

Vad du ska kontrollera

Innan du integrerar någon tredjepartstjänst som berör personuppgifter:

  1. Har de ett DPA? Ett databehandlingsavtal (Data Processing Agreement) är obligatoriskt. De flesta SaaS-leverantörer publicerar sina offentligt.
  2. Var lagrar de data? Om utanför EU, verifiera den rättsliga grunden för överföringen.
  3. Vilken data får de tillgång till? Minimera vad du skickar. Om tjänsten bara behöver en e-postadress, skicka inte hela profilen.
  4. Kan du radera data från deras system? Begäran om användarradering måste spridas överallt.
  5. Hur hanterar de intrång? Deras DPA bör specificera tidsramar för meddelande.

Vanliga tredjepartsbehandlare att granska

  • E-posttjänster (Resend, SendGrid, Mailchimp)
  • Analys (Google Analytics, Mixpanel, Amplitude)
  • Felspårning (Sentry, Bugsnag)
  • Betalningshantering (Stripe, Adyen)
  • Molnhosting (AWS, Google Cloud, Vercel)
  • Kundsupportverktyg (Intercom, Zendesk)
  • AI-API:er (OpenAI, Anthropic, Google AI)

Ha en lista över alla behandlare. Granska den kvartalsvis.

Databevarandepolicyer

Behåll inte personuppgifter längre än nödvändigt. Definiera bevarandeperioder för varje datatyp.

DatatypFöreslagen bevarandetidAnledning
AnvändarkontodataTills radering begärsBehövs för tjänsten
Sessionsloggar90 dagarSäkerhet och felsökning
Användaraktivitetsloggar1-2 årProduktanalys
Supportärenden3 årTjänstekvalitet
Finansiella poster7 årSkatte- och juridiska skyldigheter
Lösenordsåterställningstoken24 timmarSäkerhet
Misslyckade inloggningsförsök90 dagarSäkerhetsövervakning

Implementera automatiserade rensningsjobb. Lita inte på att någon kommer ihåg att köra ett skript.

GDPR-checklista för utvecklare

Använd detta som en startpunkt när du bygger eller granskar ett system.

Datainsamling

  • Varje formulärfält har ett angivet ändamål
  • Ingen onödig data samlas in
  • Integritetspolicyn är länkad från varje datainsamlingspunkt
  • Samtycke samlas in före behandling (där det krävs)
  • Samtyckejournaler lagras med tidsstämplar

Datalagring

  • Databaskryptering i vila är aktiverad
  • TLS är påtvingat för alla anslutningar
  • Känsliga fält har kryptering på applikationsnivå
  • Säkerhetskopior är krypterade
  • Åtkomst till produktionsdata är begränsad och loggad

Användarrättigheter

  • Ändpunkt för dataexport finns och täcker alla tabeller
  • Ändpunkt för kontoradering finns och hanterar all data
  • Användare kan se och återkalla samtycke i sina inställningar
  • Radering sprids till tredjepartstjänster
  • Alla begäranden om användarrättigheter besvaras inom 30 dagar

Cookies och spårning

  • Samtyckesbanner för cookies är implementerad
  • Icke-nödvändiga cookies blockeras före samtycke
  • Samtyckesval är detaljerade (inte allt eller inget)
  • “Avvisa alla” är lika framträdande som “Acceptera alla”

Tredje parter

  • Alla databehandlare är dokumenterade
  • DPA:er är undertecknade med varje behandlare
  • Data som skickas till tredje parter är minimerad
  • Radering av data från tredje parter är möjlig

Säkerhet

  • Granskningsloggar spårar åtkomst till personuppgifter
  • Avvikelselarm är konfigurerade
  • Incidenthanteringsplan är dokumenterad
  • Process för intrångsmeddelande är definierad (72-timmarsdeadline)

Bevarande

  • Bevarandeperioder är definierade för alla datatyper
  • Automatiserade rensningsjobb är schemalagda
  • Utgången data raderas faktiskt (verifiera detta)

Avslutande tankar

GDPR-efterlevnad är inte ett engångsprojekt. Det är en uppsättning arbetssätt invävda i hur du bygger programvara. Det tekniska arbetet är okomplicerat: samtyckelagring, dataexport, raderingsändpunkter, kryptering, granskningsloggning. Standardteknik.

Den svåra delen är att vara grundlig. Det är lätt att glömma den där loggfilen, den där analyticshändelsen eller den där tredjepartsintegrationen som lagrar användares e-postadresser. Granska regelbundet. Testa din raderingsändpunkt. Verifiera att dina exporter är fullständiga. Bygg in integritet i din process från början.


Behöver du hjälp med att bygga GDPR-anpassad programvara eller granska dina befintliga system? Kontakta oss. Vi bygger integritetsfokuserade applikationer för europeiska företag och verksamheter som betjänar EU-användare.

GDPRprivacysecuritycomplianceEuropedata protection

Låt oss bygga ditt nästa projekt.

Boka ett kostnadsfritt 30-minuterssamtal. Vi diskuterar dina mål, tidsplan och bästa tillvägagångssätt. Helt förutsättningslöst.

Boka ett introduktionssamtal hello@ryveris.com