DevSecOps — Beveiliging als geïntegreerd onderdeel van software delivery
Een compleet praktijkboek over DevSecOps: cultuur, security gates, threat modeling, SAST/SCA/DAST, secretsbeheer, policy as code, supply chain security en een volledig uitgewerkte praktijkcasus.
DEVSECOPS
Hoofdstuk 1 — Inleiding: wat is DevSecOps?
Software wordt tegenwoordig sneller gebouwd en vaker uitgeleverd dan ooit tevoren. Waar organisaties vroeger een paar keer per jaar een nieuwe release uitbrachten, gebeurt dat bij veel teams nu meerdere keren per dag. Deze versnelling is grotendeels te danken aan DevOps: de beweging die ontwikkeling (Development) en beheer (Operations) samenbrengt in geautomatiseerde, herhaalbare processen. Maar met deze snelheid ontstaat een nieuw risico: beveiliging kan niet langer een losstaande, langzame stap aan het einde van het traject zijn. Als security pas wordt getoetst vlak voor een release, ontstaat er wrijving, vertraging en frustratie — en vaak worden bevindingen genegeerd omdat de deadline al is vastgelegd.
DevSecOps is het antwoord op dit probleem. Het is geen nieuw team, geen nieuwe tool en geen keurmerk, maar een manier van werken waarin beveiliging een geïntegreerd, geautomatiseerd en gedeeld onderdeel wordt van de volledige softwarelevenscyclus — van de eerste ontwerpschets tot de code die in productie draait en wordt gemonitord. De term is een samentrekking van Development, Security en Operations, en de volgorde van de letters is bewust: security wordt letterlijk tussen development en operations in geplaatst, als iets dat overal bij hoort in plaats van ergens aan het einde wordt toegevoegd.
1.1 Waarom traditionele beveiliging niet meer volstaat
In de klassieke aanpak werd beveiliging vaak gezien als een poortwachtersfunctie: een apart security-team voerde aan het einde van een project een audit of penetratietest uit, en pas na goedkeuring mocht de software live. Dit model had drie grote nadelen.
- Snelheid: een audit die weken duurt past niet bij een team dat meerdere keren per dag deployt.
- Kosten: hoe later een kwetsbaarheid wordt gevonden, hoe duurder het is om deze te herstellen — een fout die in de ontwerpfase tien minuten kost om te corrigeren, kan in productie dagen of weken werk vergen, inclusief hotfixes, communicatie en mogelijk reputatieschade.
- Verantwoordelijkheid: wanneer beveiliging het exclusieve domein van één team is, voelen ontwikkelaars zich er niet verantwoordelijk voor en ontstaat er een cultuur van "security is niet mijn probleem".
1.2 De kernbelofte van DevSecOps
DevSecOps belooft niet dat er nooit meer kwetsbaarheden zullen ontstaan — dat is een utopie. De belofte is dat kwetsbaarheden sneller, vaker en goedkoper worden gevonden en verholpen, door:
- Automatisering: beveiligingscontroles worden zoveel mogelijk geautomatiseerd en in de CI/CD-pijplijn ingebouwd, zodat ze bij elke commit of pull request worden uitgevoerd.
- Vroege feedback (shift left): ontwikkelaars krijgen al tijdens het coderen of tijdens de pull request feedback over kwetsbaarheden, in plaats van weken later.
- Gedeelde verantwoordelijkheid: beveiliging is niet het exclusieve domein van één team, maar een gedeelde verantwoordelijkheid van ontwikkelaars, security-specialisten en operations-teams.
- Continue monitoring (shield right): ook na de deployment blijft een systeem bewaakt, zodat afwijkend gedrag en nieuwe kwetsbaarheden snel worden opgemerkt.
- Meetbaarheid: beveiliging wordt met concrete metrics gevolgd, zodat verbetering aantoonbaar is in plaats van een gevoel.
DevSecOps is de praktijk waarbij beveiligingsprincipes, -tooling en -verantwoordelijkheden worden geïntegreerd in elke fase van de DevOps-levenscyclus, met als doel software sneller én veiliger te leveren, zonder dat snelheid en veiligheid elkaar uitsluiten.
1.3 Voor wie is dit boek?
Dit e-book is geschreven voor ontwikkelaars, platform- en operations-engineers, security-specialisten, engineering managers en architecten die willen begrijpen hoe DevSecOps in de praktijk werkt — niet alleen op conceptueel niveau, maar ook in concrete, uitvoerbare vorm. Ieder hoofdstuk combineert theorie met praktijkvoorbeelden, diagrammen en YAML-configuraties die direct als uitgangspunt kunnen dienen voor een eigen CI/CD-pijplijn. De voorbeelden zijn platform-onafhankelijk beschreven, met concrete uitwerkingen in GitHub Actions en GitLab CI, twee van de meest gebruikte CI/CD-platformen.
1.4 Opbouw van dit boek
Het boek is opgebouwd volgens de natuurlijke volgorde van de softwarelevenscyclus: we beginnen bij cultuur en principes, gaan via ontwerp en threat modeling naar de pijplijn zelf, behandelen per fase de belangrijkste scanmethoden (SAST, SCA, DAST, IaC-scanning, containerbeveiliging), bespreken vervolgens secretsbeheer, policy-as-code en compliance, en sluiten af met monitoring, metrics, organisatorische verandering en een uitgewerkte praktijkcasus met een volledige pijplijnconfiguratie.
Hoofdstuk 2 — Van DevOps naar DevSecOps
2.1 De opkomst van DevOps
Rond 2009 ontstond de DevOps-beweging als reactie op de muur tussen ontwikkeling en beheer. Ontwikkelaars bouwden software die "werkte op mijn machine", terwijl operations-teams verantwoordelijk waren voor de stabiliteit van productieomgevingen. Deze scheiding leidde tot lange releasecycli, handmatige overdrachten en wederzijds wantrouwen. DevOps introduceerde praktijken als continuous integration, continuous delivery, infrastructure as code en uitgebreide monitoring, met als doel: sneller, betrouwbaarder en met minder wrijving software uitleveren.
2.2 Waarom security aanvankelijk buiten beeld bleef
In de eerste jaren van DevOps lag de nadruk vooral op snelheid en samenwerking tussen Dev en Ops. Security-teams werden vaak niet uitgenodigd aan tafel, deels omdat traditionele beveiligingsprocessen (audits, handmatige reviews, periodieke scans) niet pasten bij het tempo van continuous delivery. Het gevolg was een groeiende kloof: hoe sneller DevOps-teams gingen leveren, hoe verder security achterop raakte. Beveiligingsteams werden gezien als vertragende factor, en "shadow IT" en ongeautoriseerde deployments namen toe.
2.3 De geboorte van DevSecOps
Vanaf ongeveer 2015 begon de term DevSecOps (ook wel SecDevOps of Rugged DevOps genoemd) ingang te vinden. De gedachte was simpel maar ingrijpend: als beveiliging niet kan meebewegen met de snelheid van DevOps, moet beveiliging zelf worden geautomatiseerd en in de pijplijn worden ingebouwd. In plaats van een handmatige poort aan het einde, wordt security een reeks geautomatiseerde controles die parallel aan de ontwikkeling meelopen.
2.4 Kernverschillen tussen DevOps en DevSecOps
| Aspect | Klassieke DevOps | DevSecOps |
|---|---|---|
| Moment van security-toetsing | Aan het einde, vóór release | Continu, in elke fase |
| Verantwoordelijkheid | Apart security-team | Gedeeld door alle teams |
| Tooling | Handmatige scans en audits | Geautomatiseerde scans in de pijplijn |
| Feedback-snelheid | Dagen tot weken | Seconden tot minuten |
| Cultuur | "Security als blokkade" | "Security als enabler" |
| Meetpunt | Aantal audits uitgevoerd | Mean Time To Remediate, aantal kritieke bevindingen |
2.5 Shift left én shield right
Twee begrippen komen in vrijwel elk gesprek over DevSecOps terug: shift left en shield right. Shift left betekent dat beveiligingsactiviteiten die traditioneel laat in het proces plaatsvonden, naar voren worden gehaald — denk aan threat modeling tijdens het ontwerp, statische codeanalyse tijdens het schrijven van code, en scans op afhankelijkheden bij elke pull request. Shield right vult dit aan: ook na de deployment blijft het systeem actief bewaakt, met runtime-bescherming, anomaliedetectie en incident response. DevSecOps is dus geen eenmalige verschuiving naar links, maar een cirkel van continue aandacht voor beveiliging, van begin tot eind en weer terug.
"Security is not a gate, it's a guardrail." — Een veelgehoorde uitspraak binnen DevSecOps-gemeenschappen, die de verschuiving samenvat van beveiliging als blokkerende controle naar beveiliging als ondersteunende structuur die teams helpt binnen veilige grenzen snel te bewegen.
Hoofdstuk 3 — Kernprincipes en cultuur
Tooling alleen maakt geen organisatie DevSecOps-volwassen. De meest doorslaggevende factor is cultuur: de manier waarop mensen samenwerken, verantwoordelijkheid nemen en omgaan met fouten. In dit hoofdstuk bespreken we de principes die de basis vormen voor een gezonde DevSecOps-praktijk.
3.1 Gedeelde verantwoordelijkheid
In een DevSecOps-cultuur is beveiliging niet het exclusieve domein van een centraal security-team. Ontwikkelaars zijn verantwoordelijk voor het schrijven van veilige code en het oplossen van bevindingen uit geautomatiseerde scans. Platform- en operations-teams zijn verantwoordelijk voor het hardenen van infrastructuur en het bewaken van productieomgevingen. Het security-team verschuift van uitvoerder naar facilitator: het stelt beleid op, kiest en beheert tooling, biedt training en treedt op als expert bij complexe vraagstukken.
3.2 Security champions
Een bewezen praktijk is het aanstellen van security champions: ontwikkelaars binnen een team die affiniteit hebben met beveiliging en als eerste aanspreekpunt fungeren. Zij hoeven geen beveiligingsexperts te zijn, maar fungeren als brug tussen het security-team en het ontwikkelteam, signaleren risico's vroegtijdig en helpen collega's bij het interpreteren van scanresultaten.
3.3 Automatiseer wat herhaalbaar is
Elke controle die een mens herhaaldelijk en op dezelfde manier uitvoert, is een kandidaat voor automatisering. Handmatige controles zijn foutgevoelig, inconsistent en schalen niet. Geautomatiseerde controles daarentegen zijn consistent, snel en kunnen bij elke wijziging opnieuw worden uitgevoerd zonder extra kosten. Dit betekent niet dat mensen overbodig worden: complexe risicoanalyses, architecturale beslissingen en het interpreteren van resultaten in context blijven mensenwerk.
3.4 Fail fast, fail safe
Een pijplijn die een kritieke kwetsbaarheid detecteert, moet de build kunnen blokkeren ("fail the build") vóórdat de wijziging verder in de keten terechtkomt. Dit klinkt streng, maar voorkomt dat kwetsbaarheden zich opstapelen. Belangrijk is wel dat deze poorten proportioneel zijn: niet elke bevinding met lage ernst hoeft een build te blokkeren. Een gebalanceerd beleid onderscheidt tussen ernstniveaus en bepaalt per niveau of een bevinding blokkerend is, een waarschuwing oplevert, of enkel wordt gelogd.
3.5 Beveiliging als continu proces, niet als project
Beveiliging heeft geen eindpunt. Nieuwe kwetsbaarheden worden dagelijks ontdekt in bestaande software, aanvalstechnieken evolueren, en de omgeving van een systeem verandert voortdurend. Een DevSecOps-praktijk moet daarom worden ingericht als continu proces: periodieke herevaluatie van bedreigingsmodellen, regelmatige updates van scanregels, en een cultuur die leert van elk incident.
3.6 Psychologische veiligheid en een blamefree cultuur
Wanneer een kwetsbaarheid of incident wordt ontdekt, is de eerste vraag niet "wie heeft dit veroorzaakt?", maar "wat kunnen we hiervan leren en hoe voorkomen we herhaling?". Een cultuur waarin mensen bang zijn om fouten te melden, leidt tot verborgen problemen die later veel groter en duurder worden. Blameless post-mortems — waarin het proces en het systeem centraal staan, niet de persoon — zijn een kernonderdeel van een volwassen DevSecOps-cultuur.
Begin niet met het kopen van dure tooling. Begin met één geautomatiseerde scan (bijvoorbeeld een dependency-scan) in één pijplijn, laat het team de waarde ervaren, en breid vervolgens stapsgewijs uit. Cultuurverandering ontstaat door herhaalde, kleine, zichtbare successen.
Hoofdstuk 4 — De DevSecOps-pijplijn en security gates
De CI/CD-pijplijn (Continuous Integration / Continuous Delivery) is het technische hart van DevSecOps. Elke keer dat een ontwikkelaar code commit, doorloopt deze een reeks geautomatiseerde stappen: bouwen, testen, scannen en uiteindelijk uitrollen. In een DevSecOps-pijplijn worden op strategische punten beveiligingscontroles (security gates) toegevoegd, die de pijplijn kunnen blokkeren als er een probleem wordt gevonden.
4.1 De belangrijkste soorten security gates
| Afkorting | Betekenis | Wanneer in de pijplijn |
|---|---|---|
| SAST | Static Application Security Testing — analyse van broncode zonder deze uit te voeren | Bij elke commit / pull request |
| SCA | Software Composition Analysis — scannen van open source afhankelijkheden | Bij elke commit / build |
| Secrets scan | Detecteren van per ongeluk gecommitte wachtwoorden en sleutels | Bij elke commit |
| Image scan | Scannen van container-images op kwetsbaarheden | Na build, vóór push naar registry |
| IaC scan | Scannen van infrastructuurcode (Terraform, Helm, Kubernetes-manifests) | Bij wijziging van infrastructuurcode |
| DAST | Dynamic Application Security Testing — testen van een draaiende applicatie | In een staging-omgeving |
| Policy-as-code | Automatische afdwinging van organisatiebeleid | Vóór deployment |
4.2 Blokkerend versus signalerend
Niet elke bevinding moet een pijplijn stopzetten. Een veelgebruikte aanpak is het werken met ernstniveaus (bijvoorbeeld critical, high, medium, low) waarbij alleen bevindingen boven een bepaalde drempel de build blokkeren. Bevindingen onder de drempel worden gelogd en getoond in een dashboard, maar blokkeren de release niet. Deze aanpak voorkomt "alert fatigue": als elke kleine bevinding de pijplijn blokkeert, gaan teams op den duur waarschuwingen negeren of gates omzeilen.
4.3 Voorbeeld: GitHub Actions-workflow met meerdere security gates
Onderstaand voorbeeld toont een vereenvoudigde maar realistische GitHub Actions-workflow die statische analyse, dependency-scanning en secretsdetectie combineert, met een falende stap wanneer kritieke problemen worden gevonden.
name: devsecops-pipeline
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up taal-runtime
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Installeer afhankelijkheden
run: npm ci
- name: Unit tests
run: npm test -- --ci
sast-scan:
needs: build-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep SAST-scan
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/security-audit
env:
SEMGREP_RULES_FAIL_ON: "error"
dependency-scan:
needs: build-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Software Composition Analysis
uses: aquasecurity/trivy-action@0.24.0
with:
scan-type: "fs"
scan-ref: "."
severity: "CRITICAL,HIGH"
exit-code: "1"
secrets-scan:
needs: build-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Gitleaks secrets-scan
uses: gitleaks/gitleaks-action@v2
env:
GITLEAKS_ENABLE_COMMENTS: "true"
deploy:
needs: [sast-scan, dependency-scan, secrets-scan]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy naar productie
run: ./scripts/deploy.sh production4.4 Hetzelfde principe in GitLab CI
stages:
- build
- security
- deploy
variables:
DOCKER_DRIVER: overlay2
build:
stage: build
script:
- npm ci
- npm run build
sast:
stage: security
image: returntocorp/semgrep
script:
- semgrep --config p/owasp-top-ten --error --config p/security-audit .
allow_failure: false
dependency_scanning:
stage: security
image: aquasec/trivy:latest
script:
- trivy fs --severity CRITICAL,HIGH --exit-code 1 .
allow_failure: false
secret_detection:
stage: security
image: zricethezav/gitleaks:latest
script:
- gitleaks detect --source . --exit-code 1
deploy_production:
stage: deploy
script:
- ./scripts/deploy.sh production
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
needs:
- sast
- dependency_scanning
- secret_detectionZet security-jobs zoveel mogelijk parallel (zoals in beide voorbeelden) zodat ze de totale doorlooptijd van de pijplijn niet onnodig verlengen. Sequentiële scans die niet van elkaar afhankelijk zijn, zijn een veelgemaakte doorlooptijd-killer.
Hoofdstuk 5 — Threat modeling: nadenken vóór je bouwt
Threat modeling is het gestructureerd nadenken over wat er mis kan gaan met een systeem, vóórdat het gebouwd wordt — en het vervolgens ontwerpen van tegenmaatregelen. Het is een van de krachtigste shift-left-technieken, omdat het architecturale kwetsbaarheden aan het licht brengt die geen enkele scanner achteraf kan detecteren.
5.1 STRIDE: een praktisch raamwerk
STRIDE, ontwikkeld door Microsoft, is een van de meest gebruikte raamwerken voor het categoriseren van bedreigingen. Het is een ezelsbruggetje voor zes categorieën:
- Spoofing — je voordoen als iemand of iets anders (bijvoorbeeld een vervalste identiteit of API-sleutel).
- Tampering — het ongeautoriseerd wijzigen van data, in transit of at rest.
- Repudiation — het kunnen ontkennen van een uitgevoerde actie, bij gebrek aan goede logging.
- Information disclosure — het blootstellen van informatie aan onbevoegden.
- Denial of service — het onbeschikbaar maken van een dienst.
- Elevation of privilege — het verkrijgen van meer rechten dan toegestaan.
5.2 Het threat modeling-proces in vijf stappen
- Breng het systeem in kaart: teken een data flow diagram met componenten, datastromen en vertrouwensgrenzen (trust boundaries).
- Identificeer bedreigingen: loop voor elk onderdeel van het diagram de STRIDE-categorieën langs en stel de vraag "wat kan hier misgaan?".
- Beoordeel het risico: schat kans en impact in, bijvoorbeeld met een eenvoudige risicomatrix of het DREAD-model.
- Bepaal mitigaties: kies concrete tegenmaatregelen — technisch (encryptie, validatie, authenticatie) of procesmatig (code review, monitoring).
- Valideer en herhaal: threat modeling is geen eenmalige exercise; herhaal het bij elke significante architecturale wijziging.
5.3 Threat modeling integreren in DevSecOps
In een agile omgeving is een dagenlange threat modeling-sessie voor elke user story onrealistisch. Praktische aanpakken zijn: een lichte threat modeling-check als vast onderdeel van de Definition of Ready voor nieuwe features met significante architecturale impact, een jaarlijkse of per-kwartaal grondige herziening van het volledige systeem, en geautomatiseerde ondersteuning via tools die op basis van architectuurdiagrammen (bijvoorbeeld in code, zoals Threat Dragon of pytm) automatisch een deel van de bedreigingen suggereren.
# Voorbeeld: threat model als code met pytm (Python)
from pytm import TM, Server, Datastore, Dataflow, Boundary, Actor
tm = TM("Voorbeeld: klantportaal")
tm.description = "Threat model van het klantportaal en de backend-API"
internet = Boundary("Internet")
interne_zone = Boundary("Interne zone")
klant = Actor("Klant")
klant.inBoundary = internet
webserver = Server("Webserver")
webserver.inBoundary = interne_zone
webserver.isEncrypted = True
database = Datastore("Klantendatabase")
database.inBoundary = interne_zone
database.isEncrypted = True
Dataflow(klant, webserver, "HTTPS-verzoek")
Dataflow(webserver, database, "SQL-query")
tm.process()Hoofdstuk 6 — Secure coding practices
Geautomatiseerde scans zijn een vangnet, geen vervanging voor kennis. Ontwikkelaars die de belangrijkste kwetsbaarheidscategorieën begrijpen, schrijven vanaf het begin veiligere code en interpreteren scanresultaten beter.
6.1 De OWASP Top 10 als kompas
De OWASP Top 10 is een regelmatig bijgewerkte lijst van de meest voorkomende en impactvolle kwetsbaarheidscategorieën in webapplicaties. Ze vormt een uitstekend uitgangspunt voor training en voor het configureren van scanregels.
| Categorie | Korte omschrijving | Voorbeeldmaatregel |
|---|---|---|
| Broken access control | Gebruikers kunnen acties uitvoeren of data inzien buiten hun rechten | Server-side autorisatiecontroles op elk endpoint |
| Cryptografische fouten | Gevoelige data onvoldoende of onjuist versleuteld | TLS afdwingen, sterke, actuele algoritmen gebruiken |
| Injection | Ongevalideerde invoer wordt geïnterpreteerd als code of query | Parameterized queries, input-validatie, allowlisting |
| Onveilig ontwerp | Fundamentele ontwerpfouten, los van implementatie | Threat modeling, secure design patterns |
| Verkeerde beveiligingsconfiguratie | Onveilige standaardinstellingen, onnodige functies actief | Hardening-baselines, configuratie als code |
| Kwetsbare en verouderde componenten | Gebruik van afhankelijkheden met bekende kwetsbaarheden | SCA-scanning, tijdig patchen |
| Identificatie- en authenticatiefouten | Zwakke sessie- of wachtwoordafhandeling | Multi-factor authenticatie, veilige sessietokens |
| Software- en data-integriteitsfouten | Onvoldoende verificatie van updates en CI/CD-pijplijnen | Ondertekende artefacten, geverifieerde pijplijnen |
| Tekortschietende logging en monitoring | Aanvallen blijven onopgemerkt door gebrekkige logging | Gestructureerde logging, alerting op afwijkingen |
| Server-side request forgery (SSRF) | Server wordt misbruikt om interne verzoeken te doen | Allowlisting van uitgaande bestemmingen, netwerksegmentatie |
6.2 Praktische secure coding-richtlijnen
- Valideer alle invoer aan de serverzijde, ook als er al client-side validatie is — client-side controles zijn een gebruiksgemak, geen beveiligingsmaatregel.
- Gebruik parameterized queries of ORM's in plaats van string-concatenatie voor databasequeries, om SQL-injectie te voorkomen.
- Pas het principe van minimale rechten (least privilege) toe: elk proces, elke service-account en elke gebruiker krijgt precies genoeg rechten om zijn taak uit te voeren, niet meer.
- Behandel alle externe invoer als onbetrouwbaar, inclusief data uit interne systemen en berichten van andere microservices.
- Codeer output correct afhankelijk van de context (HTML, JavaScript, SQL) om cross-site scripting en injectie te voorkomen.
- Vermijd het zelf bedenken van cryptografische algoritmen; gebruik beproefde, actief onderhouden bibliotheken.
- Log beveiligingsrelevante gebeurtenissen (inlogpogingen, autorisatiefouten) zonder gevoelige data zoals wachtwoorden of volledige creditcardnummers te loggen.
6.3 Code review met een beveiligingsbril
Naast geautomatiseerde scans blijft menselijke code review waardevol, juist voor zaken die moeilijk automatisch te detecteren zijn: logische autorisatiefouten, onjuiste aannames over vertrouwde grenzen, en subtiele race conditions. Een korte securitychecklist als onderdeel van de pull request-template — bijvoorbeeld "is invoer gevalideerd?", "zijn nieuwe endpoints voorzien van autorisatiecontroles?", "worden er geen geheimen gelogd?" — verhoogt de kwaliteit van reviews aanzienlijk zonder veel overhead.
Hoofdstuk 7 — SAST en SCA: de eerste geautomatiseerde verdedigingslinie
7.1 Static Application Security Testing (SAST)
SAST-tools analyseren broncode, bytecode of binaries zonder de applicatie uit te voeren. Ze bouwen een model van de code (vaak een abstracte syntaxboom of controlestroomgraaf) en zoeken naar patronen die met bekende kwetsbaarheidscategorieën overeenkomen, zoals onveilige functieaanroepen, ontbrekende invoervalidatie of hardcoded geheimen.
Bekende open source en commerciële SAST-tools zijn onder meer Semgrep, SonarQube, CodeQL en Checkmarx. Semgrep is populair vanwege de leesbare, YAML-gebaseerde regelsyntaxis, waarmee teams eenvoudig eigen regels kunnen schrijven naast de kant-en-klare regelsets.
# Voorbeeld: eigen Semgrep-regel om hardcoded wachtwoorden te detecteren
rules:
- id: hardcoded-wachtwoord
languages: [python]
message: >
Mogelijk hardcoded wachtwoord gevonden. Gebruik een secrets-manager
of omgevingsvariabele in plaats van een letterlijke waarde in de code.
severity: ERROR
metadata:
category: security
owasp: "A07:2021 - Identification and Authentication Failures"
patterns:
- pattern-either:
- pattern: $VAR = "..."
- metavariable-regex:
metavariable: $VAR
regex: (?i)(password|wachtwoord|secret|token|apikey)7.2 SAST-configuratie in de pijplijn
# GitHub Actions job: SAST met CodeQL
name: codeql-analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "0 3 * * 1" # wekelijkse volledige scan
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
strategy:
matrix:
language: ["javascript", "python"]
steps:
- uses: actions/checkout@v4
- name: Initialiseer CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Voer CodeQL-analyse uit
uses: github/codeql-action/analyze@v37.3 Software Composition Analysis (SCA)
Moderne applicaties bestaan voor een groot deel — vaak meer dan tachtig procent — uit open source afhankelijkheden. SCA-tools analyseren deze afhankelijkheden, vergelijken ze met databases van bekende kwetsbaarheden (zoals de National Vulnerability Database) en signaleren wanneer een gebruikte versie een bekend beveiligingsprobleem bevat. Populaire tools zijn Trivy, Grype, Snyk en OWASP Dependency-Check.
# GitLab CI: SCA met Trivy, met SBOM-generatie
dependency_scanning:
stage: security
image: aquasec/trivy:latest
variables:
TRIVY_CACHE_DIR: ".trivycache"
script:
- trivy fs --format table --severity CRITICAL,HIGH,MEDIUM .
- trivy fs --format cyclonedx --output sbom.json .
- trivy fs --severity CRITICAL,HIGH --exit-code 1 .
artifacts:
paths:
- sbom.json
reports:
dependency_scanning: sbom.json
cache:
paths:
- .trivycache/7.4 Omgaan met valse positieven en "noise"
Een veelgehoorde klacht over SAST- en SCA-tools is het aantal valse positieven: bevindingen die bij nadere inspectie geen daadwerkelijk risico vormen. Dit ondermijnt het vertrouwen van ontwikkelaars in de tooling. Praktische aanpakken om dit te beperken zijn: het afstemmen van regelsets op de gebruikte taal en context in plaats van alle standaardregels te activeren, het gebruik van een baseline zodat alleen nieuwe bevindingen worden getoond, en het documenteren van bewust geaccepteerde bevindingen (met motivatie en vervaldatum) in plaats van ze te negeren.
Voer bij de introductie van een nieuwe scanner eerst een 'baseline-scan' uit op de bestaande codebase, en configureer de pijplijn zodat alleen nieuwe bevindingen (ten opzichte van deze baseline) de build blokkeren. Dit voorkomt dat een team wordt overspoeld door duizenden historische bevindingen op dag één.
Hoofdstuk 8 — DAST: de applicatie testen terwijl hij draait
Waar SAST naar de broncode kijkt, test Dynamic Application Security Testing (DAST) een daadwerkelijk draaiende applicatie, meestal in een staging- of testomgeving. DAST-tools gedragen zich als een geautomatiseerde aanvaller: ze sturen verzoeken naar de applicatie, manipuleren invoer en analyseren de respons op tekenen van kwetsbaarheden zoals SQL-injectie, cross-site scripting of onjuiste beveiligingsheaders.
8.1 SAST versus DAST versus IAST
| Type | Wat wordt getest | Voordeel | Beperking |
|---|---|---|---|
| SAST | Broncode, zonder uitvoering | Vroeg in de cyclus, exacte locatie in code | Geen zicht op runtime-configuratie |
| DAST | Draaiende applicatie, van buitenaf | Vindt runtime- en configuratiefouten | Later in de cyclus, geen exacte coderegel |
| IAST | Applicatie tijdens tests, met interne instrumentatie | Combineert snelheid met detail | Vereist instrumentatie van de applicatie |
8.2 DAST integreren in de pijplijn met OWASP ZAP
OWASP ZAP (Zed Attack Proxy) is een van de meest gebruikte open source DAST-tools. Het kan als geautomatiseerde baseline-scan of als volledige actieve scan tegen een staging-omgeving worden ingezet.
# GitHub Actions: DAST-scan met OWASP ZAP tegen een staging-omgeving
name: dast-scan
on:
workflow_run:
workflows: ["deploy-staging"]
types: [completed]
jobs:
zap-scan:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- name: OWASP ZAP baseline scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: "https://staging.voorbeeld-app.nl"
rules_file_name: ".zap/rules.tsv"
cmd_options: "-a"
fail_action: true
- name: Publiceer rapport als artefact
uses: actions/upload-artifact@v4
with:
name: zap-rapport
path: report_html.html# .zap/rules.tsv - regels om bepaalde bevindingen te negeren of te downgraden
# formaat: <rule-id> <actie: IGNORE|WARN|FAIL> <toelichting>
10021 WARN X-Content-Type-Options ontbreekt op statische assets
10038 FAIL Content Security Policy header ontbreekt of te permissief
90022 IGNORE Bekende false positive op health-check endpoint8.3 Wanneer DAST wel en niet zinvol is
DAST is bijzonder waardevol voor het vinden van configuratiefouten die pas zichtbaar worden wanneer een applicatie daadwerkelijk draait: ontbrekende beveiligingsheaders, onjuist ingestelde TLS, of endpoints die per ongeluk publiek toegankelijk zijn. Het is minder geschikt voor het vinden van logische autorisatiefouten die specifieke, geauthenticeerde gebruikersscenario's vereisen — daarvoor zijn gerichte, op maat geschreven testscripts of handmatige penetratietests beter geschikt. DAST vervangt periodieke, diepgaande penetratietests dan ook niet, maar vult ze aan door continu een brede, ondiepe controle uit te voeren.
Hoofdstuk 9 — Infrastructure as Code en containerbeveiliging
Met de opkomst van cloud-native architecturen is infrastructuur zelf code geworden: Terraform, CloudFormation, Kubernetes-manifests en Helm-charts beschrijven declaratief hoe een omgeving eruitziet. Dit betekent dat dezelfde principes die gelden voor applicatiecode — versiebeheer, code review, geautomatiseerde tests — ook op infrastructuur van toepassing zijn. Het betekent ook dat fouten in infrastructuurcode net zo'n groot beveiligingsrisico vormen als fouten in applicatiecode, met als extra risico dat ze vaak breder impact hebben.
9.1 Infrastructure as Code (IaC) scanning
IaC-scanners analyseren configuratiebestanden op bekende misconfiguraties: publiek toegankelijke opslag, ontbrekende encryptie, te ruime firewallregels, of containers die als root draaien. Bekende tools zijn tfsec, Checkov en Terrascan.
# Terraform-fragment MET een veelvoorkomende misconfiguratie
resource "aws_s3_bucket" "data" {
bucket = "voorbeeld-klantdata"
}
resource "aws_s3_bucket_public_access_block" "data" {
bucket = aws_s3_bucket.data.id
block_public_acls = false # <-- kwetsbaarheid: publieke ACL's toegestaan
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}# GitLab CI: IaC-scan met tfsec en Checkov
iac_scan:
stage: security
image:
name: aquasec/tfsec:latest
entrypoint: [""]
script:
- tfsec ./infrastructure --minimum-severity HIGH --format default
rules:
- changes:
- infrastructure/**/*.tf
checkov_scan:
stage: security
image: bridgecrew/checkov:latest
script:
- checkov -d ./infrastructure --framework terraform --compact --quiet
rules:
- changes:
- infrastructure/**/*.tf9.2 Containerbeveiliging in lagen
Containers introduceren een eigen verzameling risico's: kwetsbare basis-images, containers die met te veel rechten draaien, en een gedeelde kernel die een aanvaller mogelijk kan gebruiken om van een container naar de host te ontsnappen (container escape). Containerbeveiliging vereist daarom een gelaagde aanpak.
9.3 Container image scanning
# GitHub Actions: image scanning met Trivy vóór het pushen naar de registry
jobs:
build-and-scan-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Bouw container-image
run: docker build -t registry.voorbeeld.nl/app:${{ github.sha }} .
- name: Scan image met Trivy
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: "registry.voorbeeld.nl/app:${{ github.sha }}"
severity: "CRITICAL,HIGH"
exit-code: "1"
ignore-unfixed: true
format: "table"
- name: Push naar registry (alleen bij geslaagde scan)
run: docker push registry.voorbeeld.nl/app:${{ github.sha }}9.4 Kubernetes hardening
Een correct geconfigureerd Kubernetes-cluster beperkt de impact van een gecompromitteerde container aanzienlijk. Belangrijke maatregelen zijn: containers nooit als root laten draaien, een read-only root filesystem waar mogelijk, expliciete resource-limieten, netwerkbeleid (NetworkPolicy) dat verkeer tussen pods beperkt tot wat noodzakelijk is, en admission controllers die onveilige manifests blokkeren vóórdat ze worden toegepast.
# Kubernetes: veilig geconfigureerd Pod-manifest
apiVersion: v1
kind: Pod
metadata:
name: voorbeeld-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
fsGroup: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: registry.voorbeeld.nl/app:1.4.2
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits:
cpu: "500m"
memory: "256Mi"
requests:
cpu: "100m"
memory: "128Mi"
ports:
- containerPort: 8080# Kubernetes: NetworkPolicy die verkeer beperkt tot het noodzakelijke
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-netwerkbeleid
spec:
podSelector:
matchLabels:
app: voorbeeld-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: api-gateway
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432Gebruik zo klein mogelijke basis-images (distroless of Alpine-varianten) om het aanvalsoppervlak te beperken: hoe minder software in het image, hoe minder er kwetsbaar kan zijn en hoe kleiner de image om te scannen en te distribueren.
Hoofdstuk 10 — Secretsbeheer
Wachtwoorden, API-sleutels, certificaten en tokens — samen "secrets" genoemd — zijn een van de meest voorkomende oorzaken van datalekken wanneer ze per ongeluk in broncode, configuratiebestanden of logs terechtkomen. Secretsbeheer is het geheel van praktijken en tooling om deze gevoelige waarden veilig op te slaan, te distribueren en te roteren.
10.1 Waarom secrets niet in code horen
Zodra een geheim in een Git-repository wordt gecommit, blijft het — ook na verwijdering — in de geschiedenis staan, tenzij de volledige geschiedenis wordt herschreven. Bovendien worden repositories vaak gekopieerd, geforkt of gedeeld, waardoor een eenmaal gelekt geheim moeilijk terug te trekken is. De enige betrouwbare oplossing is: secrets nooit committen, en als het toch gebeurt, het geheim onmiddellijk intrekken (roteren) — het verwijderen uit de geschiedenis alleen is onvoldoende.
10.2 Geautomatiseerde secretsdetectie
Tools als Gitleaks en TruffleHog scannen commits op patronen die kenmerkend zijn voor geheimen (API-sleutels, private keys, tokens) en kunnen worden ingezet als pre-commit hook (lokaal, vóórdat een commit wordt gemaakt) én als pijplijnstap (als laatste vangnet).
# .pre-commit-config.yaml - lokale controle vóór elke commit
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.4
hooks:
- id: gitleaks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: detect-private-key
- id: check-added-large-files10.3 Centrale secrets-managers
In plaats van geheimen te verspreiden over configuratiebestanden, omgevingsvariabelen en scripts, worden ze idealiter centraal beheerd in een secrets-manager zoals HashiCorp Vault, AWS Secrets Manager, Azure Key Vault of Google Secret Manager. Applicaties en pijplijnen vragen geheimen dynamisch op via een API, met fijnmazige toegangscontrole, audit-logging en automatische rotatie.
# GitHub Actions: secrets ophalen uit HashiCorp Vault tijdens de pijplijn
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Haal secrets op uit Vault
uses: hashicorp/vault-action@v3
with:
url: https://vault.voorbeeld.nl
method: jwt
role: ci-deploy-role
secrets: |
secret/data/productie/database DB_WACHTWOORD | DB_PASSWORD ;
secret/data/productie/api API_SLEUTEL | API_KEY
- name: Deploy met opgehaalde secrets
run: ./scripts/deploy.sh
env:
DB_PASSWORD: ${{ env.DB_PASSWORD }}
API_KEY: ${{ env.API_KEY }}10.4 Kubernetes secrets: standaard onvoldoende
Standaard Kubernetes Secrets worden slechts base64-gecodeerd, niet versleuteld — dit is geen beveiligingsmaatregel maar enkel een encoderingsformaat. Voor productieomgevingen wordt daarom aangeraden encryptie-at-rest voor de etcd-datastore te activeren en, waar mogelijk, een externe secrets-manager te integreren met tools zoals External Secrets Operator, die geheimen dynamisch synchroniseert vanuit Vault of een cloud-provider naar Kubernetes.
# External Secrets Operator: synchroniseer een secret vanuit Vault naar Kubernetes
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: database-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: database-credentials
creationPolicy: Owner
data:
- secretKey: password
remoteRef:
key: secret/data/productie/database
property: DB_WACHTWOORDBehandel elk gelekt geheim als gecompromitteerd, ongeacht hoe kort het zichtbaar was. Automatiseer rotatie zodat een lek een routinematige, snelle actie wordt in plaats van een crisis.
Hoofdstuk 11 — Policy as Code en compliance as code
Naarmate organisaties groeien, groeit ook de behoefte om organisatiebeleid — bijvoorbeeld "containers mogen nooit als root draaien" of "opslag moet altijd versleuteld zijn" — consistent af te dwingen over honderden of duizenden repositories en clusters. Handmatige controle is dan niet meer haalbaar. Policy as code maakt het mogelijk om dit beleid te definiëren als machineleesbare regels die automatisch worden afgedwongen.
11.1 Open Policy Agent (OPA) en Rego
Open Policy Agent is een veelgebruikte, cloud-native policy-engine. Beleid wordt geschreven in de taal Rego en kan worden toegepast op uiteenlopende contexten: Kubernetes-admission control, API-autorisatie, of validatie van Terraform-plannen.
# Rego-beleid: verbied containers die als root draaien
package kubernetes.admission
deny[msg] {
input.request.kind.kind == "Pod"
container := input.request.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := sprintf(
"Container '%v' moet runAsNonRoot: true instellen",
[container.name]
)
}
deny[msg] {
input.request.kind.kind == "Pod"
container := input.request.object.spec.containers[_]
container.securityContext.privileged == true
msg := sprintf(
"Container '%v' mag niet in privileged-modus draaien",
[container.name]
)
}11.2 OPA Gatekeeper: afdwinging in Kubernetes
# ConstraintTemplate: definieert een herbruikbare regel
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequirenonroot
spec:
crd:
spec:
names:
kind: K8sRequireNonRoot
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequirenonroot
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := sprintf("Container %v moet runAsNonRoot instellen", [container.name])
}
---
# Constraint: past de regel toe op alle Pods in het cluster
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequireNonRoot
metadata:
name: vereis-non-root-containers
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]11.3 Policy as code in de pijplijn: Terraform-validatie
# GitLab CI: Terraform-plan valideren tegen OPA-beleid vóór apply
policy_check:
stage: security
image: openpolicyagent/conftest:latest
script:
- terraform plan -out=tfplan.binary
- terraform show -json tfplan.binary > tfplan.json
- conftest test tfplan.json --policy ./policies
rules:
- changes:
- infrastructure/**/*.tf11.4 Compliance as code
Voor organisaties die moeten voldoen aan raamwerken zoals ISO 27001, SOC 2, NIS2 of sectorspecifieke regelgeving, biedt compliance as code een manier om nalevingseisen te vertalen naar geautomatiseerde, continu gecontroleerde regels, in plaats van jaarlijkse, handmatige audits. Tools zoals Chef InSpec of Open Policy Agent kunnen infrastructuur en configuraties continu toetsen aan compliance-baselines, en de resultaten dienen als doorlopend bewijs ("continuous compliance") in plaats van een momentopname.
# InSpec-controle: vereis dat SSH-wachtwoordauthenticatie is uitgeschakeld
control 'ssh-01' do
impact 1.0
title 'SSH-wachtwoordauthenticatie moet uitgeschakeld zijn'
desc 'Alleen sleutelgebaseerde authenticatie is toegestaan volgens het hardeningsbeleid.'
describe sshd_config do
its('PasswordAuthentication') { should cmp 'no' }
end
endBegin met policy as code op een klein aantal, hoog-risico regels (bijvoorbeeld 'geen publieke opslag' en 'geen root-containers') en breid geleidelijk uit. Een overweldigende hoeveelheid regels bij de start leidt tot weerstand en workarounds.
Hoofdstuk 12 — Monitoring, logging en incident response
Zelfs de meest volwassen DevSecOps-praktijk kan niet elk incident voorkomen. Shield right — het bewaken van systemen ná deployment — is daarom net zo essentieel als shift left. Dit hoofdstuk behandelt runtime-monitoring, logging en een gestructureerde aanpak van incident response.
12.1 Wat runtime-beveiliging toevoegt
Statische en pre-deployment scans kunnen niet alles vangen: zero-day kwetsbaarheden, aanvallen die misbruik maken van legitiem gedrag, en configuratiedrift die na verloop van tijd ontstaat. Runtime-beveiligingstools monitoren het daadwerkelijke gedrag van applicaties en infrastructuur, en signaleren afwijkingen zoals ongebruikelijke netwerkverbindingen, onverwachte procesuitvoering binnen een container, of pogingen tot privilege-escalatie.
# Falco: runtime-detectieregel voor ongebruikelijke shell-activiteit in een container
- rule: Onverwachte shell in productiecontainer
desc: Detecteert het starten van een interactieve shell binnen een productiecontainer
condition: >
spawned_process and container and
container.image.repository contains "voorbeeld-app" and
proc.name in (bash, sh, zsh) and
not proc.pname in (entrypoint.sh, supervisord)
output: >
Onverwachte shell gestart in container
(container=%container.name image=%container.image.repository
process=%proc.name gebruiker=%user.name commandline=%proc.cmdline)
priority: WARNING
tags: [container, shell, runtime]12.2 Gestructureerde logging als basisvoorwaarde
Effectieve detectie begint bij goede logging. Applicaties moeten beveiligingsrelevante gebeurtenissen — inlogpogingen, autorisatiefouten, wijzigingen aan gevoelige gegevens, beheerdershandelingen — vastleggen in een gestructureerd formaat (bijvoorbeeld JSON), voorzien van consistente velden zoals tijdstip, gebruikers-ID, bron-IP en actie. Dit maakt het mogelijk om logs centraal te verzamelen, te doorzoeken en te correleren met tools zoals de ELK-stack, Grafana Loki of een SIEM-platform.
{
"tijdstip": "2026-03-14T09:22:11Z",
"gebeurtenis": "authenticatie_mislukt",
"gebruiker_id": "onbekend",
"poging_gebruikersnaam": "admin",
"bron_ip": "203.0.113.42",
"applicatie": "klantportaal-api",
"aantal_pogingen_laatste_uur": 27,
"ernst": "hoog"
}12.3 Alerting zonder alert fatigue
Een veelgemaakte fout is het genereren van te veel waarschuwingen, waardoor teams ze op den duur negeren. Effectieve alerting is gebaseerd op een duidelijke prioritering: kritieke alerts die direct menselijke actie vereisen (bijvoorbeeld actief misbruik), waarschuwingen die in een dashboard verschijnen voor periodieke review, en informatieve gebeurtenissen die alleen worden gelogd. Alerts moeten bovendien actiegericht zijn: elke alert zou een duidelijk antwoord moeten hebben op de vraag "wat moet ik nu doen?".
12.4 Incident response: een gestructureerde aanpak
Wanneer een incident zich voordoet, bepaalt de kwaliteit van de voorbereiding hoe snel en effectief een organisatie reageert. Een veelgebruikt raamwerk, gebaseerd op NIST-richtlijnen, onderscheidt zes fasen.
- Voorbereiden: draaiboeken (runbooks), contactlijsten, tooling en trainingsoefeningen zijn vooraf op orde.
- Detecteren en analyseren: het incident wordt herkend, geclassificeerd naar ernst en de omvang wordt in kaart gebracht.
- Indammen (containment): de directe schade wordt beperkt, bijvoorbeeld door getroffen systemen te isoleren.
- Uitroeien (eradication): de onderliggende oorzaak wordt weggenomen, bijvoorbeeld door een kwetsbaarheid te patchen of een gecompromitteerd account te blokkeren.
- Herstellen (recovery): systemen worden veilig teruggebracht naar normale werking, met verhoogde monitoring.
- Lessen trekken (post-mortem): een blameless evaluatie van wat er is gebeurd, wat goed ging, en welke verbeteringen nodig zijn.
12.5 Runbooks als code
Net als infrastructuur en beleid kunnen ook incidentresponsprocedures worden vastgelegd als code of gestructureerde configuratie, zodat ze consistent en (deels) geautomatiseerd kunnen worden uitgevoerd, bijvoorbeeld het automatisch isoleren van een gecompromitteerde pod.
# Voorbeeld: geautomatiseerde respons op een Falco-alert via een webhook naar Kubernetes
# Bij een kritieke alert wordt de betreffende pod automatisch geïsoleerd
# door een NetworkPolicy toe te passen die al het verkeer blokkeert.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: quarantaine-{{ POD_NAME }}
labels:
reden: automatische-incidentrespons
spec:
podSelector:
matchLabels:
app: "{{ POD_APP_LABEL }}"
policyTypes:
- Ingress
- Egress
ingress: []
egress: []Oefen incident response net zoals een brandoefening: met periodieke, aangekondigde en onaangekondigde simulaties ("game days"). Een draaiboek dat nooit is getest, faalt vaak precies op het moment dat het nodig is.
Hoofdstuk 13 — Security metrics en KPI's
Wat niet gemeten wordt, kan niet systematisch verbeterd worden. Tegelijk is het een valkuil om te veel of de verkeerde metrics bij te houden: metrics die niet tot actie leiden, zijn ruis. Dit hoofdstuk beschrijft welke metrics waardevol zijn en hoe ze te interpreteren.
13.1 Belangrijke metrics
| Metric | Wat het meet | Waarom het waardevol is |
|---|---|---|
| Mean Time To Remediate (MTTR) | Gemiddelde tijd tussen ontdekking en oplossing van een kwetsbaarheid | Toont hoe snel een team daadwerkelijk risico's wegneemt |
| Aantal kritieke bevindingen open | Actuele hoeveelheid onopgeloste kritieke risico's | Directe indicatie van blootstelling aan risico |
| Dekkingsgraad van scans | Percentage repositories/pijplijnen met actieve security-scans | Signaleert blinde vlekken in de organisatie |
| % builds geblokkeerd door security gate | Hoe vaak een gate daadwerkelijk ingrijpt | Te hoog percentage kan wijzen op te strenge regels of onderliggende problemen |
| Herhaling van bevindingen | Hoe vaak dezelfde soort fout terugkeert | Signaal voor structurele training of tooling-behoefte |
| Tijd tot patch bij nieuwe CVE | Snelheid van reactie op nieuw ontdekte kwetsbaarheden in afhankelijkheden | Belangrijk bij snel geëxploiteerde kwetsbaarheden |
13.2 Metrics gebruiken zonder perverse prikkels
Metrics kunnen ongewenst gedrag stimuleren als ze verkeerd worden ingezet. Als teams bijvoorbeeld alleen worden afgerekend op "aantal open bevindingen", ontstaat de prikkel om bevindingen te sluiten zonder ze daadwerkelijk op te lossen (bijvoorbeeld door ze te onderdrukken of als "acceptabel risico" te markeren zonder degelijke onderbouwing). Effectieve metrics worden daarom altijd in combinatie gebruikt, en het doel is trendverbetering over tijd, niet het behalen van een absoluut getal.
13.3 Dashboards en rapportage
Een goed dashboard toont metrics op het juiste detailniveau voor het juiste publiek: een team wil per repository en per sprint bevindingen zien, terwijl management een geaggregeerd, organisatiebreed beeld nodig heeft over trends en risicogebieden. Veel scanners kunnen resultaten exporteren naar gestandaardiseerde formaten zoals SARIF, die vervolgens centraal kunnen worden samengevoegd en gevisualiseerd.
# GitHub Actions: SARIF-resultaten uploaden naar de Security-tab
- name: Upload SARIF-resultaten
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: resultaten.sarif
category: sast-semgrepHoofdstuk 14 — Software supply chain security
De afgelopen jaren hebben verschillende geruchtmakende incidenten aangetoond dat aanvallers zich niet alleen richten op de applicatie zelf, maar ook op de keten eromheen: gecompromitteerde build-servers, vervalste pakketten in publieke registries, en kwaadaardige wijzigingen in veelgebruikte open source projecten. Supply chain security richt zich op het beveiligen van deze volledige keten, van broncode tot uitgerold artefact.
14.1 Software Bill of Materials (SBOM)
Een SBOM is een gestructureerde lijst van alle componenten waaruit een softwareproduct is opgebouwd, inclusief versies en licenties. Het is te vergelijken met een ingrediëntenlijst: wanneer een nieuwe kwetsbaarheid wordt ontdekt in een veelgebruikte bibliotheek, maakt een actuele SBOM het mogelijk om binnen minuten te bepalen welke systemen zijn geraakt, in plaats van dagenlang handmatig uit te zoeken. De twee meest gebruikte standaarden zijn SPDX en CycloneDX.
# GitHub Actions: SBOM genereren en als artefact bewaren bij elke release
generate-sbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Genereer SBOM met Syft
uses: anchore/sbom-action@v0.17.0
with:
format: cyclonedx-json
output-file: sbom.cyclonedx.json
- name: Bewaar SBOM als release-artefact
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.cyclonedx.json14.2 Artefacten ondertekenen en verifiëren
Het ondertekenen van build-artefacten (container-images, pakketten, binaries) maakt het mogelijk om cryptografisch te verifiëren dat een artefact daadwerkelijk afkomstig is van de verwachte, vertrouwde build-pijplijn en niet onderweg is gemanipuleerd. Sigstore, met de tool Cosign, heeft dit proces sterk vereenvoudigd door keyless signing te introduceren, gebaseerd op korte-levensduur certificaten in plaats van langlopende privésleutels die apart beheerd moeten worden.
# GitHub Actions: container-image ondertekenen met Cosign (keyless signing)
sign-image:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Installeer Cosign
uses: sigstore/cosign-installer@v3
- name: Onderteken image
run: |
cosign sign --yes
registry.voorbeeld.nl/app@${{ steps.build.outputs.digest }}
- name: Verifieer handtekening (voorbeeld bij deployment)
run: |
cosign verify
--certificate-identity-regexp "https://github.com/voorbeeld-org/.*"
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
registry.voorbeeld.nl/app@${{ steps.build.outputs.digest }}14.3 SLSA: een raamwerk voor build-integriteit
SLSA (Supply-chain Levels for Software Artifacts) is een raamwerk dat oplopende niveaus van zekerheid definieert over hoe een artefact is gebouwd: van basale herleidbaarheid tot volledig geïsoleerde, reproduceerbare builds met cryptografisch geverifieerde herkomst (provenance). Het biedt organisaties een gemeenschappelijke taal en groeipad om supply chain-risico's stap voor stap te verminderen, in plaats van in één keer een onhaalbaar hoog niveau na te streven.
14.4 Afhankelijkheden van vertrouwde bronnen
- Gebruik private package-registries of proxy's (bijvoorbeeld Artifactory of Nexus) die pakketten cachen en scannen vóórdat ze intern beschikbaar komen.
- Pin afhankelijkheden op exacte versies of cryptografische hashes in plaats van losse versiebereiken, om onverwachte, ongecontroleerde updates te voorkomen.
- Controleer periodiek op typosquatting: kwaadaardige pakketten met namen die sterk lijken op populaire, legitieme pakketten.
- Beperk wie build-pijplijnen kan wijzigen, aangezien een gecompromitteerde pijplijn de facto een compromittering van elk uitgeleverd artefact betekent.
Behandel de CI/CD-pijplijn zelf als een kritiek productiesysteem: met eigen toegangscontrole, monitoring en threat modeling. Een aanvaller die de pijplijn beheerst, hoeft de applicatie zelf niet meer aan te vallen.
Hoofdstuk 15 — Organisatie en cultuurverandering
De technische onderdelen van DevSecOps — scanners, pijplijnen, policy-engines — zijn relatief eenvoudig aan te schaffen. De werkelijke uitdaging zit in de organisatorische en culturele verandering die nodig is om deze tooling effectief te laten werken. Dit hoofdstuk bespreekt hoe organisaties deze transitie stapsgewijs kunnen doorvoeren.
15.1 Volwassenheidsmodellen
Volwassenheidsmodellen, zoals het OWASP Software Assurance Maturity Model (SAMM) of het DevSecOps Maturity Model (DSOMM), helpen organisaties objectief te bepalen waar ze staan en wat logische vervolgstappen zijn. In plaats van een vaag gevoel van "we doen al wel iets aan security", bieden deze modellen concrete niveaus per praktijkgebied (bijvoorbeeld threat modeling, testen, incident response), zodat verbetering meetbaar en gericht kan plaatsvinden.
| Volwassenheidsniveau | Kenmerken |
|---|---|
| Niveau 1 — Ad hoc | Beveiliging is reactief; scans (indien aanwezig) worden handmatig en incidenteel uitgevoerd. |
| Niveau 2 — Herhaalbaar | Basale scans zijn geautomatiseerd in de pijplijn; beleid bestaat maar wordt niet overal afgedwongen. |
| Niveau 3 — Gedefinieerd | Security gates zijn standaard; security champions zijn actief; metrics worden bijgehouden. |
| Niveau 4 — Beheerst | Policy as code wordt organisatiebreed afgedwongen; threat modeling is gestandaardiseerd; supply chain-maatregelen zijn actief. |
| Niveau 5 — Optimaliserend | Continue verbetering op basis van metrics en incidenten; security is volledig verweven in de ontwikkelcultuur. |
15.2 Begin klein, schaal bewust
Een veelgemaakte fout is het in één keer uitrollen van uitgebreide tooling en strenge policy's over de hele organisatie. Dit leidt tot weerstand, overbelaste teams en workarounds die de beveiliging juist ondermijnen. Een effectievere aanpak is het starten met een pilotteam, het aantonen van waarde met concrete resultaten, en het geleidelijk uitbreiden naar andere teams — waarbij lessen uit de pilot worden meegenomen.
15.3 Training en bewustwording
Geautomatiseerde tooling is geen vervanging voor kennis. Structurele investering in training — secure coding-workshops, threat modeling-sessies, capture-the-flag-oefeningen — verhoogt de kwaliteit van code vóórdat deze ooit een scanner bereikt. Training is het meest effectief wanneer die relevant en praktisch is: voorbeelden uit de eigen codebase werken beter dan generieke, abstracte lessen.
15.4 Samenwerking tussen teams
Structurele overlegvormen — zoals een terugkerend security-guild overleg, waarin security champions van verschillende teams kennis en ervaringen uitwisselen — houden beveiliging zichtbaar en actueel. Het security-team kan hierin een coachende rol spelen: niet als poortwachter die goedkeuring geeft, maar als expert die teams helpt zelfstandig goede beslissingen te nemen.
15.5 Leiderschap en draagvlak
Zonder zichtbare steun van management blijft DevSecOps een geïsoleerd initiatief van een handvol enthousiaste engineers. Leiderschap moet niet alleen middelen beschikbaar stellen, maar ook expliciet ruimte geven om kwaliteit boven puur leveringstempo te stellen wanneer dat nodig is — bijvoorbeeld door te accepteren dat een release wordt uitgesteld wanneer een kritieke kwetsbaarheid wordt gevonden.
Vier zichtbare successen, hoe klein ook: het aantal kritieke bevindingen dat is opgelost, een team dat zijn eerste threat model heeft afgerond, of een incident dat dankzij monitoring vroegtijdig werd ontdekt. Zichtbare erkenning versterkt de gewenste cultuur sterker dan beleidsdocumenten.
Hoofdstuk 16 — Praktijkcasus: een volledige DevSecOps-pijplijn
In dit hoofdstuk brengen we de eerdere hoofdstukken samen in één doorlopend voorbeeld: een fictieve organisatie, "Voorbeeld B.V.", die een klantportaal bouwt en uitrolt op Kubernetes. We doorlopen de volledige pijplijn, van commit tot productie, met alle besproken security gates geïntegreerd.
16.1 De architectuur
Het klantportaal bestaat uit een front-end, een backend-API, een PostgreSQL-database en draait als containers op een Kubernetes-cluster in de cloud. Code wordt beheerd in Git, en elke wijziging doorloopt de onderstaande pijplijn vóór deze in productie komt.
16.2 De volledige pijplijnconfiguratie
Onderstaande GitHub Actions-workflow combineert alle eerder besproken controles in een samenhangend geheel: bouwen en testen, statische analyse, dependency-scanning, secretsdetectie, container image-scanning, IaC-validatie, ondertekening van het artefact, en tot slot een DAST-scan tegen de staging-omgeving vóórdat een handmatige goedkeuring de productie-deployment vrijgeeft.
name: voorbeeld-bv-devsecops-pipeline
on:
pull_request:
branches: [main]
push:
branches: [main]
permissions:
contents: read
security-events: write
id-token: write
jobs:
# ---------- FASE 1: Bouwen en unit-testen ----------
build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: "20" }
- run: npm ci
- run: npm test -- --ci
# ---------- FASE 2: Statische analyse (parallel) ----------
sast:
needs: build-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: returntocorp/semgrep-action@v1
with:
config: p/owasp-top-ten p/security-audit
dependency-scan:
needs: build-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aquasecurity/trivy-action@0.24.0
with:
scan-type: "fs"
severity: "CRITICAL,HIGH"
exit-code: "1"
secrets-scan:
needs: build-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: gitleaks/gitleaks-action@v2
iac-scan:
needs: build-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: tfsec
uses: aquasecurity/tfsec-action@v1.0.3
with:
working_directory: infrastructure
# ---------- FASE 3: Bouwen, scannen en ondertekenen van image ----------
build-sign-image:
needs: [sast, dependency-scan, secrets-scan, iac-scan]
runs-on: ubuntu-latest
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v4
- id: build
run: |
docker build -t registry.voorbeeld.nl/klantportaal:${{ github.sha }} .
echo "digest=$(docker inspect --format='{{index .RepoDigests 0}}' registry.voorbeeld.nl/klantportaal:${{ github.sha }})" >> "$GITHUB_OUTPUT"
- name: Scan image
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: "registry.voorbeeld.nl/klantportaal:${{ github.sha }}"
severity: "CRITICAL,HIGH"
exit-code: "1"
- name: Genereer SBOM
uses: anchore/sbom-action@v0.17.0
with:
format: cyclonedx-json
output-file: sbom.cyclonedx.json
- run: docker push registry.voorbeeld.nl/klantportaal:${{ github.sha }}
- name: Onderteken image met Cosign
uses: sigstore/cosign-installer@v3
- run: cosign sign --yes ${{ steps.build.outputs.digest }}
# ---------- FASE 4: Deploy naar staging + DAST ----------
deploy-staging:
needs: build-sign-image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./scripts/deploy.sh staging ${{ github.sha }}
dast-scan:
needs: deploy-staging
runs-on: ubuntu-latest
steps:
- uses: zaproxy/action-baseline@v0.12.0
with:
target: "https://staging.klantportaal.voorbeeld.nl"
fail_action: true
# ---------- FASE 5: Policy-gate en productie-deployment ----------
policy-gate:
needs: dast-scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Valideer Kubernetes-manifests tegen OPA-beleid
run: conftest test ./k8s --policy ./policies
deploy-production:
needs: policy-gate
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment:
name: productie # vereist handmatige goedkeuring in GitHub-omgevingsinstellingen
steps:
- uses: actions/checkout@v4
- name: Verifieer handtekening vóór deployment
run: |
cosign verify
--certificate-identity-regexp "https://github.com/voorbeeld-bv/.*"
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
registry.voorbeeld.nl/klantportaal@${{ needs.build-sign-image.outputs.digest }}
- run: ./scripts/deploy.sh production ${{ github.sha }}16.3 Wat deze pijplijn illustreert
- Parallellisatie: de vier scanjobs in fase 2 draaien gelijktijdig, zodat de doorlooptijd beperkt blijft.
- Opeenvolgende afhankelijkheden: elke fase bouwt voort op een succesvolle vorige fase — een falende scan voorkomt dat een kwetsbaar artefact ooit wordt gebouwd, ondertekend of uitgerold.
- Defense in depth: geen enkele controle staat op zichzelf; SAST, SCA, secretsdetectie, IaC-scanning, image-scanning, DAST en policy-validatie vangen elk een ander deel van het risicospectrum.
- Herleidbaarheid: het SBOM en de digitale handtekening zorgen ervoor dat op elk moment kan worden vastgesteld waaruit een productie-artefact bestaat en dat het niet is gemanipuleerd.
- Menselijke controle op het juiste moment: een geautomatiseerde pijplijn sluit een bewuste, menselijke goedkeuring vóór productie-deployment niet uit — die blijft zinvol als laatste, weloverwogen stap.
Hoofdstuk 17 — De toekomst van DevSecOps
17.1 Kunstmatige intelligentie in beveiliging
AI-ondersteunde tools worden steeds vaker ingezet om code te reviewen, kwetsbaarheden te prioriteren op basis van daadwerkelijke exploiteerbaarheid, en zelfs geautomatiseerd fixes voor te stellen. Tegelijkertijd gebruiken aanvallers AI om phishing, social engineering en het vinden van kwetsbaarheden te versnellen. Dit betekent dat DevSecOps-praktijken moeten meebewegen: AI-gegenereerde code vereist dezelfde — zo niet strengere — controles als door mensen geschreven code, aangezien deze tools ook onveilige patronen kunnen reproduceren.
17.2 Supply chain security als blijvend zwaartepunt
Naarmate softwareketens complexer worden, zal de aandacht voor SBOM's, ondertekende artefacten en herleidbare builds (zoals in het SLSA-raamwerk) verder toenemen. Regelgeving in verschillende regio's begint dit ook actief te stimuleren of te verplichten, wat supply chain-transparantie van een "best practice" naar een nalevingsvereiste verschuift.
17.3 Policy as code en platform engineering
De opkomst van platform engineering — het bouwen van interne developer platforms die gestandaardiseerde, vooraf beveiligde bouwstenen aanbieden — maakt het mogelijk om beveiliging "by default" aan te bieden. In plaats van dat elk team zelf een veilige pijplijn moet samenstellen, biedt een centraal platformteam kant-en-klare, reeds geharde templates aan ("golden paths"), waardoor veilige keuzes de gemakkelijkste keuzes worden.
17.4 Van reactief naar voorspellend
Waar huidige tooling vooral reageert op bekende kwetsbaarheidspatronen, ontwikkelt het vakgebied zich richting meer voorspellende risicoanalyse: het combineren van code-eigenschappen, historische incidentdata en runtime-gedrag om risico's te prioriteren vóórdat ze daadwerkelijk worden misbruikt. Dit vermindert de afhankelijkheid van het handmatig doorspitten van lange lijsten met scanbevindingen.
DevSecOps is een vakgebied dat voortdurend verandert. Regelmatige bijscholing, het volgen van OWASP-projecten en het testen van nieuwe tooling in een veilige sandbox-omgeving zijn essentieel om niet achterop te raken.
Hoofdstuk 18 — Conclusie
DevSecOps is geen eindbestemming maar een doorlopende reis. Het draait om het inbouwen van beveiliging in elke fase van de softwarelevenscyclus — niet als vertragende blokkade, maar als geïntegreerd onderdeel van hoe teams werken. De belangrijkste inzichten uit dit boek laten zich samenvatten in een aantal kernboodschappen.
- Cultuur gaat vóór tooling. Zonder gedeelde verantwoordelijkheid en psychologische veiligheid leveren zelfs de beste scanners weinig op.
- Automatiseer wat herhaalbaar is, maar behoud menselijk oordeelsvermogen voor complexe, contextafhankelijke beslissingen.
- Shift left én shield right: beveiliging begint bij ontwerp en threat modeling, en eindigt nooit — ook niet na een succesvolle deployment.
- Meet wat ertoe doet, en gebruik metrics om te leren en te verbeteren, niet om af te rekenen.
- Begin klein, toon waarde, en breid vervolgens gestaag uit — grootschalige, geforceerde uitrol van tooling en beleid roept weerstand op en ondermijnt zichzelf.
- De software supply chain is onderdeel van het aanvalsoppervlak: beveilig niet alleen de applicatie, maar ook de keten die haar bouwt en uitlevert.
De concrete YAML-voorbeelden, diagrammen en checklists in dit boek zijn bedoeld als startpunt, niet als eindpunt. Elke organisatie heeft een eigen risicoprofiel, technologiestack en cultuur, en een goede DevSecOps-praktijk wordt altijd op maat doorontwikkeld. De reis begint met een eerste, kleine stap: één geautomatiseerde scan, één threat model, één gesprek tussen een ontwikkelaar en een security-specialist. Van daaruit groeit, stap voor stap, een organisatie die snelheid en veiligheid niet als tegenstelling ziet, maar als twee kanten van dezelfde medaille.
Bijlage A — Glossarium
| Term | Betekenis |
|---|---|
| CI/CD | Continuous Integration / Continuous Delivery: geautomatiseerd bouwen, testen en uitleveren van software. |
| SAST | Static Application Security Testing: analyse van broncode zonder uitvoering. |
| DAST | Dynamic Application Security Testing: testen van een draaiende applicatie van buitenaf. |
| SCA | Software Composition Analysis: scannen van open source afhankelijkheden op kwetsbaarheden. |
| IaC | Infrastructure as Code: infrastructuur gedefinieerd en beheerd als code. |
| SBOM | Software Bill of Materials: gestructureerde lijst van alle componenten in een softwareproduct. |
| Policy as code | Organisatiebeleid vastgelegd als machineleesbare, automatisch afdwingbare regels. |
| Shift left | Het naar voren halen van beveiligingsactiviteiten in de ontwikkelcyclus. |
| Shield right | Het continu bewaken en beschermen van systemen na deployment. |
| Threat modeling | Gestructureerd analyseren van mogelijke bedreigingen vóór en tijdens het ontwerp van een systeem. |
| STRIDE | Raamwerk voor het categoriseren van bedreigingen: Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege. |
| Security gate | Geautomatiseerd controlepunt in een pijplijn dat een build kan blokkeren bij een bevinding. |
| MTTR | Mean Time To Remediate: gemiddelde tijd tussen ontdekking en oplossing van een kwetsbaarheid. |
| SLSA | Supply-chain Levels for Software Artifacts: raamwerk voor build-integriteit en herleidbaarheid. |
| Secrets management | Het veilig opslaan, distribueren en roteren van gevoelige waarden zoals wachtwoorden en API-sleutels. |
| OPA | Open Policy Agent: cloud-native policy-engine, met de taal Rego. |
| SIEM | Security Information and Event Management: platform voor het centraal verzamelen en analyseren van beveiligingslogs. |
| Container escape | Een aanval waarbij een proces vanuit een container toegang krijgt tot de onderliggende hostmachine. |
| Least privilege | Het principe dat elk proces, elke gebruiker of elke service enkel de minimaal noodzakelijke rechten krijgt. |
| Zero trust | Beveiligingsmodel waarbij geen enkel verzoek standaard wordt vertrouwd, ongeacht de herkomst binnen of buiten het netwerk. |
Bijlage B — DevSecOps-checklist
B.1 Ontwerp en planning
- Is er een threat model opgesteld voor nieuwe of significant gewijzigde architectuur?
- Zijn vertrouwensgrenzen (trust boundaries) expliciet in kaart gebracht?
- Is het principe van minimale rechten toegepast in het ontwerp?
B.2 Ontwikkeling
- Is er een pre-commit hook actief voor secretsdetectie?
- Wordt alle externe invoer server-side gevalideerd?
- Bevat de pull request-template een beveiligingschecklist voor reviewers?
B.3 Build en CI
- Draait SAST bij elke pull request?
- Draait SCA/dependency-scanning bij elke build?
- Wordt een SBOM gegenereerd en bewaard bij elke release?
- Worden container-images gescand vóórdat ze naar de registry worden gepusht?
- Wordt infrastructuurcode (Terraform, Kubernetes-manifests) gescand op misconfiguraties?
B.4 Release en deployment
- Worden artefacten digitaal ondertekend en geverifieerd vóór deployment?
- Draait een DAST-scan tegen de staging-omgeving?
- Wordt policy as code afgedwongen vóór productie-deployment?
- Is er een handmatige goedkeuringsstap voor productie-releases met verhoogd risico?
B.5 Operatie en monitoring
- Is runtime-monitoring actief op productiesystemen?
- Zijn beveiligingsrelevante gebeurtenissen gestructureerd gelogd en centraal doorzoekbaar?
- Is er een actueel, geoefend incident response-draaiboek?
- Worden security-metrics periodiek gerapporteerd en besproken?
B.6 Organisatie
- Zijn er security champions actief binnen ontwikkelteams?
- Is er een blameless cultuur rondom het melden van fouten en incidenten?
- Krijgen teams structurele training in secure coding en threat modeling?
Bijlage C — Aanbevolen bronnen en tooling
C.1 Raamwerken en standaarden
- OWASP Top 10 — meest voorkomende kwetsbaarheidscategorieën in webapplicaties.
- OWASP SAMM (Software Assurance Maturity Model) — volwassenheidsmodel voor secure development.
- NIST Cybersecurity Framework en NIST SP 800-61 (incident response).
- SLSA (Supply-chain Levels for Software Artifacts).
- CIS Benchmarks — hardeningsrichtlijnen voor besturingssystemen, containers en cloud-platformen.
C.2 Veelgebruikte open source tooling per categorie
| Categorie | Voorbeelden |
|---|---|
| SAST | Semgrep, CodeQL, SonarQube |
| SCA / dependency-scanning | Trivy, Grype, OWASP Dependency-Check |
| Secretsdetectie | Gitleaks, TruffleHog |
| IaC-scanning | tfsec, Checkov, Terrascan |
| Container image-scanning | Trivy, Grype, Clair |
| DAST | OWASP ZAP, Nuclei |
| Policy as code | Open Policy Agent (OPA), Conftest, Kyverno |
| Runtime-beveiliging | Falco, Tetragon |
| Supply chain / ondertekening | Sigstore/Cosign, Syft (SBOM), in-toto |
| Threat modeling | OWASP Threat Dragon, pytm |
Dit e-book biedt een startpunt voor de implementatie van DevSecOps binnen een organisatie. Voor verdieping op specifieke onderwerpen wordt aangeraden de documentatie van bovenstaande tools en raamwerken te raadplegen, aangezien deze voortdurend worden bijgewerkt met nieuwe functionaliteit en richtlijnen.