Hardening deploy dari config yang bisa menjalankan kode berarti menganggap file konfigurasi sebagai bagian dari permukaan serangan, bukan sekadar data. Dalam banyak pipeline modern, perubahan pada file CI/CD, package manager, hook, task runner, atau templating config dapat memicu perintah shell, script build, atau fetch artefak yang akhirnya menjalankan kode tak terduga saat deploy.
Masalahnya bukan hanya malware yang disisipkan ke source code. Blindspot yang lebih sering luput justru ada pada file yang tampak aman: workflow CI, script package, hook Git, task automation, chart deployment, dan template environment. Jika deploy membaca config lalu mengeksekusi langkah otomatis dari config tersebut, maka perubahan kecil pada file itu bisa punya dampak setara perubahan kode produksi.
Mengapa file config bisa berbahaya saat deploy
Secara praktik, banyak tool memperlakukan konfigurasi sebagai instruksi operasional. Selama pipeline membaca instruksi itu dan memberi akses ke secret, network, artefak, atau environment target, file config dapat menjadi jalur eksekusi kode.
Pola umum yang memicu eksekusi
- CI/CD workflow: langkah seperti run, shell command, reusable workflow, custom action, atau container step.
- Package manager: lifecycle script seperti install, prepare, postinstall, atau script custom yang dipanggil pipeline.
- Hooks: Git hooks, pre-deploy hook, release hook, migration hook, atau hook dari tool internal.
- Task runner: Makefile, justfile, taskfile, npm scripts, invoke, mage, atau script wrapper lain.
- Templating config: engine template yang mendukung evaluasi ekspresi, command substitution, atau render berbasis plugin.
- Provisioning/deploy config: manifest yang memanggil job init, sidecar helper, remote chart, atau script bootstrap.
Intinya, risiko muncul ketika ada rantai seperti ini: config berubah - pipeline memercayai config - runner mengeksekusi instruksi - secret atau akses deploy terbuka.
Kenapa ini sering lolos review
- Reviewer fokus pada perubahan kode aplikasi, bukan file operasional.
- Perubahan tampak kecil, misalnya menambah satu command atau mengganti action pihak ketiga.
- Tim menganggap file YAML, TOML, JSON, atau template hanya berisi data.
- Diff sulit dibaca karena config besar, generated, atau tersebar di banyak repo.
- Deploy path jarang diuji dengan perspektif penyalahgunaan.
Blindspot supply chain yang paling sering muncul
1. CI/CD yang mengeksekusi command dari workflow
Workflow CI/CD hampir selalu punya kemampuan menjalankan shell command. Jika repo mengizinkan perubahan workflow tanpa kontrol tambahan, attacker atau insider cukup memodifikasi langkah deploy, langkah build, atau dependency fetch.
# Contoh pola berisiko pada workflow CI/CD
steps:
- uses: actions/checkout@v4
- name: Build
run: make build
- name: Deploy
run: ./scripts/deploy.shContoh di atas tidak salah dengan sendirinya. Risikonya ada pada fakta bahwa make build dan ./scripts/deploy.sh bisa berubah melalui commit yang tampaknya rutin. Jika pipeline juga memegang credential cloud atau token registry, perubahan kecil pada langkah ini bisa mengekfiltrasi secret atau mendorong artefak berbahaya.
2. Package manager dan lifecycle scripts
Banyak package manager mendukung lifecycle script. Saat pipeline menjalankan install atau build, script tersebut dapat berjalan otomatis.
{
"scripts": {
"build": "node scripts/build.js",
"postinstall": "node scripts/setup.js"
}
}Risikonya ada pada dua sisi. Pertama, repo aplikasi sendiri dapat mengubah script ini. Kedua, dependency transitif juga bisa membawa script yang dieksekusi saat instalasi, tergantung tool dan mode instalasi yang dipakai. Karena itu deploy yang melakukan install langsung di runner produksi atau runner dengan akses sensitif memiliki permukaan serangan lebih luas.
3. Hook deploy, migration, dan release
Banyak sistem deploy punya hook sebelum atau sesudah release. Hook sering dipakai untuk migrasi database, warm cache, atau notifikasi. Masalahnya, hook hampir selalu punya privilege tinggi karena berjalan dekat dengan lingkungan target.
Jika hook didefinisikan lewat file config atau script repo, perubahan hook harus dianggap setara perubahan pada entrypoint deploy.
4. Task runner sebagai lapisan abstraksi yang tidak terlihat
make deploy, task release, atau npm run deploy memang nyaman, tetapi juga menyembunyikan detail yang sebenarnya dieksekusi. Saat tim mereview hanya command tingkat atas, isi task di bawahnya sering luput diperiksa. Ini masalah yang sama dengan shell script wrapper yang tumbuh tanpa kontrol.
5. Templating config yang dapat mengevaluasi ekspresi
Beberapa sistem templating mendukung evaluasi ekspresi, plugin, atau helper yang menarik data dari lingkungan sekitar. Dalam kondisi buruk, proses render config menjadi jalur eksekusi kode. Bahkan tanpa eksekusi langsung, template dapat memuat referensi remote, membentuk command, atau menyuntikkan nilai yang mengubah perilaku deploy.
Catatan: Tidak semua templating engine menjalankan kode, tetapi tim perlu memetakan mana yang hanya melakukan substitusi data dan mana yang dapat menjalankan plugin, helper, hook, atau command eksternal.
Prinsip hardening deploy yang efektif
Anggap config deploy sebagai kode berisiko tinggi
Langkah pertama bukan teknologi, melainkan klasifikasi. File berikut sebaiknya diperlakukan sebagai high-risk change surface:
- workflow CI/CD
- script build/deploy/release
- package manifest yang mendefinisikan script
- task runner file
- helm chart, kustomize overlay, manifest deploy, terraform wrapper, ansible playbook terkait deploy
- template config yang diproses saat release
- hook migration, release, post-deploy, rollback
Jika klasifikasi ini jelas, Anda bisa menerapkan review, approval, dan pembatasan berbeda dibanding perubahan biasa.
Immutable artifact, mutable config seminimal mungkin
Semakin banyak langkah build atau install yang terjadi saat deploy, semakin besar peluang file config menjalankan kode. Praktik yang lebih aman adalah:
- build artefak lebih awal di pipeline terpisah,
- tandatangani atau verifikasi provenance artefak,
- deploy artefak immutable,
- batasi config deploy ke parameter data, bukan instruksi build.
Ini bekerja karena Anda memisahkan fase membuat sesuatu dari fase menjalankan sesuatu di target. Permukaan serangan deploy menjadi lebih kecil.
Least privilege di setiap runner
Runner build tidak harus punya akses produksi. Runner deploy tidak harus bisa mengubah source repository. Token untuk membaca paket tidak harus bisa menulis release. Prinsip least privilege mengurangi dampak jika sebuah config memang berhasil mengeksekusi kode.
Pembagian minimal yang umum:
- Runner lint/test: tanpa secret produksi, network keluar dibatasi seperlunya.
- Runner build: akses ke cache dan registry build, bukan ke cluster produksi.
- Runner deploy: hanya artefak yang sudah disetujui, token terbatas ke target environment tertentu.
- Runner rollback: hanya mampu memilih release sebelumnya dan memulihkan state, bukan membangun ulang.
Runner terisolasi dan ephemeral
Gunakan runner yang di-reset setelah job selesai. Isolasi ini mengurangi persistensi malware, kebocoran credential antar job, dan efek samping dari perubahan config yang lolos. Jika memungkinkan:
- gunakan environment sementara untuk setiap job,
- hindari shared workspace jangka panjang,
- hapus credential setelah step selesai,
- batasi akses filesystem dan Docker socket jika tidak benar-benar perlu.
Verifikasi provenance artefak dan dependency
Deploy yang aman tidak cukup memercayai branch utama. Verifikasi bahwa artefak benar-benar berasal dari pipeline yang sah, dari commit yang disetujui, dan tidak diganti di tengah jalan. Praktik yang berguna:
- pin dependency dan action ke referensi yang stabil,
- hindari referensi mengambang untuk komponen kritis,
- catat commit SHA sumber artefak,
- simpan metadata build dan signer/provenance,
- validasi checksum atau signature sebelum deploy.
Trade-off-nya adalah pengelolaan metadata tambahan dan disiplin release yang lebih ketat. Namun manfaatnya besar saat investigasi insiden dan rollback.
Guardrail sebelum deploy
1. Wajibkan review khusus untuk file berisiko
Jangan samakan perubahan pada workflow deploy dengan perubahan dokumentasi. Terapkan aturan bahwa file tertentu memerlukan reviewer dari tim platform, DevOps, atau security champion.
# Contoh pola kebijakan file sensitif
sensitive_paths:
- .github/workflows/**
- .gitlab-ci.yml
- scripts/deploy/**
- Makefile
- package.json
- helm/**
- k8s/**
- deploy/**Implementasinya bisa lewat CODEOWNERS, branch protection, policy di platform SCM, atau gate internal yang memblok deploy jika file sensitif berubah tanpa approval yang tepat.
2. Bedakan approval untuk code dan deploy config
Masalah umum: PR sudah disetujui untuk fitur, lalu perubahan workflow ikut lolos karena reviewer yang sama tidak terbiasa membaca config deploy. Pisahkan jalur approval jika perlu. Minimal, tandai PR yang menyentuh file sensitif dengan label otomatis dan status check khusus.
3. Deteksi perubahan berisiko secara otomatis
Buat aturan sederhana namun tegas untuk mendeteksi pola yang patut dicurigai:
- penambahan step
runbaru pada workflow, - pergantian action pihak ketiga,
- penambahan lifecycle script package manager,
- perubahan hook deploy atau migration,
- penambahan command jaringan seperti curl atau wget di jalur deploy,
- perubahan target registry, image, chart, atau source URL,
- kenaikan permission token runner.
Deteksi ini tidak harus canggih. Diff-aware policy sederhana sering lebih berguna daripada scanner besar yang tidak dipelihara.
# Pseudocode pemeriksaan sebelum deploy
changed_files=$(git diff --name-only origin/main...HEAD)
if matches_sensitive_path "$changed_files"; then
require_additional_approval
run_policy_checks
fi4. Nonaktifkan jalur eksekusi yang tidak perlu
Jika pipeline tidak butuh lifecycle script dependency, matikan. Jika deploy tidak perlu install dependency di target, jangan lakukan. Jika task runner hanya menambah abstraksi tanpa nilai, pertimbangkan menyederhanakan jalur deploy agar lebih transparan.
Trade-off-nya adalah beberapa workflow lama perlu direfaktor. Namun semakin sedikit mekanisme eksekusi implisit, semakin mudah diaudit.
5. Pisahkan fase build, sign, dan deploy
Ini guardrail yang sangat kuat. Build menghasilkan artefak. Fase verifikasi memeriksa metadata dan provenance. Deploy hanya menerima artefak yang lolos. Dengan model ini, perubahan config deploy tidak bisa diam-diam mengubah source yang dibangun tanpa terlihat pada rantai metadata.
Observability untuk deploy yang menjalankan kode
Observability penting bukan hanya untuk performa, tetapi juga untuk mendeteksi kapan deploy melakukan sesuatu yang tidak semestinya.
Sinyal minimum yang perlu dicatat
- siapa yang memicu pipeline dan dari commit mana,
- file sensitif apa saja yang berubah,
- artefak apa yang dibangun dan checksum-nya,
- runner mana yang mengeksekusi deploy,
- command penting yang dijalankan pada fase release,
- akses secret apa yang digunakan job,
- koneksi keluar ke host mana selama build/deploy,
- release ID untuk korelasi dengan log aplikasi dan infrastruktur.
Alert yang berguna
- deploy dari commit yang mengubah file workflow atau script deploy,
- deploy yang memakai runner atau token tidak biasa,
- peningkatan mendadak egress network saat build/deploy,
- rollback beruntun setelah release,
- perbedaan artefak dari commit yang sama,
- penggunaan secret produksi oleh job non-deploy.
Jangan hanya mengandalkan log text mentah. Minimal, beri ID release dan korelasikan ke commit, artefak, environment, dan operator. Saat insiden terjadi, waktu investigasi berkurang drastis.
Checklist audit blindspot supply chain di pipeline deploy
Audit file dan jalur eksekusi
- Apakah semua file yang bisa memengaruhi deploy sudah terdaftar sebagai file sensitif?
- Apakah ada script atau task runner yang dipanggil secara tidak langsung dari workflow?
- Apakah package manager menjalankan lifecycle script saat CI/build/deploy?
- Apakah ada hook pre/post deploy, migration, atau release yang belum terdokumentasi?
- Apakah templating config hanya melakukan substitusi data, atau bisa menjalankan plugin/helper/command?
- Apakah deploy menarik resource dari URL atau registry eksternal saat runtime?
Audit akses dan privilege
- Apakah runner build terpisah dari runner deploy?
- Apakah token deploy scoped ke satu environment dan masa berlaku singkat?
- Apakah job non-produksi bisa membaca secret produksi?
- Apakah runner punya akses shell terlalu luas ke host target?
- Apakah network egress runner dibatasi?
Audit integritas dan provenance
- Apakah action, image, plugin, atau dependency kritis dipin ke referensi stabil?
- Apakah artefak release bisa ditelusuri ke commit sumber dan pipeline pembuatnya?
- Apakah checksum, signature, atau metadata build diverifikasi sebelum deploy?
- Apakah ada kontrol untuk mencegah rebuild diam-diam di fase deploy?
Audit rollback dan kesiapan insiden
- Apakah rollback bisa dilakukan tanpa build ulang?
- Apakah ada daftar release sebelumnya yang siap dipromosikan kembali?
- Apakah log deploy cukup detail untuk mengetahui command apa yang berjalan?
- Apakah runbook insiden menyebut cara memutus token, runner, dan akses jaringan?
Runbook insiden: deploy terlanjur menjalankan kode tak terduga
Saat insiden terjadi, tujuan utamanya ada tiga: hentikan dampak, pulihkan layanan, lalu kumpulkan bukti secukupnya tanpa memperparah keadaan.
1. Contain: hentikan jalur eksekusi dan batasi radius
- Pause pipeline deploy dan nonaktifkan trigger otomatis sementara.
- Cabut atau rotasi token yang dipakai job terdampak, terutama credential cloud, registry, dan secret manager.
- Karantina runner terkait. Jika runner ephemeral, hentikan instansinya dan cegah reuse artefak workspace.
- Blok egress network runner atau environment build jika dicurigai ada eksfiltrasi.
- Jika perlu, freeze perubahan pada repo yang memuat file deploy sensitif.
2. Recover: rollback cepat dengan artefak yang sudah diketahui baik
Rollback terbaik adalah mempromosikan release sebelumnya yang sudah tervalidasi, bukan membangun ulang dari branch yang dianggap aman. Build ulang saat insiden justru berisiko membawa variabel baru.
# Contoh langkah rollback konseptual
1. pilih release N-1 yang checksum dan provenance-nya valid
2. deploy ulang artefak yang sama
3. verifikasi health check, error rate, dan konektivitas
4. tahan traffic bertahap bila platform mendukungJika ada migrasi database yang tidak kompatibel mundur, gunakan strategi rollback yang realistis: rollback aplikasi ke mode kompatibel, aktifkan feature flag, atau jalankan prosedur pemulihan data yang sudah diuji sebelumnya.
3. Investigate: kumpulkan bukti minimum yang relevan
- commit atau PR yang memicu deploy,
- daftar file sensitif yang berubah,
- log command pada fase build/deploy,
- artefak yang dipakai dan metadata pembuatannya,
- token atau secret yang diakses job,
- koneksi keluar yang terjadi selama job,
- perubahan permission pada workflow atau runner.
Fokus pada bukti yang dapat menjawab pertanyaan: apa yang dijalankan, oleh siapa, dengan akses apa, dan sejak kapan.
4. Eradicate: hilangkan akar masalah
- hapus perubahan config berbahaya atau revert PR terkait,
- perketat policy file sensitif,
- pin dependency/action/plugin yang semula longgar,
- nonaktifkan hook atau lifecycle script yang tidak diperlukan,
- pisahkan build dari deploy jika sebelumnya masih campur.
5. Postmortem ringan yang fokus pada perbaikan
Postmortem tidak perlu panjang, tetapi harus menghasilkan tindakan nyata. Format sederhana yang cukup:
- Timeline: kapan perubahan masuk, kapan deploy berjalan, kapan dampak terdeteksi.
- Root cause: config mana yang memicu eksekusi dan kenapa kontrol gagal.
- Detection gap: sinyal apa yang seharusnya ada tetapi tidak termonitor.
- Recovery gap: bagian rollback mana yang lambat atau manual.
- Action items: owner, prioritas, dan tenggat.
Tujuan postmortem adalah menurunkan peluang kejadian ulang dan mempercepat respons berikutnya, bukan mencari kambing hitam.
Contoh guardrail praktis yang bernilai tinggi
Blok deploy jika file sensitif berubah tanpa approval tambahan
# Pseudocode gate deploy
if changed_files.intersects(sensitive_paths):
assert approvals.from_platform_or_security >= 1
assert policy_checks_passed == true
assert release_artifact_is_prebuilt == trueGuardrail ini sederhana, tetapi efektif untuk mencegah perubahan workflow atau script deploy lolos sebagai perubahan biasa.
Jalankan deploy dari artefak prebuilt, bukan dari source checkout terbaru
Dengan pendekatan ini, job deploy tidak perlu menjalankan install, compile, atau lifecycle script dari repo. Hasilnya, perubahan config di fase deploy punya ruang gerak jauh lebih sempit.
Batasi permission token workflow
Jangan berikan kemampuan tulis ke repo, registry, dan environment sekaligus pada satu job jika tidak dibutuhkan. Semakin kecil permission, semakin kecil pula nilai yang bisa dieksfiltrasi atau disalahgunakan.
Monitor perubahan dependency operasional
Tim sering memantau dependency aplikasi, tetapi lupa dependency operasional seperti action CI pihak ketiga, image build, plugin chart, atau helper deploy. Padahal dependency ini berada langsung di jalur release.
Kesalahan umum yang perlu dihindari
- Menyamakan YAML dengan data pasif. Banyak YAML adalah instruksi eksekusi, bukan sekadar konfigurasi.
- Build saat deploy. Ini memperlebar permukaan serangan dan memperlambat rollback.
- Runner bersama untuk semua tahap. Kebocoran atau persistensi antartahap jadi lebih mudah terjadi.
- Token terlalu luas. Satu workflow compromise langsung berdampak ke banyak sistem.
- Tidak punya baseline file sensitif. Tim tidak tahu perubahan mana yang seharusnya memicu kewaspadaan tinggi.
- Rollback bergantung pada rebuild. Saat insiden, ini menambah ketidakpastian.
Langkah implementasi bertahap untuk tim kecil
Tim kecil tidak perlu menunggu platform sempurna. Terapkan bertahap dengan prioritas dampak tertinggi.
Tahap 1: minggu pertama
- Daftar semua file sensitif yang bisa memengaruhi build dan deploy.
- Aktifkan reviewer wajib untuk file tersebut.
- Dokumentasikan jalur deploy aktual: workflow - script - task runner - artefak - target.
- Pastikan ada rollback ke artefak rilis sebelumnya tanpa build ulang.
Tahap 2: 2-4 minggu
- Pisahkan runner build dan runner deploy.
- Batasi token deploy hanya ke environment yang relevan.
- Tambahkan pemeriksaan otomatis untuk perubahan berisiko pada workflow, script, dan package lifecycle.
- Kurangi langkah install/build di fase deploy.
Tahap 3: 1-2 bulan
- Implementasikan provenance atau minimal metadata artefak yang konsisten.
- Pin dependency operasional penting ke referensi stabil.
- Tambahkan logging release ID, commit SHA, artefak, dan akses secret per job.
- Uji tabletop exercise untuk skenario deploy menjalankan kode tak terduga.
Tahap 4: setelah fondasi stabil
- Perketat isolasi runner dan egress network.
- Evaluasi templating engine, hook, dan plugin yang masih punya kemampuan eksekusi implisit.
- Bangun policy-as-code untuk memblok perubahan yang menaikkan privilege atau menarik resource tak dikenal.
Untuk banyak tim, kombinasi file sensitif + approval tambahan + artefak immutable + rollback cepat + runner terisolasi sudah memberi pengurangan risiko yang besar tanpa investasi berlebihan.
Penutup
Blindspot supply chain pada pipeline deploy sering bukan berasal dari source code utama, melainkan dari file konfigurasi yang ternyata dapat menjalankan kode. Karena itu, hardening deploy dari config yang bisa menjalankan kode harus dimulai dengan perubahan cara pandang: config deploy adalah jalur eksekusi berisiko tinggi.
Jika Anda hanya mengambil beberapa langkah, prioritaskan ini: petakan file sensitif, wajibkan review khusus, deploy dari artefak prebuilt, isolasikan runner, batasi privilege token, dan siapkan rollback yang cepat. Langkah-langkah ini praktis, bisa diterapkan bertahap, dan paling langsung menurunkan risiko ketika config berubah menjadi kode yang dieksekusi saat release.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!