“Security by Design” lyder rigtigt – men hvis det ikke bliver oversat til konkrete krav i backloggen, ender det som et slogan, der først bliver testet, når noget går galt.
I denne artikel får du en praktisk model til at gøre Security by Design operationelt: fire områder du kan stille krav til (identitet/adgang, data, softwarekvalitet og drift), en komponent-tjekliste (API, frontend, mobil, integrationer og third-party SDKs) samt en mini-case, der viser den end-to-end dokumentation, som mange teams mangler. Undervejs får du konkrete takeaways, typiske faldgruber – og hvad det realistisk koster i tid og kompleksitet at gøre det rigtigt.
Hvad “Security by Design” er – og hvorfor det betyder noget
Security by Design betyder, at sikkerhedskrav tænkes ind som en del af design, udvikling og drift – ikke som en “hardening sprint” til sidst. Det handler om at forebygge fejltyper (uautoriseret adgang, datalæk, misbrug af API’er, supply chain-risici) gennem standardiserede kontroller og evidens, der kan gentages.
Hvorfor betyder det noget? Fordi de fleste alvorlige hændelser ikke kræver “Hollywood-hacking”. De kræver en manglende adgangskontrol, en fejlkonfigureret servicekonto, en log der ikke findes, eller en API uden rate limiting. Sikkerhed er ofte fraværet af små fejl – og små fejl er typisk procesfejl.
Mini-konklusion: Hvis du ikke kan beskrive dine sikkerhedskrav som testbare kontroller, har du ikke et designprincip – du har en hensigtserklæring.
Fra slogan til styring: 4 områder, der gør sikkerhed konkret
Det mest effektive skifte, jeg har set i teams, er at stoppe med at tale om “sikkerhed” som én ting og i stedet styre efter fire gennemgående områder. De går igen i threat models, audits, incident reviews og compliance-krav – og de er nemme at omsætte til definition of done.
- Identitet og adgang: Hvem er du, og hvad må du? (MFA, least privilege, service accounts)
- Data: Hvad håndterer vi, hvor ligger det, og hvor længe? (klassifikation, kryptering, retention)
- Softwarekvalitet: Hvordan undgår vi kendte fejlkategorier? (input validation, authz, rate limiting)
- Drift: Hvordan opdager og håndterer vi angreb og fejl? (logging, monitoring, incident response hooks)
Mini-konklusion: Fire områder er nok til at skabe overblik – og få tilstrækkelig dybde til at kunne måle og dokumentere indsatsen.
1) Identitet og adgang: MFA, least privilege og service accounts
MFA som minimum – men brug den rigtigt
MFA er baseline for admin-adgang, udviklerkonti, CI/CD og produktionsadgang. Men mange implementerer MFA uden at lukke de oplagte omveje: “break glass”-konti uden overvågning, persistente sessions uden re-auth, eller API tokens der lever evigt. Sæt en politik for session-varighed, token-udløb og krav om step-up authentication ved følsomme handlinger (fx ændring af udbetalingskonto eller eksport af data).
Least privilege i praksis (også for maskiner)
Least privilege lykkes sjældent med håndholdt rettighedsstyring. Gør det i stedet “rollebaseret og tidsbegrænset”: standardroller for læse/skrive/admin, og just-in-time adgang til produktion. For servicekonti er faldgruben ofte, at de får brede rettigheder “for at få ting til at virke”. Krav du kan indføre:
- Service accounts må kun have scoped permissions til én opgave og én ressourcegruppe
- Ingen delte “team-konti”; hver integration har sin egen identitet
- Secrets roteres (fx hver 30–90 dage) eller udskiftes med short-lived tokens
- Adgang til prod kræver audit-log og ticket-reference
Mini-konklusion: Identitet er din første perimeter. Hvis den er blød, bliver resten af kontrollerne dyrere – og ofte nytteløse.
2) Data: klassifikation, kryptering og retention
Klassifikation: du kan ikke beskytte det, du ikke har navngivet
Start simpelt: tre niveauer er ofte nok (offentlig, intern, følsom). Bind klassifikationen til konkrete regler: hvor data må lagres, hvem må tilgå det, og hvilke logfelter der er forbudte. Den klassiske fejl er, at teams “klassificerer alt som følsomt” og dermed ender med at ignorere deres egne regler. Det er bedre at være præcis end paranoid.
Kryptering og retention: sikkerhed vs. driftbarhed
Kryptering i transit (TLS) er minimum. Kryptering i hvile er ofte et krav, men den praktiske forskel ligger i nøglestyring: hvem kan tilgå nøglerne, hvordan roteres de, og kan du re-kryptere uden downtime? Retention handler om at slette det, du ikke længere har brug for. Data, du ikke har, kan ikke lække.
En pragmatisk retention-model kan fx være: logs 30–90 dage (med undtagelser), event-data 12 måneder, kontodata så længe kundeforholdet varer + lovkrav. Det vigtige er at kunne forklare “hvorfor” og vise, at sletning faktisk sker automatisk.
Mini-konklusion: Dataarbejde er kedeligt – og netop derfor bliver det ofte overset. Men det er her, de fleste reelle konsekvenser opstår ved en hændelse.
3) Softwarekvalitet: input validation, authorization og rate limiting
Sikker softwarekvalitet er i praksis en håndfuld kontroller, der eliminerer 80% af de typiske sårbarheder. Det handler ikke om “perfekt kode”, men om konsekvent håndværk og standardbiblioteker.
Input validation: accepter mindre, afvis mere
Den hyppigste kilde til bugs er implicitte antagelser: “det felt er altid en e-mail”, “den liste er altid kort”, “kunden kan ikke se andres data”. Brug schema-validation på grænserne (API gateway, backend endpoints) og normalisér input tidligt. Et konkret eksempel: begræns tekstfelter (længde, tegnsæt), whitelist filtyper og scan uploads, og afvis ukendte felter for at undgå “mass assignment”.
Authorization (authz): den kontrol, der ofte mangler
Authz er ikke det samme som authentication. Du kan være korrekt logget ind og stadig få adgang til noget, du ikke må. Indfør et fast mønster: “deny by default”, ressource-baserede checks (owner/org/role), og tests der beviser, at du ikke kan tilgå naboens data (IDOR). Den klassiske faldgrube er at lave authz i frontend i stedet for backend.
Rate limiting: gør misbrug dyrere
Rate limiting og throttling beskytter både mod brute force og mod “uheldig” automatisering. Det forbedrer også stabilitet. En god tommelfingerregel er at rate limit per bruger og per IP, og at have særligt stramme grænser på login, password reset, OTP og søgninger. Hvis du har en offentlig API, er det ofte den billigste kontrol, der kan forhindre den dyreste incident.
Mini-konklusion: Secure coding er sjældent “flere regler” – det er færre mønstre, der bruges konsekvent og testes automatisk.
4) Drift: logging, monitoring og incident response hooks
Drift er der, hvor sikkerhed bliver enten synlig eller usynlig. Mange organisationer har fine politikker, men kan ikke svare på: “Hvordan opdager vi misbrug?” og “Hvad gjorde vi, og hvornår?”
Logging der kan bruges som bevis
Logging skal være struktureret og konsistent: hvem gjorde hvad, mod hvilken ressource, med hvilket resultat. Det betyder fx correlation IDs, bruger-id (pseudonymiseret hvis nødvendigt), og event-type. Log ikke følsomme felter (passwords, tokens, fulde kortnumre). En typisk fejl er enten at logge for lidt (ingen spor) eller for meget (støj og data-læk i logs).
Monitoring og incident hooks: fra alarm til handling
Monitoring er ikke kun uptime. Du vil også måle sikkerhedssignaler: spikes i 401/403, mange password resets, usædvanlige dataeksporter, rate limit hits, og ændringer i rettigheder. Incident response hooks betyder, at produktet kan “hjælpe” under en hændelse: kill-switches, mulighed for at invalidere sessions globalt, tvungen password reset, eller at disable en integration uden deployment.
Mini-konklusion: Hvis du ikke kan opdage og reagere hurtigt, bliver selv små sårbarheder til store hændelser.
Midtvejs: gør principperne til krav, du kan teste og dokumentere
Det er her mange teams får et gennembrud: Når Security by Design bliver til konkrete krav pr. komponent, bliver det pludselig muligt at estimere, planlægge og levere sikkerhed uden drama i slutningen af sprinten.
Et nyttigt format er: “kontrol + acceptkriterium + evidens”. Eksempel: “API endpoints kræver authz-check pr. ressource” (kontrol), “403 ved adgang til andres ressource” (accept), “automatiseret integrationstest + logudsnit fra CI” (evidens).
Mini-konklusion: Sikkerhed bliver skalerbar, når den kan kopieres mellem teams og valideres automatisk.
Krav pr. komponent: API, frontend, mobile apps, integrationer og third-party SDKs
Nedenfor er en praktisk tjekliste, jeg selv ville bruge som baseline i en product security review. Den er bevidst konkret og kan bruges som “definition of done” pr. komponent.
API
- Authn/authz: OAuth/OIDC eller tilsvarende, ressourcebaseret authz, deny by default
- Input validation: schema validation, size limits, strict content types
- Rate limiting: pr. bruger/IP, særlige regler for login/reset
- Fejlhåndtering: ingen stack traces eller detaljerede fejl til klient
- Logging: audit events (login, rettighedsændringer, dataeksport)
Frontend (web)
- Ingen authz i UI alene; UI må kun afspejle backend-regler
- CSRF-beskyttelse hvor relevant, og sikker cookie-konfiguration
- Beskyttelse mod XSS via escaping, templating og content policies
- Ingen secrets i build artifacts; miljøvariabler håndteres korrekt
Mobile apps
- Sikker lagring: tokens i OS-keystore, ikke i plain storage
- Certificate pinning hvor trusselsniveauet kræver det
- Jailbreak/root-detektion som risikobaseret foranstaltning
- App-logging uden følsomme data; remote wipe/forced logout ved behov
Integrationer (intern/ekstern)
- Separate service accounts pr. integration med scoped adgang
- Timeouts, retries og idempotency for at undgå “storme” og duplikater
- Validering af payloads og signering (fx HMAC) hvor relevant
- Kill-switch: mulighed for at deaktivere integration uden release
Third-party SDKs
- Version pinning og opdateringsproces (fx månedlig gennemgang)
- SBOM/afhængighedsoverblik og sårbarhedsscanning i CI
- Begræns privileges: SDK må kun få de permissions, det behøver
- Data flow review: hvilke events/data sendes ud af huset?
Mini-konklusion: Når kravene er komponentnære, bliver de også lettere at automatisere og sværere at “glemme”.
Mini-case: “ny feature” → threat model → controls → test → release evidence
Forestil dig, at du skal lancere en ny feature: “Eksportér kunderapport som CSV” i et B2B-system. Den lyder harmløs, men den ændrer dataflow og kan misbruges.
1) Threat model (30–60 minutter, ikke en uge)
Start med tre spørgsmål: Hvilke aktiver berører vi? Hvem er angriberen? Hvad er misbrugsscenarierne? For CSV-eksport kunne det være:
- Uautoriseret eksport af andre kunders data (IDOR/authz-fejl)
- Masse-eksport (data exfiltration) via automatisering
- CSV injection (formler, der eksekveres ved åbning i regneark)
- Leak via logs eller fejlbeskeder
2) Controls (bind dem til de 4 områder)
Så vælger du kontroller, der matcher truslerne:
- Identitet/adgang: step-up auth ved eksport, og kun bestemte roller må eksportere
- Data: klassificér rapporten som følsom; log kun metadata, ikke indhold
- Softwarekvalitet: authz-check pr. kunde-id; output-escaping mod CSV injection; rate limiting på eksport-endpoint
- Drift: audit log event “report_exported”; alert ved usædvanligt antal eksporter
3) Test (gør det bevisbart)
Testpakken bør indeholde både negative tests og misbrugstests. Eksempler:
- Integrationstest: bruger A kan ikke eksportere kunde B → forvent 403
- Rate limit test: 100 eksportkald på 1 minut → throttling og audit-log
- CSV injection test: felter med “=HYPERLINK(…)” → output prefikses/escapes
- Logtest: verificér at event logges med correlation ID, men uden følsomme felter
4) Release evidence (det teams ofte mangler)
Til sidst samler du evidens, der kan vises senere: link til threat model-notat, PR med kontroller, testresultater fra CI, og en kort release note om nye audit-events/alerts. Det tager typisk 1–2 timer ekstra pr. feature, når skabelonen først er på plads – men sparer dage ved incident, audit eller kundespørgsmål.
Mini-konklusion: End-to-end sikkerhed er ikke en stor ceremoni; det er en lille, gentagelig kæde fra trussel til evidens.
Typiske spørgsmål: hvordan, hvad koster det, og hvilke fejl går igen?
Hvordan kommer vi i gang uden at bremse udviklingen? Start med de to mest “kopierbare” ting: en komponent-tjekliste (som ovenfor) og en threat model-skabelon på én side. Læg kravene ind i definition of done, og gør tests til en del af CI.
Hvad koster Security by Design? I praksis ser jeg ofte 5–15% ekstra tid pr. feature i starten, primært til authz, logging, og tests. Når mønstre og biblioteker er standardiseret, falder overhead typisk til 2–8%. Omkostningen ved ikke at gøre det er sværere at budgettere, men den viser sig som brand- og driftsskade, genudvikling og “panic hardening” under pres.
Hvilke faldgruber går igen?
- At “sikkerhed” bliver en checkliste uden ejers