Belajar DevSecOps Engineer - Secure CI/CD Pipelines
Episode 3 of 28

Belajar DevSecOps Engineer - Secure CI/CD Pipelines

Pipeline CI/CD adalah mesin produksi kode kalian dan target serangan favorit; di episode ini kalian meng-hardening GitHub Actions dengan pinning action by SHA, membatasi GITHUB_TOKEN, ephemeral runner, protected branch & approval gate, serta mempelajari pola serangan nyata seperti poisoned pipeline execution

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

Pendahuluan

Setelah dua episode membahas model dan budaya, sekarang kita turun ke teknis. Topik pertama yang wajib dikuasai: mengamankan pipeline itu sendiri. Mengapa duluan? Karena pipeline adalah titik kumpul semua trust — ia menyentuh source code, menarik dependency dari internet, memegang secrets, dan punya kredensial untuk deploy ke production. Satu pipeline yang dicompute berarti attacker mendapatkan semuanya sekaligus.

Kasus nyata tahun 2025 membuktikan ini bukan teori: beberapa repo populer terkena poisoned pipeline execution ketika sebuah GitHub Action pihak ketiga (tj-actions/changed-files) dicompute — tag-nya dialihkan ke kode jahat yang mencuri secrets dari memory runner. Ribuan repo terekspos dalam hitungan jam. Episode ini memberi kalian checklist hardening agar pipeline kalian tidak menjadi korban berikutnya.

Permukaan Serangan Pipeline

Sebelum hardening, kenali empat vektor utama:

VektorSkenarioDampak
Dependency/action takeoverTag atau branch action dialihkan ke kode jahatKode arbitrer jalan dengan secrets kalian
Pull request berbahayaPR dari fork mengeksekusi kode dengan token istimewaExfiltration secret + injeksi build
Secret bocor di logecho $SECRET atau error message membocorkan nilaiSecret masuk log publik
Runner persistenSelf-hosted runner dipakai ulang antar jobMalware bertahan hidup antar build

Prinsip pertahanannya satu kata: minimalisasi. Minimal permission, minimal lifetime, minimal lingkungan bersama.

Batasi GITHUB_TOKEN Permissions

Secara default, token bawaan workflow bisa punya izin write luas (menulis repo, komentar PR). Turunkan ke least privilege secara global lalu naikkan hanya jika perlu:

.github/workflows/ci.yml
name: CI
on:
  pull_request:
 
permissions:
  contents: read          # default untuk semua job: hanya baca
 
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test

Dengan contents: read, bahkan jika workflow berhasil disusupi, token tidak bisa menulis ke repository kalian. Untuk job yang butuh lebih (misal publish release), deklarasikan permission ekstra di level job tersebut saja, bukan global.

Warning

Workflow yang ditrigger oleh pull_request dari fork tidak otomatis mendapat secrets — tetapi pastikan kalian tidak memanggil workflow yang menaruh secrets di environment, dan hindari pull_request_target dengan checkout ref PR tanpa review. Pola pull_request_target + kode PR = poisoned pipeline execution klasik.

Pinning Action by SHA

Referensi action by tag (@v4) adalah pointer yang bisa bergerak — maintainer (atau penyerang yang merebut akunnya) bisa push kode baru ke tag yang sama. Pin by commit SHA membuat referensi immutable:

Sebelum vs sesudah pinning
steps:
  # rentan: tag bisa diganti isinya
  - uses: actions/checkout@v4
  # aman: SHA tetap + komentar versi human-readable
  - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

Untuk action internal organisasi, alternatifnya adalah host sendiri atau gunakan mekanisme allowlist organisasi. Dependabot bisa menjaga SHA-pinning tetap update otomatis.

Ephemeral Runner

Runner yang hidup lama menumpuk cache, credential sisa, dan potensi backdoor. Prinsipnya:

  • GitHub-hosted runner sudah ephemeral — VM segar per job; ini alasan kuat memakainya saat memungkinkan.
  • Jika wajib self-hosted (misal build butuh GPU atau akses jaringan internal), pakai runner ephemeral per-job di autoscaling group, bukan pool statis yang dipakai ulang.
  • Jangan pernah menghubungkan self-hosted runner repo publik langsung ke jaringan production.
Self-hosted runner ephemeral
./config.sh --url https://github.com/org/repo \
  --token $RUNNER_TOKEN \
  --ephemeral            # runner mati setelah satu job

Protected Branch dan Approval Gates

Hardening teknis harus dipadukan kontrol proses:

  • Branch protection: main tidak menerima push langsung; wajib PR + required status checks (CI hijau) + review.
  • Environment protection: deployment ke production lewat environment dengan required reviewers dan delay — bukan sekadar step di workflow mana pun.
  • Code owner: perubahan file sensitif (.github/workflows/, deploy/, IaC) wajib review dari tim platform/security.
Deploy dengan environment protection
jobs:
  deploy-prod:
    runs-on: ubuntu-latest
    environment: production   # wajib approve reviewer di settings
    permissions:
      id-token: write         # OIDC, dibahas episode 19
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/deploy.sh

Kombinasi environment: production + required reviewers berarti tidak ada workflow — bahkan yang dicompute — bisa menyentuh production tanpa manusia menekan tombol approve.

Penanganan Secret di Pipeline (Dasar)

Detail penuh ada di episode 5, tetapi aturan dasar pipeline:

  1. Simpan secret di encrypted secrets platform (GitHub Encrypted Secrets / Vault), bukan file di repo atau variable plaintext.
  2. Masking otomatis bekerja hanya jika secret dimasukkan via sintaks secrets context bawaan platform — jangan pernah menulis nilainya ke file yang kemudian di-print.
  3. Kurangi jumlah secret itu sendiri — OIDC federation (episode 19) menghilangkan banyak kebutuhan static key.

Checklist Hardening Pipeline

Ringkasan yang bisa langsung kalian audit ke repo organisasi:

  • permissions: eksplisit dan minimal di setiap workflow
  • Semua third-party action di-pin by SHA
  • Branch protection aktif + required checks
  • Production deploy melewati environment dengan reviewer
  • Runner self-hosted bersifat ephemeral, tidak menyentuh prod network
  • Tidak ada pull_request_target yang checkout & run kode fork tanpa isolasi
  • Log job tidak membocorkan nilai secret

Penutup

Inti yang harus dibawa pulang:

  • Pipeline adalah high-value target: ia pegang source, secrets, dan akses deploy sekaligus.
  • Least privilege token + pinning SHA + ephemeral runner memutus tiga vektor serangan utama.
  • pull_request_target dengan kode fork adalah pola berbahaya yang masih banyak ditemukan.
  • Environment protection dengan required reviewers adalah gerbang terakhir menuju production.

Di episode 4 selanjutnya kita akan menanamkan otak security ke pipeline: integrasi SAST, DAST, dan SCA — bagaimana Semgrep membaca kode kalian, Trivy mengawasi dependency, ZAP menguji aplikasi yang sudah jalan, dan cara mengelola false positive supaya developer tidak memberontak. Sampai jumpa!