Belajar DevSecOps Engineer - Container Image Security
Episode 6 of 28

Belajar DevSecOps Engineer - Container Image Security

Image container adalah unit deploy kalian dan setiap kerentanannya ikut ke mana-mana; di episode ini kalian membangun image minimal non-root dengan multi-stage build, scan Trivy/Grype sebagai gate CI, dan menyiapkan fondasi supply chain dengan SBOM serta signing yang dibahas tuntas di episode 12-13

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Di episode 5 kita mengamankan secret. Sekarang perhatikan objek yang membawa semua itu — kode, library, konfigurasi — ke production: image container. Image adalah artefak yang paling lama hidup di sistem kalian; base image yang dipilih hari ini akan membawa ratusan package OS dan CVE-nya ke setiap environment selama berbulan-bulan.

Mengapa episode ini penting sekarang? Karena keputusan keamanan terbesar pada container justru diambil saat build, bukan saat runtime. Setelah image ter-push dan ter-deploy, memperbaikinya berarti rebuild + redeploy seluruh armada. Shift-left dalam konteks container artinya: desain Dockerfile yang aman sejak baris pertama, lalu verifikasi otomatis di pipeline.

Pilih Base Image Secara Sadar

Setiap layer base image adalah permukaan serangan. Perbandingan praktis:

BaseUkuranPackage OSKapan Dipakai
ubuntu:24.04~78 MBRatusanButuh toolchain OS lengkap
alpine~8 MBMinimalBinary statis; hati-hati musl libc
gcr.io/distroless/nodejs22~130 MBHampir nolRuntime Node tanpa shell
scratch0 MBNolBinary Go/Rust yang fully static

Aturan praktisnya: semakin sedikit yang ada di image, semakin sedikit yang harus di-patch. Distroless tidak punya shell maupun package manager — attacker yang berhasil eksekusi kode tidak bisa spawn sh, download tool, atau enumerasi sistem dengan mudah. Ini disebut shrinking the attack surface, dan efeknya nyata terhadap banyak kelas exploit post-exploitation.

Dockerfile Aman: Sebelum vs Sesudah

Perhatikan pola buruk yang masih umum ditemukan:

Dockerfile — pola rentan
FROM node:22
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]

Empat masalah: base penuh toolchain, COPY . . membawa .env dan .git, npm install bukan deterministik, dan proses jalan sebagai root. Bandingkan versi yang di-hardening:

Dockerfile — multi-stage + non-root
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
 
FROM gcr.io/distroless/nodejs22 AS runtime
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --chown=nonroot:nonroot src ./src
USER nonroot
CMD ["server.js"]

Poin-poin penting dari versi kedua:

  1. Multi-stage: stage deps memakai alpine untuk npm ci; stage final distroless hanya membawa hasilnya — compiler dan shell tidak ikut ke production.
  2. npm ci membaca lockfile → build reproducible (dan SCA di episode 4 akurat).
  3. USER nonroot — jika aplikasi dicompromise, attacker mendapat user tanpa privilege, bukan root.
  4. Tidak ada COPY . . — hanya direktori yang benar-benar dibutuhkan.

Tambahkan juga flag runtime defensif saat menjalankan:

Jalankan dengan batasan ketat
docker run --rm --read-only \
  --cap-drop=ALL \
  --security-opt no-new-privileges \
  -p 3000:3000 myapp:latest

Scanning sebagai Gate: Trivy & Grype

Dua scanner open source dominan: Trivy (Aquasecurity) dan Grype (Anchore). Keduanya memindai layer image terhadap database CVE. Trivy unggul karena satu binary untuk banyak target (image, fs, IaC, K8s); Grype kuat untuk workflow SBOM-first. Pola gate di CI:

Gate scan image di pipeline
jobs:
  image-scan:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Scan image hasil build
        run: |
          trivy image \
            --exit-code 1 \
            --ignore-unfixed \
            --severity HIGH,CRITICAL \
            myapp:${{ github.sha }}

Tiga flag yang membuat gate ini realistis:

  • --ignore-unfixed — CVE tanpa patch tersedia tidak menggagalkan build (tidak ada aksi yang bisa dilakukan developer); tetap terlaporkan.
  • --severity HIGH,CRITICAL — medium ke bawah masuk report, bukan blocker.
  • Tag by SHA (github.sha) — scan persis artefak yang akan di-push, bukan latest yang isinya bisa berbeda.

Tip

Scan dua kali: di CI sebelum push (gate) dan terjadwal harian/mingguan terhadap image yang sudah ada di registry (detective). CVE baru dirilis setiap hari — image yang bersih minggu lalu belum tentu bersih hari ini. Topik ini diperdalam di episode 10 tentang vulnerability management.

Fondasi Supply Chain: SBOM dan Signing

Dua fitur yang baru akan dibahas tuntas di episode 12-13, tetapi mulai sekarang biasakan:

Generate SBOM dan sign image
trivy image --format cyclonedx --output sbom.json myapp:1.0.0
cosign sign myapp:1.0.0

SBOM (Software Bill of Materials) adalah daftar isi resmi image — berguna saat CVE baru keluar untuk mencari "apakah kita memakai X?". Signing (cosign) memberi jaminan integritas: siapa pun yang menarik image bisa memverifikasi bahwa ia benar-benar dibangun oleh pipeline kalian, bukan image palsu di registry.

Pitfall Umum

  • :latest di production — tag bergerak membuat rollback dan audit mustahil; pin by digest (@sha256:...) untuk deployment.
  • Secret baked saat build — argumen build yang berisi kredensial tertinggal di history layer; gunakan BuildKit secrets (RUN --mount=type=secret).
  • Scan sekali lalu lupa — tanpa scan berkala, registry kalian menjadi museum CVE.
  • Root "karena butuh port 80" — pakai port tinggi + reverse proxy/Capability NET_BIND_SERVICE, bukan full root.

Penutup

Inti yang harus dibawa pulang:

  • Keamanan image ditentukan saat build: base minimal, multi-stage, non-root, deterministic install.
  • Distroless/scratch menghilangkan shell & package manager — memutus jalur post-exploitation.
  • Trivy/Grype sebagai CI gate dengan threshold severity + scan berkala registry.
  • SBOM dan cosign signing dimulai sejak sekarang; detailnya episode 12-13.

Di episode 7 selanjutnya kita turun ke infrastruktur: IaC Security & Policy-as-Code — bagaimana bucket publik dan security group terbuka dicegah sebelum terraform apply, memakai scanner IaC dan aturan Rego/OPA yang bisa kalian tulis sendiri. Sampai jumpa!

Belajar DevSecOps Engineer - Container Image Security | Belajar DevSecOps Engineer