SBOM: Cek Lisensi Sebelum Serah Terima Perangkat Lunak
Daftar komponen perangkat lunak membantu memeriksa lisensi sebelum rilis. Terapkan pemindaian dan aturan pemeriksaan pada proses kompilasi.
Untuk Tim Teknis

Daftar isi
Layanan Node dapat memuat ratusan atau ribuan paket ketika dependensi tidak langsung ikut dihitung. Ukur jumlah dalam rilis yang sebenarnya. Setiap paket punya lisensi. Sebagian kecil dari lisensi itu membawa kewajiban yang harus dipenuhi saat serah terima.
SBOM, singkatan dari software bill of materials, adalah daftar komponen perangkat lunak yang dibuat otomatis. Lengkapi daftar ini dengan pemeriksaan kebijakan lisensi dalam integrasi berkelanjutan atau CI, agar komponen bermasalah terdeteksi sebelum produk dikirim.
Bayangkan SBOM seperti daftar komposisi di kemasan makanan. Isinya daftar lengkap semua bahan yang masuk ke kompilasi Anda, dibuat otomatis. Pemeriksaan kebijakan menghentikan alur otomatis jika ada komponen yang tidak boleh dikirim kepada klien.
Lisensi yang memerlukan perhatian khusus sudah saya bahas terpisah di artikel lisensi sumber terbuka. Artikel ini soal cara tahu isi kompilasi Anda sebenarnya apa.
Manifest itu klaim, bukan fakta
Daftar dari npm ls belum cukup untuk memastikan lisensi. Kolom lisensi dalam manifes paket diisi oleh pembuat paket sendiri dan belum tentu telah diverifikasi.
Ada paket yang menulis MIT di package.json, padahal di dalam lib/ ada berkas kode sumber hasil salin dengan header GPL. Ada paket yang tidak menulis lisensi sama sekali. Ada juga kolom lisensi berisi SEE LICENSE IN LICENSE.txt yang menunjuk ke berkas yang tidak pernah ikut terbit di tarball.
SPDX, standar SBOM yang lebih tua, memisahkan dua hal ini secara eksplisit. Dalam format paket SPDX 2.3, tersedia kolom licenseDeclared, yaitu klaim proyeknya sendiri. Ada juga kolom licenseConcluded, yaitu hasil analisis Anda.
Alat sederhana umumnya hanya mengisi kolom pertama. Pemindai level berkas seperti ScanCode Toolkit membaca header kode sumber aslinya untuk mengisi kolom kedua.
Untuk kebanyakan pekerjaan serah terima, pemindaian lisensi yang dideklarasikan sudah menangkap masalah yang jelas. Contohnya paket AGPL yang masuk sprint lalu, atau helper model berlisensi nonkomersial. Pemindaian tingkat berkas baru perlu saat tim legal klien minta bukti, bukan sekadar pernyataan. Perlu juga saat satu basis kode mau berpindah tangan dan jawabannya berdampak ke harga.
Dua format, dan pilihannya tidak terlalu penting
SPDX dan CycloneDX sama-sama bisa dipakai. SPDX lahir dari Linux Foundation dan sudah jadi standar ISO/IEC 5962:2021. CycloneDX lahir dari OWASP dengan fokus keamanan, lalu diadopsi sebagai ECMA-424 pada 2024.
Pilih berdasarkan siapa yang mengonsumsi hasilnya. Kalau tim kepatuhan klien sudah punya alur kerja sendiri, ikuti format mereka. Kalau tidak ada yang punya preferensi, CycloneDX JSON lebih enak dibaca dan diolah, sedangkan SPDX punya lebih banyak alat legal di sekitarnya.
Konversi antar keduanya juga rutin, dan syft sendiri bisa menghasilkan dua-duanya. Tentukan format sesuai kebutuhan penerima. Yang lebih penting adalah membuat SBOM secara rutin dan menindaklanjuti temuannya.
Cara membuatnya
Syft (Apache-2.0) jadi pilihan utama saya. Alat ini membaca direktori kode sumber, citra kontainer, atau artefak hasil kompilasi, lalu mengeluarkan SPDX atau CycloneDX:
syft dir:. -o cyclonedx-json=sbom.json
syft registry.example.com/app:2.4.1 -o spdx-json=sbom-image.json
Alat bawaan tiap ekosistem menggali lebih dalam di bahasanya sendiri, jadi layak dijalankan berdampingan:
cargo deny check licenses— Rust, sudah punya allow/deny list dan evaluasi ekspresi SPDX di dalamnyago-licenses report— Go, mencari berkas lisensi per modulpip-licenses— Python, membaca metadata distribusi yang terpasang
Alat Rust menggabungkan kebijakan dan pemindaian. Jika ada pelanggaran, alat mengembalikan kode keluar selain nol, sehingga alur CI dapat dihentikan tanpa skrip tambahan.
Hubungkan temuan lisensi dengan keputusan CI
SBOM perlu digunakan dalam keputusan peluncuran, bukan hanya disimpan. Kelompokkan lisensi menjadi tiga hasil pemeriksaan berikut, lalu terapkan dalam CI.
Lolos diam-diam — MIT, BSD-2-Clause, BSD-3-Clause, ISC, Apache-2.0, Zlib. Semuanya permisif, kewajibannya perlu diperiksa pada teks lisensi, dan itu ditangani langkah NOTICE di bawah.
Gagalkan kompilasi — AGPL-3.0, SSPL, BUSL-1.1, varian Creative Commons nonkomersial, dan string kosong. Ini kebijakan penyaringan awal untuk produk tertutup, bukan kesimpulan hukum otomatis. AGPL dan SSPL memiliki ketentuan jaringan yang berbeda; kasus pemakaian yang disetujui dapat diberi pengecualian terdokumentasi setelah pemeriksaan teks dan arsitektur. BUSL karena selama periode sebelum perubahan lisensinya, komponen tersebut belum menggunakan lisensi sumber terbuka. CC nonkomersial karena serah terima komersial justru pekerjaan yang sedang Anda kerjakan.
String kosong masuk daftar gagal karena tanpa teks lisensi berarti tidak ada izin yang diberikan. Posisinya lebih buruk daripada lisensi restriktif, bukan lebih aman.
Tandai untuk pemeriksaan manusia — LGPL-2.1, LGPL-3.0, MPL-2.0, EPL-2.0, dan GPL-2.0 dengan classpath exception. Penggunaannya perlu memenuhi syarat lisensi masing-masing. LGPL masih bisa dipakai saat dynamic linking (pustaka dimuat terpisah saat program jalan) dan perlu mekanisme pemenuhan tambahan saat static linking (ditanam mati ke dalam program), jadi jawabannya bergantung pada cara Anda mengirimkannya. MPL menerapkan kewajiban copyleft pada tingkat berkas: perubahan pada berkas yang tercakup harus memenuhi ketentuan penyediaan sumbernya. Periksa berkas mana yang diubah.
Pemeriksaan perlu memahami ekspresi lisensi SPDX, bukan hanya membandingkan satu teks lisensi. Satu paket bisa menulis MIT OR Apache-2.0, Apache-2.0 WITH LLVM-exception, atau MIT AND BSD-3-Clause.
Perbandingan string persis akan menolak MIT OR Apache-2.0, padahal keduanya sama-sama boleh. Gunakan alat yang dapat mengurai ekspresi tersebut. Penolakan keliru yang berulang membuat tim cenderung mengabaikan pemeriksaan.
Citra kontainer adalah pohon dependensi kedua
Pemindaian pada tingkat aplikasi melewatkan lapisan sistem operasi. Padahal satu jenis kejutan khas justru bersembunyi di sana.
Contoh paling jelas: ffmpeg yang dipasang lewat apt di Debian atau Ubuntu. Paket itu dibangun dengan encoder berlisensi GPL seperti libx264 dan libx265, jadi berkas biner hasilnya didistribusikan di bawah GPL.
Cerita LGPL yang sering diulang orang soal FFmpeg berlaku untuk kompilasi yang dikonfigurasi tanpa komponen itu. Hampir tidak ada yang membangun sendiri. Semua orang menjalankan apt-get install ffmpeg, dan citra kontainernya mewarisi berkas biner GPL yang tidak akan pernah muncul di pemindaian package.json.
Kewajiban yang perlu dipenuhi bergantung pada cara produk didistribusikan. Berkas biner GPL yang dipanggil sebagai proses terpisah di layanan yang Anda operasikan sendiri berbeda posisinya dengan berkas biner yang sama di dalam appliance yang diserahkan ke klien. Bagaimanapun, lapisan OS harus dipindai dulu sebelum pertanyaannya bisa diajukan.
Atribusi adalah kewajiban yang paling sering dilanggar
Semua lisensi permisif di allow list tadi tetap menuntut satu hal: cantumkan ulang pemberitahuan hak cipta dan teks lisensinya di distribusi Anda. MIT menyatakannya dalam satu kalimat. Apache-2.0 menjabarkannya di empat klausul, plus kewajiban menyertakan berkas NOTICE kalau proyek asalnya punya.
Ini kewajiban yang paling sering dilanggar di perangkat lunak komersial, sekaligus yang paling murah diperbaiki. Buat berkas atribusi pihak ketiga dari SBOM saat kompilasi, lalu kirimkan bersama produk. Bisa di pemasang, di layar tentang, atau di folder docs sebelah berkas biner.
Langkah otomatis ini membantu memenuhi kewajiban atribusi yang sering diperiksa saat audit kepatuhan.
Yang tidak akan ditemukan pemindai mana pun
Tiga kategori berikut tetap memerlukan pemeriksaan manusia karena daftar paket saja tidak mencakup semuanya.
SDK biner tanpa manifest. File AAR dari vendor, DLL tertutup, atau pustaka driver yang diserahkan lewat flashdisk. Tidak ada metadata paket, tidak ada berkas lisensi, tidak ada yang dapat dipindai. Itu urusan kontrak yang diselesaikan sebelum integrasi, bukan saat kompilasi.
Model bobot dan kumpulan data. Package pip berlisensi Apache-2.0 bisa mengunduh bobot berlisensi riset nonkomersial saat pertama dijalankan. SBOM melihat paketnya dan melaporkannya bersih. Lisensi kode, lisensi bobot, dan lisensi kumpulan data adalah tiga izin yang terpisah.
Kode hasil salin-tempel. Potongan dari jawaban forum, contoh dari repositori orang lain, fungsi yang diambil dari satu blog post. Tidak ada entri dependensi, jadi tidak ada pemindai yang melaporkannya. Pemindai level berkas menangkap sebagiannya saat header lisensi lengkap ikut tersalin. Itu satu alasan menjalankannya sebelum basis kode berpindah tangan.
Simpan SBOM bersama rilisnya
Buat SBOM per rilis dan simpan sebagai artefak rilis di sebelah berkas binernya. Simpan di tempat arsip rilis yang dapat dikelola tim.
Alasannya praktis. Delapan belas bulan setelah serah terima, auditor klien bertanya isi versi 2.3.1 apa saja. Atau muncul CVE di sebuah pustaka dan Anda perlu tahu versi mana saja yang sudah diterapkan memakainya.
Membuat ulang SBOM dari penanda versi git tidak membuktikan isi yang diterapkan. Lockfile dengan versi persis dan pemasangan yang mematuhi berkas itu membantu pengulangan hasil, tetapi paket asal bisa ditarik dan lingkungan kompilasi bisa berbeda. SBOM dari artefak rilis mencatat komponen yang ditemukan alat pemindai; cakupannya tetap perlu diperiksa.
Arah regulasi juga sama. EU Cyber Resilience Act mewajibkan produsen produk dengan elemen digital menyusun SBOM yang minimal mencakup dependensi level atas. Kewajiban pelaporan kerentanannya mulai berlaku 11 September 2026, dan berlaku penuh pada 11 Desember 2027. Produsen yang menempatkan produk dalam cakupan aturan di pasar Uni Eropa perlu menilai kewajiban ini beserta pengecualiannya.
Kesimpulan
Buat SBOM di CI. Saring dengan kebijakan allow, deny, dan pemeriksaan yang paham ekspresi SPDX. Pindai citra kontainer serta repositorinya. Hasilkan berkas NOTICE dari data yang sama, lalu arsipkan SBOM bersama rilis.
Langkah ini mendokumentasikan komponen dalam rantai dependensi. Tetap periksa SDK biner, bobot model, dan kode salin-tempel secara terpisah. Tentukan penanggung jawabnya agar izin yang tidak tercatat tidak baru ditemukan saat serah terima.
Artikel Terkait
Ceritakan kendala operasional Anda agar kita dapat membahas langkah yang sesuai.