Pemindaian menjawab cacat apa yang dibawa katalog-web:2.0, tetapi jawaban itu bergantung pada satu asumsi yang belum pernah kita uji: bahwa image yang dipindai memang image yang dibangun tim kita. Tiga pertanyaan sederhana cukup untuk meruntuhkan asumsi itu — image ini dibangun oleh siapa, dari source apa, dengan builder yang bagaimana? Tag 2.0 tidak menjawab satu pun dari ketiganya: tag hanyalah penunjuk yang bisa dipindahkan siapa pun yang memegang hak push ke repository, dan kita sudah membuktikan sifat mudah pindah itu pada Chapter Image Digest. Chapter ini membangun jawaban yang tidak bisa ditiru: provenance — metadata asal-usul yang tercipta otomatis di dalam proses build, tersimpan sebagai attestation di samping image, dan bisa diverifikasi kapan pun oleh siapa pun yang memegang digest-nya.

Provenance sebagai Attestation #

Attestation adalah klaim yang menempel pada sebuah image di registry: berkas manifest OCI yang bukan image runnable, melainkan metadata yang menjelaskan image di sebelahnya. Docker buildx menghasilkan dua attestation yang saling melengkapi. Provenance menjawab pertanyaan sang pembuktian: build bagaimana yang melahirkan image ini — builder apa, source repository mana, commit hash berapa, flag build apa, dan kapan. SBOM menjawab pertanyaan sang pemeriksa: paket apa saja yang dibawa image — inventaris yang sama dengan fondasi pemindaian pada Chapter Image Scanning. Keduanya lahir di dalam builder, diseret bersama image saat push, dan karena itu jauh lebih sulit dipalsukan daripada catatan yang ditulis manusia setelah kejadian.

Build dengan Provenance dan SBOM #

Budi membangun ulang rilisnya sebagai image dua platform — pola cross-build yang kita kenal dari Chapter Target Platform — kali ini dengan kedua attestation dinyalakan penuh:

bash
$ docker buildx build --platform linux/amd64,linux/arm64 \
    --provenance=mode=max --sbom=true \
    -t budi/katalog-web:2.0 --push .

Output yang Dihasilkan (dipotong):

text
[+] Building 26.3s (20/20) FINISHED
 => [linux/amd64 1/8] FROM docker.io/library/node:22-alpine            0.0s
...
 => exporting to image                                                  1.4s
 => => exporting layers                                                 1.0s
 => => exporting manifest sha256:f82cb306261ee610ed26a4b00be6d8b0676b3336fd47c2eb0d586670c925b3f1
...
 => => exporting attestation manifest sha256:cd748e50b84fb8188d90fe032f580c8637dbfe601a133c10bf83b635e5f44238
...
 => => exporting manifest list sha256:3b2e88c968c6ab0def61437a20a7894445faaa1b87da95d13f29bbdb4258b1c3
 => => pushing layers                                                  12.4s
 => => pushing manifest for docker.io/budi/katalog-web:2.0              1.2s

Mari kita telaah tiga flag yang membedakan build ini:

  1. --provenance=mode=max — menyalakan attestation provenance dalam mode paling kaya: seluruh konteks build ikut tercatat, termasuk argumen build dan metadata source; mode mode=min yang lebih ramping sebenarnya sudah menjadi bawaan setiap build yang di-push lewat buildx, sehingga flag ini berarti “buktikan lebih banyak”, bukan “mulai membuktikan”.
  2. --sbom=true — memerintahkan builder menyusun inventaris paket dari isi image dan menyimpannya sebagai attestation kedua; scanner seperti Scout tinggal membacanya tanpa mengunduh ulang seluruh layer.
  3. --push — mengirim hasil langsung ke registry; attestation memang dirancang hidup di registry, menempel pada manifest yang sama dengan image-nya.

Verifikasi dengan imagetools inspect #

Klaim harus bisa diperiksa, dan pemeriksaannya tidak butuh alat rahasia: docker buildx imagetools inspect membuka isi index yang ditunjuk tag:

bash
$ docker buildx imagetools inspect budi/katalog-web:2.0

Output yang Dihasilkan (dipotong):

text
Name:      docker.io/budi/katalog-web:2.0
MediaType: application/vnd.oci.image.index.v1+json
Digest:    sha256:3b2e88c968c6ab0def61437a20a7894445faaa1b87da95d13f29bbdb4258b1c3

Manifests:
  Name:        docker.io/budi/katalog-web:2.0@sha256:f82cb306261ee610ed26a4b00be6d8b0676b3336fd47c2eb0d586670c925b3f1
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    linux/amd64

  Name:        docker.io/budi/katalog-web:2.0@sha256:0a202c2540b1d1f3e3f75e2f927ae606367724f68d8633e022a69b473d056351
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    linux/arm64

  Name:        docker.io/budi/katalog-web:2.0@sha256:cd748e50b84fb8188d90fe032f580c8637dbfe601a133c10bf83b635e5f44238
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    unknown/unknown
  Annotations:
    vnd.docker.reference.type:   attestation-manifest
    vnd.docker.reference.digest: sha256:f82cb306261ee610ed26a4b00be6d8b0676b3336fd47c2eb0d586670c925b3f1
...

Mari kita telaah isi index tersebut:

  1. Digest milik index di baris atas — identitas sebenarnya dari tag 2.0: daftar manifest yang menempel di bawahnya; inilah digest yang kita pakai untuk memverifikasi segala hal tentang rilis ini, sesuai disiplin dari Chapter Image Digest.
  2. Dua manifest ber-Platform nyata — image linux/amd64 dan linux/arm64, masing-masing dengan digest sendiri; server yang menarik budi/katalog-web:2.0 diam-diam memilih salah satunya sesuai arsitekturnya.
  3. Entri unknown/unknown ber-annotation attestation-manifest — manifest yang bukan image runnable: vnd.docker.reference.type menyatakan jenisnya attestation, dan vnd.docker.reference.digest menunjuk manifest platform mana yang dibuktikannya — pada baris ini, attestation milik image amd64; entri serupa untuk arm64 menyusul di baris yang terpotong.

Level Kematangan SLSA #

Provenance yang bisa diverifikasi adalah fondasi kerangka SLSA — peta kematangan keamanan rantai pasok perangkat lunak yang naik tiga level:

Level SLSAYang dijaminPadanan praktiknya
1build terdokumentasi — provenance ada dan bisa diverifikasibuildx dengan --provenance=mode=max
2hosted build — platform build yang menahan upaya ubahCI terkelola yang menandatangani provenance-nya
3hardened build — isolasi kuat antar build yang tak saling mengintipplatform build dengan isolasi terverifikasi

Tangga ini menegaskan posisi kita: dua flag pada docker buildx build sudah mengantarkan image ke SLSA level 1 secara jujur — provenance terdokumentasi dan diverifikasi. Naik ke level berikutnya bukan soal flag lagi, melainkan soal di mana build dijalankan dan siapa yang menjamin integritas platformnya.

Tanda Tangan yang Terikat Digest #

Attestation menjelaskan asal-usul; tanda tangan mengunci keaslian. Alat cosign dari ekosistem Sigstore menandatangani image — dan pilihan argumennya adalah pelajaran utamanya, karena yang ditandatangani adalah digest, bukan tag:

bash
$ cosign sign budi/katalog-web@sha256:3b2e88c968c6ab0def61437a20a7894445faaa1b87da95d13f29bbdb4258b1c3

Output yang Dihasilkan:

text
tlog entry created with index: 18345672

Signature tercatat di transparency log publik, terikat pada byte-byte image lewat digest index. Saudara kembarnya cosign verify memeriksa tanda tangan itu pada digest yang sama: siapa pun yang memindahkan tag 2.0 ke manifest lain tidak akan membawa serta tanda tangan — verifikasi langsung gagal karena digest yang ditunjuk sudah tidak cocok. Inilah jawaban teknis atas skenario tag yang ditiru di pembuka chapter.

Trusted Content di Docker Hub #

Verifikasi provenance menuntut alat; kepercayaan juga bisa dimulai dari sisi penerbit. Docker Hub menandai dua kelas seperti itu — pembahasan lengkapnya ada di Chapter Docker Hub: Official Images di namespace library/ dikurasi langsung oleh Docker (nginx, postgres, node — seluruh image yang kita pakai sepanjang course), dan Verified Publisher menandai repository milik organisasi yang telah memverifikasi identitasnya. Label ini bukan pengganti provenance dan pemindaian, tetapi menyaring pilihan pertama dengan jauh lebih baik daripada mengambil image acak dengan nama yang mirip.

Satu image kini membawa bukti asal-usulnya sendiri. Namun image tidak pernah berdiri sendiri: image lahir dari source code, dependensi, base image, dan mesin build — dan setiap mata rantai itu adalah tempat orang jahat bisa masuk. Chapter Supply Chain Security memanjangkan pengawasan dari satu image menjadi seluruh rantai pasoknya, dari repository sampai server produksi.

Referensi #