Var fjärde säkerhetsincident i molnet under första kvartalet 2026 gick tillbaka till en felkonfigurerad resurs, inte till en avancerad attack. Enligt Verizons Data Breach Investigations Report 2026 stod molnfelkonfiguration för 14 procent av alla globala dataintrång under kvartalet, upp från 9 procent 2024. Det gör felkonfiguration till den vanligaste tekniska vägen in i produktionsmiljöer, före både nätfiske och sårbara applikationer. Ett av de tydligaste exemplen är intrånget hos rekryteringsplattformen TalentHook, där mer än 26 miljoner CV:n exponerades efter en felkonfigurerad molnresurs.

Problemet sitter sällan i själva molnkontot. Det sitter i koden som byggde det. De flesta team i Sverige och Norden kör i dag sin infrastruktur som Terraform-filer, granskar dem i pull requests och applicerar dem automatiskt via CI/CD. Om ingen läser Terraform-koden med samma noggrannhet som applikationskoden slinker fel som öppna säkerhetsgrupper, överprivilegierade IAM-roller och oskyddade S3-bucketar rakt igenom till produktion. Den här guiden visar hur du bygger en skanningspipeline för Terraform med Trivy, Checkov, Terrascan och OPA/Conftest, steg för steg, med kommandon du kan köra direkt.

Sveriges Cybersäkerhetslag, som implementerar NIS2-direktivet (EU 2022/2555), trädde i kraft den 15 januari 2026 och skärpte kraven på riskhantering och incidentrapportering för väsentliga och viktiga verksamheter. Att fånga felkonfigurationer innan de når produktion, i stället för att upptäcka dem efter en incident, är precis den typen av förebyggande kontroll lagen efterfrågar. Guiden nedan är byggd för utvecklare och säkerhetsansvariga som redan använder Terraform men ännu inte har en automatiserad kontroll av vad koden faktiskt bygger.

Sverige har också höjt sin totala satsning på cyberförsvar under 2026. I den föreslagna försvarsbudgeten för året finns cirka 0,37 miljarder kronor öronmärkta specifikt för förstärkt cybersäkerhet, av en total försvarsbudget på ungefär 49,83 miljarder kronor. Pengarna går i första hand till nationell infrastruktur, men trycket sprider sig neråt i kedjan: leverantörer och underleverantörer till offentlig sektor möter allt oftare krav på att visa upp konkreta tekniska kontroller, inte bara policydokument. En Terraform-pipeline som stoppar farliga ändringar automatiskt är ett av de enklaste sätten att uppfylla den typen av krav utan att lägga till ett helt nytt team.

Vad är IaC-säkerhetsskanning och varför Terraform behöver det

Infrastructure as Code, IaC, betyder att du beskriver servrar, nätverk och behörigheter som textfiler i stället för att klicka ihop dem i en molnkonsol. Terraform är det mest använda verktyget för det i Norden, och filerna (.tf) blir en exakt ritning över hela din molnmiljö. Fördelen är spårbarhet och repeterbarhet. Nackdelen är att ett fel i ritningen kopieras till varje miljö du applicerar den mot, ofta utan att någon märker det förrän en säkerhetsgranskning eller ett intrång avslöjar det.

IaC-säkerhetsskanning är statisk analys av Terraform-koden innan den appliceras. Verktyget läser filerna, jämför dem mot ett regelbibliotek och flaggar mönster som brukar leda till intrång: en S3-bucket utan kryptering, en säkerhetsgrupp som tillåter trafik från 0.0.0.0/0 på port 22, en IAM-policy med wildcard-behörigheter, eller en EC2-instans som kör den äldre och sårbara metadatatjänsten IMDSv1. Skillnaden mot verktyg som AWS Security Hub eller Prowler är tidpunkten. De granskar en miljö som redan körs. IaC-skanning stoppar felet innan terraform apply ens körs, vilket är billigare och betydligt snabbare att åtgärda.

En analys av molnsäkerhetsincidenter 2024–2025 pekar på att överprivilegierade identitetsbehörigheter var en bidragande faktor i så mycket som 75 procent av granskade molnintrång. De flesta av dessa behörigheter skapades via IaC, ofta genom att någon kopierade en fungerande IAM-policy från ett annat projekt utan att strama åt den. Det är exakt den typen av fel en skanner fångar på några sekunder, långt innan koden når en produktionsmiljö full av kunddata.

En annan vanlig källa till fel är återanvända Terraform-moduler från den publika registret. Att bygga vidare på en modul någon annan redan skrivit sparar tid, men om modulen skapades för ett annat syfte kan den bära med sig standardinställningar som aldrig var tänkta att hamna i en miljö med känslig data, till exempel en publikt nåbar databas för att göra det enkelt att testa modulen lokalt. En skanner bryr sig inte om varifrån koden kommer. Den flaggar felkonfigurationen oavsett om du skrev raden själv eller ärvde den från en modul med tio tusen nedladdningar.

Förutsättningar: detta behöver du innan du börjar

Du behöver inte en stor molnmiljö för att följa den här guiden. Allt kan köras lokalt mot testfiler, och inget av verktygen kräver att du faktiskt applicerar infrastruktur mot ett skarpt konto. Så här ser verktygslistan ut, med de versioner som var aktuella i skrivande stund.

VerktygVersion (sep 2026)Syfte i pipelinenInstallationObligatoriskt?
Terraformv1.16.1Skriva och applicera infrastrukturkodHashiCorp-paket eller tfenvJa
Trivyv0.74.0Snabb IaC-skanning, ersätter tfsecBinär, Homebrew eller aptJa
Checkov3.3.16Djupare compliance-kontrollerpip install checkovJa
Terrascanv1.19.9Policy-driven skanning, OPA-baseradBinär från GitHub ReleasesValfritt
OPA / Conftestv1.20.2Egna policyer i RegoBinär från OPA-projektetValfritt
pre-commit4.6.2Köra skanning lokalt före commitpip install pre-commitRekommenderat
Git och ett GitHub-kontosenasteVersionshantering och CI/CDJa

Du behöver också grundläggande kunskap om hur en .tf-fil ser ut och tillgång till en terminal med bash eller zsh. Allt i guiden testades på Linux, men kommandona fungerar identiskt på macOS. På Windows kör du dem enklast via WSL2. Räkna med cirka 90 minuter för att gå igenom samtliga tolv steg, inklusive tid för att läsa skanningsresultaten och förstå varför varje regel slår till.

Verktygslandskapet 2026: tfsec, Trivy, Checkov, Terrascan och OPA jämförda

Terrängen har förändrats sedan tfsec var förstahandsvalet för Terraform-skanning. Aqua Security flyttade tfsecs regelmotor in i Trivy redan 2023, och sedan 2024 är IaC-skanningen fullt konsoliderad i kommandot trivy config. Under 2026 är tfsec i praktiken i underhållsläge: projektet får säkerhetsfixar men inga nya regler, vilket betyder att team som fortfarande bygger sin pipeline runt tfsec skannar mot ett regelbibliotek som slutat växa. Rekommendationen för nya projekt är att börja med Trivy config i stället.

Checkov löser ett delvis annat problem. Där Trivy är snabbt och bra på att hitta uppenbara fel, är Checkov starkare på regelefterlevnad och har fler inbyggda kontroller mot ramverk som CIS Benchmarks och PCI DSS. Terrascan bygger, precis som Conftest, på Open Policy Agent och Rego-språket, vilket gör det till förstahandsvalet om du redan har investerat i OPA för Kubernetes-policyer och vill återanvända samma kompetens för Terraform. Den praktiska rekommendationen för 2026 är att kombinera dem: Trivy eller tfsec för snabb statisk analys i varje commit, Checkov för djupare kontroller vid pull request, och OPA/Conftest för organisationsspecifika regler som inget färdigt verktyg täcker.

VerktygStatus 2026MotorStyrkaCI/CD-integration
tfsecUnderhållsläge, inga nya reglerEgen (Go)Snabb, enkel att komma igång medGitHub Actions, GitLab CI
Trivy configAktiv, tar över tfsecs reglerEgen (Go), byggd på tfsec-arvetBred täckning, en binär för allt (containers, IaC, SBOM)Alla större CI-plattformar
CheckovAktiv, stort communityPythonDjup compliance-mappning, SARIF-exportGitHub Security, GitLab, Jenkins
TerrascanAktivOPA/RegoPolicy-som-kod, återanvänder Rego-reglerGitHub Actions, Azure DevOps
OPA / ConftestAktiv, bred användning utanför TerraformRegoFullt anpassningsbara reglerAlla, via CLI-anrop

Utöver de öppna verktygen finns även kommersiella alternativ som Snyk IaC och Wiz, som erbjuder samma typ av statisk analys men paketerat med instrumentpaneler, prioritering baserad på faktisk molnexponering och support. De är värda att överväga när ett team växer förbi vad en handfull öppna verktyg och egna skript klarar av att underhålla, men startkostnaden och licensavgiften gör dem mindre lämpade som första steg för ett enskilt team som bara vill komma igång. Den här guiden fokuserar därför på de öppna alternativen, som täcker samma grundbehov utan någon licenskostnad alls.

IaC-skanning kontra runtime-skanning: så kompletterar de varandra

Ett vanligt missförstånd är att tro att IaC-skanning gör verktyg som Prowler för AWS, Azures inbyggda IAM-granskning eller GCP Security Command Center överflödiga. Det stämmer inte. De löser olika delar av samma problem och bör köras parallellt, inte som ersättning för varandra. IaC-skanning läser koden innan den appliceras och kan bara se det som faktiskt står i dina .tf-filer. Runtime-verktyg granskar den levande miljön och fångar därför även sådant som skapats manuellt i en molnkonsol, ändrats av en engångsscript, eller drivit iväg från sitt ursprungliga IaC-tillstånd över tid, ett fenomen som brukar kallas konfigurationsdrift.

Praktiskt betyder det att en organisation med en mogen säkerhetsprocess kör båda lagren samtidigt. IaC-skanningen stoppar de flesta felen redan i pull request-fasen, vilket är billigast och snabbast att åtgärda. Runtime-skanningen fångar sedan upp allt som ändå slinker igenom, antingen för att någon applicerade en ändring manuellt utanför pipelinen, eller för att en resurs skapades innan skanningen infördes. Om du redan har satt upp Prowler för din AWS-miljö eller Azures IAM- och Storage-granskning, är nästa naturliga steg i mognadstrappan att lägga till IaC-skanningen som beskrivs i den här guiden, snarare än att välja det ena framför det andra.

Steg 1–3: Sätt upp testmiljön och kör din första skanning

Steg 1: Skapa en testmapp med en medvetet sårbar Terraform-fil

Skapa en mapp och en main.tf med några klassiska felkonfigurationer, så att du har något konkret att skanna mot innan du rör din riktiga infrastruktur.

mkdir iac-skanning-demo && cd iac-skanning-demo

cat > main.tf << 'EOF'
resource "aws_s3_bucket" "logs" {
  bucket = "mitt-foretag-loggar"
}

resource "aws_security_group" "web" {
  name = "web-sg"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_iam_policy" "admin_all" {
  name = "full-access"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Action   = "*"
      Resource = "*"
    }]
  })
}
EOF

Filen innehåller tre vanliga fel: en S3-bucket utan kryptering eller åtkomstblockering, en säkerhetsgrupp som öppnar SSH mot hela internet, och en IAM-policy med fullständig wildcard-behörighet. Alla tre dyker regelbundet upp i verkliga granskningar.

Steg 2: Installera Trivy

På Linux och macOS installerar du Trivy via det officiella installationsskriptet eller din pakethanterare.

# Debian/Ubuntu
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# macOS
brew install trivy

# Verifiera installationen
trivy --version

Steg 3: Kör din första skanning med Trivy config

Peka Trivy mot mappen med Terraform-koden. Kommandot heter config, ett arv från tiden då Trivy bara skannade containerimages och IaC-stödet lades till som ett separat kommando.

trivy config .

Ett typiskt utdatafönster ser ut ungefär så här, med tre fynd som matchar de tre felen du la in i steg 1:

main.tf (terraform)

Tests: 24 (SUCCESSES: 21, FAILURES: 3)
Failures: 3 (HIGH: 2, CRITICAL: 1)

CRITICAL: Security group allows ingress from 0.0.0.0/0 on port 22
HIGH: S3 bucket does not have encryption enabled
HIGH: IAM policy grants full administrative privileges

Lägg märke till att Trivy räknar 24 tester totalt och bara flaggar tre. Det är en poäng värd att komma ihåg: de flesta reglerna i regelbiblioteket handlar om saker du redan gör rätt. Skanningen är till för att fånga undantagen, inte för att döma hela filen.

Steg 4–6: Tolka resultat och åtgärda de vanligaste felkonfigurationerna

Steg 4: Installera och kör Checkov

Checkov är skrivet i Python och installeras enklast via pip. Verktyget har ett bredare regelbibliotek än Trivy när det gäller mappning mot specifika compliance-ramverk.

pip install checkov

# Skanna hela mappen
checkov -d .

# Skanna en enskild fil
checkov -f main.tf

Checkov ger dig ofta fler fynd än Trivy på samma fil, eftersom regelbiblioteket är större och mer finkornigt. Det är inte ett tecken på att Trivy missar saker, utan på att verktygen prioriterar delvis olika saker. Kör gärna båda och slå ihop resultaten i början, tills du har en känsla för vilka regler som är relevanta för just din miljö.

Steg 5: Läs och prioritera skanningsresultaten

Ett vanligt nybörjarmisstag är att försöka fixa allt på en gång. Sortera i stället fynden efter allvarlighetsgrad och exponering. En öppen SSH-port mot hela internet är alltid kritisk. En saknad tagg för kostnadsuppföljning är sällan det. Bygg en enkel prioriteringsordning: kritiska nätverksexponeringar först, sedan identitets- och behörighetsfel, därefter kryptering i vila, och sist kosmetiska regler som namnstandarder.

Steg 6: Åtgärda överprivilegierad IAM och IMDSv1

Byt ut wildcard-policyn mot specifika handlingar och resurser, och tvinga fram IMDSv2 på varje EC2-instans du hanterar, eftersom den äldre metadatatjänsten IMDSv1 är ett känt mål för SSRF-attacker som kan användas för att stjäla tillfälliga AWS-nycklar.

resource "aws_iam_policy" "s3_read_only" {
  name = "s3-read-only-logs"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Action   = ["s3:GetObject", "s3:ListBucket"]
      Resource = ["arn:aws:s3:::mitt-foretag-loggar/*"]
    }]
  })
}

resource "aws_instance" "app" {
  ami           = "ami-0123456789abcdef0"
  instance_type = "t3.micro"

  metadata_options {
    http_tokens   = "required"  # tvingar IMDSv2
    http_endpoint = "enabled"
  }
}

Kör om trivy config . efter ändringen. Antalet fynd ska sjunka från tre till noll om du åtgärdat alla tre ursprungliga fel korrekt.

Steg 7–9: Skanna planer, generera SARIF och bygg en CI/CD-pipeline

Steg 7: Skanna Terraform-planer, inte bara källkod

Källkodsskanning missar fel som bara syns när Terraform faktiskt räknar ut vad som ska hända, till exempel värden som sätts via variabler eller moduler. Skanna därför även den genererade planen.

terraform init
terraform plan -out=plan.tfplan
terraform show -json plan.tfplan > plan.json
checkov -f plan.json --framework terraform_plan

Den här metoden fångar exakt det som kommer att appliceras, med alla variabler och moduler upplösta, vilket gör den till ett bra komplement till den statiska skanningen av källkoden.

Steg 8: Generera SARIF-rapporter för GitHub Security

SARIF är ett standardformat som gör att skanningsresultat visas direkt i GitHubs säkerhetsflik, bredvid Dependabot- och CodeQL-varningar, i stället för att begravas i en byggloggfil ingen läser.

checkov -d . --output sarif > results.sarif

Ladda upp filen med actionen github/codeql-action/upload-sarif i din pipeline, som visas i nästa steg, så dyker fynden upp automatiskt för hela teamet utan att någon behöver leta efter dem manuellt.

Steg 9: Bygg en GitHub Actions-pipeline

Sätt ihop stegen ovan till ett arbetsflöde som körs vid varje pull request och blockerar merge om kritiska fel hittas.

name: iac-skanning

on:
  pull_request:
    paths:
      - '**.tf'

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Trivy config-skanning
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: config
          scan-ref: .
          severity: CRITICAL,HIGH
          exit-code: 1

      - name: Checkov-skanning med SARIF
        run: |
          pip install checkov
          checkov -d . --output sarif > results.sarif
        continue-on-error: true

      - name: Ladda upp till GitHub Security
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

Lägg märke till exit-code: 1 på Trivy-steget. Det är det som faktiskt stoppar en pull request från att mergas när ett kritiskt fel finns kvar, och skiljer en pipeline som bara rapporterar från en som verkligen blockerar dåliga ändringar.

Kör ni GitLab i stället för GitHub fungerar samma princip, bara med annan syntax. Nedan är en motsvarande jobbdefinition för .gitlab-ci.yml som stoppar pipelinen vid kritiska fynd på samma sätt.

iac-skanning:
  stage: test
  image: aquasec/trivy:latest
  script:
    - trivy config --exit-code 1 --severity CRITICAL,HIGH .
  rules:
    - changes:
        - "**/*.tf"

Steg 10–12: Policy-som-kod, pre-commit och uppföljning

Steg 10: Lägg till egna policyer med OPA och Conftest

Färdiga regler täcker det mesta, men varje organisation har egna krav, till exempel att alla S3-bucketar måste ha en specifik tagg eller att inga resurser får skapas i en region utanför EU. Sådana regler skriver du själv i Rego och kör med Conftest.

package main

deny[msg] {
  resource := input.resource_changes[_]
  resource.type == "aws_s3_bucket"
  not resource.change.after.tags.miljo
  msg := sprintf("S3-bucket %s saknar obligatorisk tagg 'miljo'", [resource.name])
}

deny[msg] {
  resource := input.resource_changes[_]
  resource.type == "aws_instance"
  resource.change.after.availability_zone != "eu-north-1a"
  resource.change.after.availability_zone != "eu-north-1b"
  msg := sprintf("Instans %s skapas utanför godkänd EU-region", [resource.name])
}

Kör policyn mot samma plan.json som du redan genererade i steg 7: conftest test plan.json. Den här typen av regel är exakt vad som skiljer ett generiskt skanningsverktyg från en pipeline anpassad efter er egen efterlevnadspolicy.

Steg 11: Installera pre-commit-hooks lokalt

Att fånga fel i CI är bra, men att fånga dem innan koden ens committas är bättre, eftersom utvecklaren fortfarande har hela kontexten i huvudet.

pip install pre-commit

cat > .pre-commit-config.yaml << 'EOF'
repos:
  - repo: local
    hooks:
      - id: trivy-config
        name: Trivy IaC-skanning
        entry: trivy config --exit-code 1 .
        language: system
        pass_filenames: false
EOF

pre-commit install

Från och med nu körs skanningen automatiskt varje gång någon i teamet försöker skapa en commit, och en commit med kritiska fel stoppas innan den ens når din lokala Git-historik.

Steg 12: Mät och följ upp med baseline-filer

När du inför skanning i ett befintligt projekt hittar du sannolikt hundratals fynd på en gång. Att kräva att alla åtgärdas innan pipelinen kan användas dödar oftast hela initiativet. Skapa i stället en baseline som fryser dagens kända fel och bara blockerar nya.

checkov -d . --create-baseline
# Skapar .checkov.baseline med dagens kända fynd

checkov -d . --baseline .checkov.baseline
# Flaggar bara NYA fynd jämfört med baseline

Sätt ett mål, till exempel att baseline-filen ska krympa med 10 procent varje kvartal, och följ upp det i samma forum där ni redan pratar om annan teknisk skuld.

Skala upp: flera team, repon och molnkonton

Att få skanningen att fungera i ett enda repo är en sak. Att rulla ut den till tjugo team med egna Terraform-repon och olika mognadsnivå är en annan utmaning helt. Det första steget är att bestämma vem som äger regeluppsättningen centralt. Utan en tydlig ägare hamnar varje team i sin egen tolkning av vad som räknas som kritiskt, vilket gör resultaten svåra att jämföra mellan projekt och nästan omöjliga att rapportera samlat till ledningen.

Ett fungerande mönster är att en central plattform- eller säkerhetsfunktion äger en delad konfigurationsfil, till exempel .checkov.yaml och Rego-policyerna, i ett eget repo. Varje teams pipeline hämtar den filen vid körning i stället för att kopiera in en egen variant. Det gör det möjligt att skärpa en regel för hela organisationen med en enda ändring, samtidigt som enskilda team fortfarande kan lägga till egna, projektspecifika undantag lokalt. Många organisationer inför dessutom en enkel eskalationsmodell: nya regler börjar i "endast varna"-läge i några veckor så att team hinner åtgärda befintliga fynd, innan regeln växlas till att faktiskt blockera merge.

Mät framstegen på organisationsnivå, inte bara per repo. Ett enkelt mått är andelen repon som har skanning aktiverad i sin pipeline, ett annat är det totala antalet öppna kritiska fynd över tid. Båda måtten är lätta att förstå för en säkerhetschef som inte själv skriver Terraform, och båda går att generera automatiskt genom att samla Checkovs SARIF-utdata från samtliga repon i en central instrumentpanel.

Fem vanliga fallgropar vid IaC-skanning

  • Att blockera allt från dag ett. Ett befintligt projekt med hundratals fynd blir omöjligt att jobba med om pipelinen stoppar varje pull request direkt. Använd baseline-filer och trappa upp kraven gradvis.
  • Att bara skanna källkod, aldrig planen. Fel som uppstår genom variabler och moduler syns inte förrän du kör terraform plan, vilket gör att rena källkodsskanningar missar en del av de allvarligaste felen.
  • Att lita på ett enda verktyg. Trivy, Checkov och Terrascan har delvis olika regelbibliotek. Ett fel som ett verktyg missar fångas ofta av ett annat, särskilt under de första månaderna.
  • Att ignorera SARIF-integrationen. Fynd som bara syns i en byggloggfil läses sällan. Utan SARIF-uppladdning till GitHub Security försvinner varningarna i praktiken efter att pipelinen körts klart.
  • Att glömma bort tfsecs status. Team som fortsatte bygga sin pipeline runt tfsec efter 2024 skannar mot ett regelbibliotek som slutat växa, eftersom projektet numera bara får säkerhetsfixar och inga nya regler.

Felsökning: åtta vanliga problem och lösningar

  • "command not found: trivy" efter installation. Binären hamnade sannolikt inte i din PATH. Kör echo $PATH och kontrollera att /usr/local/bin finns med, eller flytta binären dit manuellt.
  • Checkov hittar noll resurser i en mapp full av .tf-filer. Kontrollera att du kör kommandot i mappen som innehåller filerna, inte en nivå ovanför, och att filerna faktiskt har ändelsen .tf och inte .tf.txt.
  • "terraform show -json" ger ett tomt resultat. Du har troligen glömt -out=plan.tfplan i terraform plan-steget. Utan den flaggan skriver Terraform bara planen till skärmen, inte till en fil som kan konverteras.
  • Pipelinen blockerar allt, även gamla, redan godkända resurser. Skapa en baseline-fil enligt steg 12 innan du sätter exit-code: 1 i CI, annars stoppas varje pull request av historiska fynd.
  • SARIF-filen laddas upp men inget syns i GitHub Security. Kontrollera att repot faktiskt har GitHub Advanced Security eller motsvarande aktiverat för privata repon, och att jobbet har behörigheten security-events: write.
  • Conftest hittar policyfilen men kör inga regler. Rego-paketet i filen måste heta main om du inte anger ett annat namespace explicit med --namespace när du kör kommandot.
  • Trivy och Checkov ger motstridiga resultat på samma resurs. Det är förväntat, eftersom regelbiblioteken skiljer sig åt. Dokumentera vilket verktyg som är "sanningen" för er organisation i tveksamma fall, eller kräv att båda ska godkänna innan merge.
  • pre-commit-hooken tar för lång tid och stör utvecklarflödet. Begränsa hooken till att bara köra mot ändrade filer med pass_filenames: true i stället för att skanna hela repot vid varje commit.

Avancerat: anpassade regler och undantagshantering

När grundskanningen är på plats uppstår snabbt behovet av undantag. Ett testkonto kan behöva en bredare säkerhetsgrupp än produktion, eller en tillfällig resurs kan sakna en tagg av goda skäl. Både Trivy och Checkov stödjer inline-undantag direkt i koden, vilket är att föredra framför att stänga av en regel globalt.

# checkov:skip=CKV_AWS_24:SSH öppet endast i testmiljön, tidsbegränsat till 2026-12-31
resource "aws_security_group" "test_only" {
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Kravet bör vara att varje undantag har en kommentar med motivering och helst ett datum, så att en granskning sex månader senare inte behöver gissa varför regeln stängdes av. Ett vanligt mönster är att låta CI räkna antalet aktiva undantag och larma om siffran stiger, i stället för att bara acceptera att listan växer i det tysta.

För organisationer med flera molnkonton är nästa steg att centralisera policyerna i ett eget Git-repo och låta varje projekts pipeline hämta reglerna därifrån vid körning, snarare än att kopiera samma .checkov.yaml-fil till tjugo olika repon. Det gör det möjligt att uppdatera en regel på ett ställe och få den att gälla överallt vid nästa pipeline-körning.

Olika miljöer bör dessutom ha olika strikthet. En testmiljö som bara existerar i några timmar behöver inte samma nivå av kontroll som en produktionsmiljö med kunddata, men den bör ändå ha ett minimiskydd mot de allra allvarligaste felen. Ett vanligt mönster är att köra samma regelbibliotek överallt, men bara sätta exit-code: 1, det vill säga faktisk blockering, för pipelines kopplade till produktionsgrenar. Testmiljöer kör då samma skanning i "rapportera men blockera inte"-läge, vilket ger utvecklare insyn i sina fel utan att bromsa den snabba iterationen en testmiljö är till för.

Komplett exempelprojekt: från källkod till skyddad pipeline

Så här ser mappstrukturen ut när alla tolv steg är ihopsatta till ett fungerande projekt du kan klona och bygga vidare på.

iac-skanning-demo/
├── main.tf                       # Terraform-resurserna
├── .checkov.yaml                 # Checkov-konfiguration och undantag
├── .checkov.baseline              # Frysta, kända fynd
├── .pre-commit-config.yaml        # Lokal skanning före commit
├── policy/
│   └── main.rego                  # Egna OPA/Conftest-regler
└── .github/
    └── workflows/
        └── iac-skanning.yml       # CI/CD-pipeline med Trivy + Checkov + SARIF

Med den strukturen på plats har du tre skyddslager som kompletterar varandra. Pre-commit-hooken fångar de enklaste felen innan koden lämnar din dator. Pull request-pipelinen i GitHub Actions kör en bredare skanning med både Trivy och Checkov och blockerar merge vid kritiska fynd. OPA/Conftest-policyerna fångar organisationsspecifika krav som inget färdigt verktyg känner till. Ingen av delarna ersätter de andra, och det är just kombinationen som gör pipelinen svår att kringgå av misstag.

Håll verktygen uppdaterade utan att pipelinen bryts

Ett regelbibliotek som aldrig uppdateras blir snabbt värdelöst, eftersom nya molntjänster och nya attackmönster tillkommer varje kvartal. Samtidigt kan en okontrollerad uppgradering av Trivy eller Checkov plötsligt aktivera tiotals nya regler över en natt och stoppa varje pull request i hela organisationen. Lösningen är att pinna versionerna explicit i din pipeline, precis som du redan gör med andra beroenden, och uppgradera medvetet i stället för att alltid dra den absolut senaste versionen automatiskt.

# Pinna exakt version i GitHub Actions
- name: Trivy config-skanning
  uses: aquasecurity/[email protected]
  with:
    scan-type: config

# Pinna Checkov via requirements.txt
echo "checkov==3.3.16" >> requirements.txt
pip install -r requirements.txt

Skapa en rutin, till exempel en gång i månaden, för att testa den senaste versionen i en separat gren innan du uppdaterar produktionens pipeline. Läs igenom ändringsloggen för nya regler, och lägg de som är relevanta för er miljö i "varna men blockera inte"-läge under en övergångsperiod innan de får full blockerande effekt. Det håller pipelinen förutsägbar samtidigt som ni ändå får nytta av nya kontroller när de väl är redo att användas skarpt.

Så mappar du fynd mot NIS2 och Cybersäkerhetslagen

Sveriges Cybersäkerhetslag kräver att väsentliga och viktiga verksamheter kan visa att de har processer för riskhantering, inte bara att de råkar sakna kända sårbarheter för stunden. Att koppla varje skanningsregel till ett etablerat ramverk gör det enklare att visa upp arbetet vid en revision eller tillsyn, i stället för att förklara varje enskilt verktygsval från grunden.

FelkonfigurationNIST CSF 2.0Cloud Controls MatrixPCI DSS v4
Överprivilegierad IAM-policyPR.AA-05IAM-057.2
IMDSv1 aktiverat på instansPR.PS-01IVS-042.2
Hemligheter inbäddade i imagesPR.DS-01, PR.PS-01DSP-173.5
Okrypterad lagring i vilaPR.DS-01DSP-173.5
Publikt exponerad S3-bucketPR.AA-05IAM-057.2
Saknad loggning på nätverksresursPR.PS-01IVS-0410.2

Ett praktiskt tips är att lägga in kolumnen "kontrollreferens" direkt i din baseline-fil eller i kommentarerna kring varje undantag. Då slipper ni bygga om hela mappningen manuellt inför nästa revision, och ni kan visa direkt vilken kod som stänger vilken kontrollpunkt i ramverket ni rapporterar mot.

Den här typen av SSRF-relaterad risk handlar inte bara om molnets metadatatjänst. Under 2026 dokumenterades till exempel CVE-2026-42339, en SSRF-sårbarhet i AI-gatewayen New API (version 0.11.9-alpha.1 och tidigare), där en autentiserad användare med låga rättigheter kunde gå från blind SSRF till fullständig läsning mot interna tjänster via produktens AWS Bedrock-integration. Tidigare patchar i version 0.9.0.5 och 0.9.6 stängde liknande hål men missade att blockera adressen 0.0.0.0, vilket visar att SSRF-skydd måste testas mot fler adressformat än bara de mest uppenbara. Samma princip gäller din Terraform-kod: IMDSv2-tvång på instansnivå är precis den typen av kontroll som stoppar en SSRF-sårbarhet från att eskalera till stulna molnuppgifter.

Checklista: verifiera pipelinen innan lansering

Innan du kopplar in exit-code: 1 mot huvudgrenen och låter pipelinen börja blockera riktiga pull requests, är det värt att gå igenom en kort checklista. Ett fel här kostar mycket mer tid att felsöka i efterhand än att kontrollera i förväg, särskilt om hela teamet plötsligt blockeras från att merga kod en fredag eftermiddag.

  1. Kör skanningen manuellt mot ett representativt repo och bekräfta att antalet fynd känns rimligt, varken noll (vilket kan betyda att skanningen inte hittar filerna) eller flera hundra utan sammanhang.
  2. Testa baseline-flödet genom att medvetet introducera ett nytt fel och bekräfta att det flaggas, samtidigt som de gamla, redan kända felen i baseline-filen fortsätter passera.
  3. Verifiera att SARIF-filen faktiskt syns i GitHub Security-fliken efter en testkörning, inte bara att jobbet i pipelinen går grönt.
  4. Bekräfta att ett kritiskt fynd faktiskt blockerar merge-knappen i en testad pull request, inte bara att jobbet rapporterar ett fel i loggen.
  5. Låt minst en kollega som inte byggt pipelinen testa flödet från början, inklusive hur de hanterar ett falskt positivt fynd med ett inline-undantag.
  6. Dokumentera vem som är kontaktperson när pipelinen blockerar något oväntat, så att inte hela teamet står stilla i väntan på svar.

När samtliga sex punkter är avklarade är pipelinen redo att sättas i skarpt läge mot huvudgrenen. Många team väljer att köra i "varna men blockera inte"-läge i en till två veckor innan de aktiverar full blockering, vilket ger tid att fånga upp överraskningar utan att stoppa leveranser i onödan.

Vanliga frågor

Måste jag välja mellan Trivy och Checkov, eller kan jag köra båda?
Du kan och bör köra båda. De har delvis olika regelbibliotek, och ett fel som ett verktyg missar fångas ofta av det andra. Många team kör Trivy i pre-commit-hooken för snabb feedback och Checkov i CI för en djupare kontroll vid pull request.

Fungerar samma skanningsverktyg för Azure och GCP, eller bara AWS?
Både Trivy och Checkov stödjer resurser för AWS, Azure och Google Cloud i samma regelbibliotek. Kommandona i den här guiden fungerar identiskt oavsett molnleverantör, det är bara resurstyperna i main.tf som skiljer sig.

Är tfsec fortfarande värt att använda 2026?
Tfsec fungerar fortfarande och tar emot säkerhetsfixar, men projektet får inga nya regler eftersom regelmotorn flyttades in i Trivy. Nya projekt bör starta direkt med trivy config i stället för att bygga en pipeline runt ett verktyg som slutat växa.

Hur hanterar jag falska positiva utan att stänga av en hel regel?
Använd inline-undantag som checkov:skip direkt i koden, med en kommentar som förklarar varför och gärna ett datum. Det ger spårbarhet utan att regeln försvinner globalt för hela projektet.

Räcker IaC-skanning för att uppfylla Cybersäkerhetslagens krav?
Nej. IaC-skanning täcker en del av kraven på riskhantering och förebyggande kontroller, men lagen kräver även incidentrapportering, kontinuitetsplanering och leverantörskedjesäkerhet som ligger utanför det här verktygets räckvidd. Se det som ett lager bland flera, inte en helhetslösning.

Kan jag köra dessa verktyg mot Terragrunt eller bara ren Terraform?
Både Trivy och Checkov skannar den genererade Terraform-koden oavsett om den kommer från Terragrunt, Terraform Cloud-moduler eller ren HCL. Kör skanningen mot den mapp där de faktiska .tf-filerna finns, eller mot den genererade planen enligt steg 7.

Hur ofta bör baseline-filen uppdateras?
Sätt en rutin för att granska och krympa baseline-filen varje kvartal, kopplat till samma möte där ni går igenom annan teknisk skuld. En baseline som bara växer och aldrig krymper har i praktiken slutat fungera som ett skyddslager.

Behöver jag OPA/Conftest om jag redan kör Checkov?
Inte nödvändigtvis. Checkov stödjer egna Python-baserade regler också. OPA/Conftest är mest värt investeringen om ni redan använder Rego för Kubernetes-policyer och vill återanvända samma språk och kompetens för Terraform.