Pipeline rilis yang tahan risiko saat dependensi lisensi berubah bukan sekadar soal compliance. Ini adalah cara menjaga agar produk tetap bisa dibangun, dirilis, dan dipelihara ketika sebuah paket mengubah lisensi, registry membatasi akses, vendor menutup layanan, atau dependency transitive tiba-tiba menjadi masalah hukum dan operasional.

Tim engineering sering baru sadar ada ketergantungan berisiko ketika pipeline merah menjelang release, atau lebih buruk, ketika artefak lama tidak bisa direproduksi. Konteks seperti gerakan Stop Killing Games berguna sebagai pemicu berpikir: jika sebuah produk bergantung pada pihak luar untuk tetap berfungsi, apa yang terjadi saat aturan, akses, atau lisensi berubah? Di level software delivery, jawabannya adalah merancang pipeline yang bisa mendeteksi, menahan, dan mengurangi dampak perubahan tersebut sejak fase CI sampai rollout produksi.

Mengapa perubahan lisensi dan kebijakan vendor bisa menghentikan rilis

Risiko tidak datang hanya dari package yang Anda import langsung. Sumber masalah yang umum antara lain:

  • Lisensi paket berubah pada versi baru, atau ternyata dependensi transitif membawa lisensi yang tidak sesuai kebijakan perusahaan.
  • Registry atau vendor mengubah syarat akses, misalnya rate limit, authentication, geoblocking, atau penghentian paket tertentu.
  • Layanan SaaS pihak ketiga berubah model produk, sehingga environment build atau runtime tidak lagi kompatibel.
  • Artefak upstream dihapus atau diganti, membuat build tidak reproducible.
  • Tooling security/compliance baru diterapkan mendadak, tetapi repository belum memiliki metadata yang cukup untuk lolos pengecekan.

Masalah ini sering dianggap terpisah: legal mengurus lisensi, DevOps mengurus build, security mengurus supply chain. Padahal dampaknya bertemu di satu titik: release pipeline. Karena itu desain pipeline harus memandang lisensi, provenance artefak, dan ketersediaan dependency sebagai satu rangkaian kontrol.

Prinsip desain pipeline rilis yang tahan risiko

1. Fail closed untuk perubahan berisiko tinggi

Jika ada lisensi terlarang, checksum artefak berubah, atau sumber dependency tidak tepercaya, pipeline sebaiknya menahan rilis sampai ada keputusan eksplisit. Ini lebih aman daripada membiarkan perubahan masuk diam-diam.

2. Fail open terbatas untuk ketersediaan non-kritis

Untuk beberapa komponen non-produksi, misalnya upload hasil scan ke dashboard eksternal, pipeline boleh tetap lanjut jika layanan eksternal gagal, selama bukti scan lokal tetap tersimpan. Tujuannya menjaga keandalan pipeline tanpa mengorbankan kontrol inti.

3. Reproducible build lebih penting daripada build yang hanya “berhasil hari ini”

Rilis yang baik harus bisa dibangun ulang dari source, lockfile, dan artefak yang sama. Jika pipeline tergantung pada latest, unduhan langsung dari internet, atau metadata yang berubah, maka tim sulit membuktikan apa yang sebenarnya dirilis.

4. Pisahkan policy decision dari mekanisme scan

Scanner hanya mengumpulkan fakta: nama paket, versi, lisensi, sumber, checksum. Keputusan seperti “GPL dilarang di binary distribusi komersial” atau “AGPL harus legal review” sebaiknya disimpan sebagai policy yang bisa diaudit dan diubah tanpa mengubah banyak job CI.

Komponen wajib dalam pipeline rilis yang aman

Gate CI untuk license scanning

License scanning sebaiknya berjalan pada pull request dan branch utama, bukan hanya sebelum rilis. Targetnya bukan mencari semua kemungkinan masalah hukum, tetapi mendeteksi perubahan yang relevan untuk keputusan engineering sehari-hari:

  • paket baru masuk,
  • versi paket berubah,
  • lisensi berubah,
  • lisensi tidak diketahui atau ambigu,
  • metadata lisensi tidak lengkap.

Implementasi praktis:

  1. Bangun dependency tree dari lockfile, bukan hanya manifest.
  2. Hasil scan disimpan sebagai artefak pipeline agar bisa dibandingkan antar commit.
  3. Terapkan kategori hasil: allow, review, deny.
  4. Pull request dengan status review tidak bisa merge tanpa approval yang sesuai.

Catatan: scanner lisensi tidak selalu akurat untuk paket dengan metadata buruk atau lisensi ganda. Karena itu hasil “unknown” jangan otomatis dianggap aman.

SBOM sebagai inventaris rilis

Software Bill of Materials (SBOM) memberi daftar komponen yang masuk ke artefak. Dalam konteks perubahan lisensi atau kebijakan vendor, SBOM membantu menjawab dua pertanyaan penting:

  • Apa saja yang ikut terkirim pada rilis ini?
  • Rilis mana saja yang terdampak jika satu komponen berubah status?

Praktiknya, hasil build release sebaiknya selalu menghasilkan SBOM dan menyimpannya bersama artefak, checksum, dan metadata commit. Format dan tool bisa berbeda, tetapi prinsipnya sama: SBOM harus terkait dengan artefak rilis yang benar-benar dikirim, bukan sekadar snapshot source tree.

Approval release berbasis risiko

Tidak semua perubahan butuh level persetujuan yang sama. Approval yang efektif biasanya berbasis kelas risiko:

  • Perubahan dependency patch dengan lisensi tetap: approval engineering biasa.
  • Perubahan dependency mayor atau sumber registry: approval maintainer repo.
  • Lisensi baru/unknown/restricted: approval tambahan dari owner compliance atau legal contact.
  • Perubahan vendor runtime kritis: approval release manager atau SRE.

Yang penting adalah aturan ini tertulis dalam policy merge dan release, bukan diputuskan ad hoc saat ada insiden.

Fallback build dan mode degradasi

Jika vendor atau layanan eksternal berubah kebijakan, pipeline masih perlu cara untuk tetap menghasilkan rilis yang aman. Contohnya:

  • menggunakan mirror internal untuk package registry,
  • menggunakan cache artefak yang tervalidasi,
  • menonaktifkan fitur opsional yang bergantung pada SDK/vendor tertentu,
  • membangun varian produk tanpa komponen yang sedang diblokir sambil menunggu review.

Fallback build bukan berarti mengabaikan compliance. Tujuannya adalah menghindari situasi “tidak bisa merilis apa pun” ketika satu dependency atau layanan berubah mendadak.

Pinning versi dan lockfile yang benar-benar dipakai

Pinning versi adalah kontrol dasar tetapi sering dijalankan setengah hati. Kesalahan umum:

  • manifest dipin, tetapi lockfile tidak dikomit,
  • CI tetap menjalankan perintah yang memperbarui dependency,
  • base image container memakai tag yang bisa berubah,
  • tooling build diunduh tanpa checksum.

Prinsipnya, semua input build yang signifikan harus dipakukan sejauh praktis: versi package, base image, compiler/toolchain, dan sumber artefak. Jika tidak, lisensi atau isi binary bisa berubah tanpa perubahan kode aplikasi.

Verifikasi artefak dan provenance

Pipeline yang tahan risiko harus dapat membuktikan bahwa artefak release berasal dari source dan dependency yang diharapkan. Minimal lakukan:

  • hash/checksum pada artefak build,
  • verifikasi checksum dependency yang diunduh,
  • penyimpanan metadata source revision,
  • penandatanganan artefak atau attestasi provenance jika infrastruktur mendukung.

Ini penting ketika registry upstream mengubah isi paket, atau ketika tim perlu mengaudit apakah rilis lama masih dapat dipercaya.

Mirror dependency internal

Mirror internal mengurangi ketergantungan langsung pada internet dan kebijakan registry eksternal. Manfaat praktisnya:

  • build lebih stabil,
  • artefak lama tetap tersedia,
  • akses bisa dibatasi ke paket yang sudah lolos review,
  • tim punya satu titik kontrol untuk cache, retensi, dan audit.

Trade-off-nya adalah biaya operasional: storage, sinkronisasi, retensi, dan tata kelola. Namun untuk produk yang harus dipelihara bertahun-tahun, ini sering lebih murah daripada insiden rilis yang berulang.

Contoh alur GitHub Actions

Berikut contoh alur yang menekankan urutan kontrol, bukan tool tertentu. Workflow ini memisahkan validasi dependency, build, dan release approval.

name: release-pipeline

on:
  pull_request:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  dependency-audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup build environment
        run: ./ci/setup.sh
      - name: Install dependencies from lockfile
        run: ./ci/install-locked.sh
      - name: Generate dependency inventory
        run: ./ci/generate-deps-report.sh > deps-report.json
      - name: Run license policy check
        run: ./ci/check-license-policy.sh deps-report.json policy/licenses.yml
      - name: Generate SBOM
        run: ./ci/generate-sbom.sh > sbom.json
      - name: Upload audit artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dependency-audit
          path: |
            deps-report.json
            sbom.json

  build:
    needs: dependency-audit
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup build environment
        run: ./ci/setup.sh
      - name: Restore validated dependencies
        run: ./ci/install-locked.sh --prefer-internal-mirror
      - name: Build release artifact
        run: ./ci/build-release.sh
      - name: Verify artifact
        run: ./ci/verify-artifact.sh dist/
      - name: Publish build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: release-artifacts
          path: dist/

  release:
    if: github.ref == 'refs/heads/main'
    needs: build
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: release-artifacts
          path: dist/
      - name: Create release metadata
        run: ./ci/create-release-metadata.sh dist/
      - name: Publish release
        run: ./ci/publish-release.sh dist/

Beberapa hal penting dari alur di atas:

  • Build tidak jalan sebelum audit dependency selesai.
  • Instalasi dependency menggunakan lockfile.
  • SBOM dan laporan lisensi diunggah sebagai artefak pipeline.
  • Job release dipisahkan agar approval environment atau manual gate bisa diterapkan.

Di GitHub, Anda bisa menambahkan protected branch, required status checks, dan environment reviewers untuk memastikan merge dan release tidak melewati gate.

Contoh alur GitLab CI

Jika memakai GitLab CI, ide dasarnya sama: pisahkan tahap scan, build, verify, dan release.

stages:
  - audit
  - build
  - verify
  - release

audit_dependencies:
  stage: audit
  script:
    - ./ci/setup.sh
    - ./ci/install-locked.sh
    - ./ci/generate-deps-report.sh > deps-report.json
    - ./ci/check-license-policy.sh deps-report.json policy/licenses.yml
    - ./ci/generate-sbom.sh > sbom.json
  artifacts:
    paths:
      - deps-report.json
      - sbom.json

build_release:
  stage: build
  needs: [audit_dependencies]
  script:
    - ./ci/setup.sh
    - ./ci/install-locked.sh --prefer-internal-mirror
    - ./ci/build-release.sh
  artifacts:
    paths:
      - dist/

verify_release:
  stage: verify
  needs: [build_release]
  script:
    - ./ci/verify-artifact.sh dist/
    - ./ci/check-release-against-sbom.sh dist/ sbom.json

publish_release:
  stage: release
  needs: [verify_release]
  when: manual
  script:
    - ./ci/publish-release.sh dist/

Di GitLab, kombinasi yang biasanya berguna adalah:

  • merge request approvals untuk dependency change tertentu,
  • protected branches/tags,
  • manual job untuk publish release,
  • rules yang membedakan alur branch biasa dan branch release.

Kebijakan merge yang benar-benar membantu

Pipeline yang baik akan tetap bocor jika kebijakan merge terlalu longgar. Kebijakan minimal yang layak dipertimbangkan:

  1. Semua perubahan lockfile wajib direview. Jangan anggap lockfile sebagai file turunan yang tidak penting.
  2. Perubahan dependency harus terlihat jelas di pull request. Gunakan bot atau template PR yang merangkum paket baru, paket dihapus, dan perubahan lisensi.
  3. Status check license policy wajib hijau sebelum merge.
  4. Perubahan pada folder build/release policy memerlukan reviewer khusus.
  5. Tag release hanya dibuat dari commit yang sudah lolos pipeline lengkap.

Template PR sederhana sering cukup membantu. Misalnya mewajibkan pengisi PR menjawab:

  • apakah ada dependency baru,
  • apakah ada perubahan lisensi,
  • apakah paket diambil dari sumber baru,
  • apakah fallback build sudah diuji jika sumber utama gagal.

Rollout bertahap agar perubahan tidak langsung menghentikan produk

Setelah artefak lolos build dan policy gate, risiko belum selesai. Jika vendor policy berubah di runtime, Anda butuh strategi rollout yang bisa dibalik cepat.

Canary dan progressive rollout

Rilis ke sebagian kecil traffic atau tenant lebih dulu. Ini tidak menyelesaikan masalah lisensi, tetapi mengurangi blast radius jika perubahan dependency menimbulkan kegagalan koneksi, timeout, atau perilaku SDK yang tak terduga.

Feature flag untuk integrasi vendor

Jika komponen tertentu bergantung pada layanan pihak ketiga, letakkan di balik feature flag atau adapter. Dengan begitu, saat vendor mengubah kebijakan atau endpoint, Anda bisa mematikan fitur non-kritis tanpa menarik seluruh rilis.

Artifact promotion, bukan rebuild per environment

Build sekali, verifikasi sekali, lalu promosi artefak yang sama dari staging ke production. Jika Anda membangun ulang di setiap environment, hasil dependency atau metadata bisa berbeda, dan kontrol lisensi menjadi lebih sulit dipercaya.

Rollback yang memakai artefak tervalidasi

Pastikan rollback menunjuk ke artefak lama yang checksum, SBOM, dan metadata-nya masih tersedia. Rollback yang membangun ulang dari source lama bisa gagal jika dependency upstream sudah berubah atau hilang.

Checklist deprecation risk untuk dependency dan vendor

Selain gate CI, tim perlu checklist review berkala agar risiko tidak menumpuk diam-diam.

Checklist dependency

  • Apakah paket memiliki maintainer aktif?
  • Apakah lisensi saat ini jelas dan terdokumentasi?
  • Apakah ada riwayat perubahan lisensi atau dual licensing yang perlu dipantau?
  • Apakah package source dan checksumnya bisa diverifikasi?
  • Apakah paket tersedia di mirror internal?
  • Apakah ada alternatif yang kompatibel jika paket ditarik atau dibatasi?
  • Apakah lockfile dan base image sudah dipin?

Checklist layanan/vendor pihak ketiga

  • Apakah ada SLA atau jaminan akses yang relevan untuk build/runtime?
  • Apakah ada batas kuota, kebijakan auth, atau syarat distribusi yang bisa berubah?
  • Apakah SDK/vendor menjadi dependency hard atau bisa diganti adapter?
  • Apakah ada mode operasi terbatas jika layanan gagal?
  • Apakah data, artefak, atau model bisa diekspor jika vendor dihentikan?
  • Apakah tim punya runbook untuk deprecation atau shutdown mendadak?

Kesalahan umum yang sering terjadi

  • Mengandalkan scanner sebagai sumber kebenaran tunggal. Metadata lisensi bisa salah atau kosong.
  • Hanya memeriksa dependency langsung. Risiko sering ada di dependency transitif.
  • Mengizinkan update otomatis tanpa policy gate. Otomasi bagus, tetapi harus dibatasi oleh aturan merge.
  • Menyimpan SBOM terpisah dari artefak release. Akibatnya sulit membuktikan SBOM itu milik build yang mana.
  • Tidak punya mirror atau cache tervalidasi. Build menjadi rapuh terhadap perubahan eksternal.
  • Rollback mengandalkan rebuild. Ini gagal ketika upstream dependency sudah berubah.

Tips debugging saat pipeline mendadak gagal karena perubahan dependency

  1. Bandingkan lockfile dan dependency tree antara build terakhir yang hijau dan build gagal.
  2. Periksa apakah checksum artefak upstream berubah meski nomor versi tetap sama.
  3. Lihat hasil scan lisensi sebelumnya untuk mencari perubahan kategori allow/review/deny.
  4. Validasi sumber unduhan: registry utama, mirror internal, atau fallback cache.
  5. Cek apakah base image berubah jika Anda masih memakai tag mutable.
  6. Uji rebuild offline atau via mirror internal untuk memastikan masalahnya benar-benar ada pada upstream.

Jika insiden disebabkan perubahan kebijakan vendor, dokumentasikan hasilnya ke dalam policy dan runbook. Tujuannya bukan hanya memulihkan rilis saat ini, tetapi mengurangi peluang kejadian serupa terulang.

Rancangan minimum yang layak diterapkan

Jika tim Anda belum memiliki sistem yang matang, mulai dari paket minimum berikut:

  1. pakai lockfile dan larang build dari dependency yang tidak terkunci,
  2. tambahkan gate CI untuk license scanning pada PR dan main branch,
  3. hasilkan SBOM untuk setiap release artifact,
  4. simpan checksum dan metadata artefak release,
  5. gunakan approval manual untuk release berisiko,
  6. siapkan mirror internal untuk dependency penting,
  7. lakukan rollout bertahap dengan opsi rollback ke artefak tervalidasi.

Setelah itu, baru tambah attestasi provenance, signing, atau policy yang lebih granular. Pendekatan bertahap lebih realistis daripada mencoba membangun seluruh kontrol supply chain sekaligus.

Penutup

Pipeline rilis yang tahan risiko saat dependensi lisensi berubah adalah kombinasi kontrol teknis dan kebijakan operasional. Kuncinya bukan menebak semua perubahan yang mungkin terjadi, melainkan memastikan pipeline dapat mendeteksi perubahan penting, menghentikan rilis saat perlu, dan tetap menyediakan jalur aman untuk membangun, memverifikasi, serta merilis produk.

Jika produk Anda masih bergantung penuh pada registry publik, paket yang tidak dipin, approval informal, dan rollback berbasis rebuild, maka risiko utamanya bukan hanya compliance. Risiko sebenarnya adalah kehilangan kemampuan untuk memelihara dan merilis software ketika pihak luar mengubah aturan permainan.