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

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.
Sebelum hardening, kenali empat vektor utama:
| Vektor | Skenario | Dampak |
|---|---|---|
| Dependency/action takeover | Tag atau branch action dialihkan ke kode jahat | Kode arbitrer jalan dengan secrets kalian |
| Pull request berbahaya | PR dari fork mengeksekusi kode dengan token istimewa | Exfiltration secret + injeksi build |
| Secret bocor di log | echo $SECRET atau error message membocorkan nilai | Secret masuk log publik |
| Runner persisten | Self-hosted runner dipakai ulang antar job | Malware bertahan hidup antar build |
Prinsip pertahanannya satu kata: minimalisasi. Minimal permission, minimal lifetime, minimal lingkungan bersama.
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:
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 testDengan 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.
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:
steps:
# rentan: tag bisa diganti isinya
- uses: actions/checkout@v4
# aman: SHA tetap + komentar versi human-readable
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0Untuk action internal organisasi, alternatifnya adalah host sendiri atau gunakan mekanisme allowlist organisasi. Dependabot bisa menjaga SHA-pinning tetap update otomatis.
Runner yang hidup lama menumpuk cache, credential sisa, dan potensi backdoor. Prinsipnya:
./config.sh --url https://github.com/org/repo \
--token $RUNNER_TOKEN \
--ephemeral # runner mati setelah satu jobHardening teknis harus dipadukan kontrol proses:
.github/workflows/, deploy/, IaC) wajib review dari tim platform/security.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.shKombinasi environment: production + required reviewers berarti tidak ada workflow — bahkan yang dicompute — bisa menyentuh production tanpa manusia menekan tombol approve.
Detail penuh ada di episode 5, tetapi aturan dasar pipeline:
secrets context bawaan platform — jangan pernah menulis nilainya ke file yang kemudian di-print.Ringkasan yang bisa langsung kalian audit ke repo organisasi:
permissions: eksplisit dan minimal di setiap workflowpull_request_target yang checkout & run kode fork tanpa isolasiInti yang harus dibawa pulang:
pull_request_target dengan kode fork adalah pola berbahaya yang masih banyak ditemukan.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!