Changelog dari chapter sebelumnya menjawab “apa yang berubah” — tanda tangan menjawab “siapa pembuatnya, dan bisakah dibuktikan?”. Isi commit terkunci oleh hash-nya, tetapi identitas di dalamnya berupa nama dan email yang ditulis bebas. Chapter penutup section ini menandatangani commit dan tag dengan GPG, membuktikan tandanya dari tiga sisi, lalu meninjau alternatif kunci SSH.

Mengapa Rilis Perlu Ditandatangani #

Kolom user.name dan user.email pada commit adalah klaim, bukan fakta: siapa pun bisa menuliskan identitas orang lain, dan Git tidak memeriksanya. Hash commit menjaga isi tetapi tidak mengikat identitas pembuat. Tanda tangan kriptografis menutup dua celah itu: kunci privat penandatangani membubuhkan tanda pada isi commit atau tag, dan pemegang kunci publik terkait bisa memverifikasi dua jaminan — autentik (tanda hanya lahir dari kunci privat) dan utuh (isi tak berubah sejak ditandatangani). Platform hosting memeriksa tanda tersebut lalu menampilkan lencana “Verified” pada commit dan tag yang lolos.

Memeriksa GPG dan Menyiapkan Kunci Latihan #

Git membuat tanda tangan lewat alat eksternal; untuk format OpenPGP alatnya gpg (GnuPG). Periksa ketersediaannya:

bash
gpg --version

Output yang Dihasilkan:

text
gpg (GnuPG) 2.4.7
libgcrypt 1.11.0
(dipotong — sisa keluaran berisi lisensi, direktori home, dan daftar algoritma)

Mesin latihan memakai GnuPG 2.4.7; sisa keluarannya lisensi dan daftar algoritma. Bila gpg tidak dikenal, pasang paket gnupg lewat manajer paket.

Kunci sendiri dibuat interaktif lewat gpg --full-generate-key. Sandbox menyiapkan kunci latihan Budi Santoso di gnupg-key/ — kita impornya ke keyring terpisah lewat GNUPGHOME agar keyring pribadi tak tersentuh:

bash
export GNUPGHOME=/tmp/gnupg-tags
gpg --import gnupg-key/secret.asc
gpg --import-ownertrust gnupg-key/ownertrust.txt

Key ID yang dipasang ke Git kita baca dari keyring tersebut:

bash
gpg --list-secret-keys --keyid-format long

Output yang Dihasilkan:

text
/tmp/gnupg-tags/pubring.kbx
---------------------------
sec   ed25519/94168B32ED11AC2A 2026-10-13 [SCA]
      314E3367582B669B265839D394168B32ED11AC2A
uid                 [ultimate] Budi Santoso <[email protected]>
ssb   ed25519/9160EE9F9DBAD0E7 2026-10-13 [SA]

Baris sec memuat kunci utama: algoritma ed25519, key ID 94168B32ED11AC2A, kemampuan [SCA] (sign, certify, authenticate); ssb mencatat subkey penandatanganan, uid identitas pemiliknya. Key ID di baris sec itulah yang dipasang ke user.signingkey; jalur keyring menyesuaikan GNUPGHOME.

Kualitas kunci tak bisa ditawar: SHA-1 dianggap patah sejak serangan tumbukan 2017, dan kunci pendek tergolong lelawas. Eksperimen berikut meminta kunci RSA 768 bit di keyring percobaan:

bash
printf '%s\n' '%no-protection' 'Key-Type: rsa' 'Key-Length: 768' \
  'Subkey-Type: rsa' 'Subkey-Length: 768' \
  'Name-Real: Budi Santoso' 'Name-Email: [email protected]' \
  'Expire-Date: 0' '%commit' > /tmp/genkey-lemah.txt
GNUPGHOME=/tmp/gnupg-lemah gpg --batch --generate-key /tmp/genkey-lemah.txt 2>&1 | grep -F 'keysize invalid'

Output yang Dihasilkan:

text
gpg: keysize invalid; using 3072 bits
gpg: keysize invalid; using 3072 bits

Dua baris itu muncul karena kunci utama dan subkey sama-sama ditolak: GnuPG 2.4.7 menolak ukuran di bawah ambang aman, lalu melanjutkan dengan 3072 bit.

Menandatangani Commit #

Repository latihan-tanda disetel seperti biasa plus satu config: user.signingkey memakai key ID dari daftar kunci tadi.

bash
mkdir latihan-tanda && cd latihan-tanda
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
git config user.signingkey 94168B32ED11AC2A

Semua perintah config sunyi. Commit pertama tanpa tanda sebagai pembanding, commit kedua ditandatangani lewat opsi -S:

bash
printf '# Toko Berkah\nberanda\n' > situs.md
git add situs.md
git commit -m "Buat beranda toko"
printf '# Toko Berkah\nberanda\nmenu: beranda\n' > situs.md
git add situs.md
git commit -S -m "Tandatangani perubahan beranda"

Output yang Dihasilkan:

text
[main b562201] Tandatangani perubahan beranda
 1 file changed, 1 insertion(+)

Keluaran komit tampak biasa — tandanya tersimpan di dalam objek commit, bukan di ringkasan.

Membuktikan Tanda Tangan Commit #

git log --show-signature menampilkan commit beserta hasil verifikasi tandanya:

bash
git log --show-signature -1

Output yang Dihasilkan:

text
commit b5622016b9af1291ef708d1a7e4d08da18c23b33
gpg: Signature made Wed Oct 28 10:10:00 2026 WIB
gpg:                using EDDSA key DA8040AE72612B94F7F3D3FC9160EE9F9DBAD0E7
gpg: Good signature from "Budi Santoso <[email protected]>" [ultimate]
Author: Budi Santoso <[email protected]>
Date:   Wed Oct 28 10:10:00 2026 +0700

    Tandatangani perubahan beranda

Baris pertama memuat hash commit b562201. Tiga baris gpg: adalah hasil verifikasi GnuPG: tanda dibuat 28 Oktober 2026 pukul 10:10 WIB, memakai kunci EDDSA ber-ID DA8040AE..., vonisnya Good signature dari “Budi Santoso” dengan kepercayaan ultimate (keyring latihan memegang kunci privatnya).

Kedua, git cat-file -p HEAD membongkar isi objek commit seperti tersimpan di database:

bash
git cat-file -p HEAD

Output yang Dihasilkan:

text
tree 06b768f38fdbfbc85ca4d3df8f9ccf9b63982ae3
parent 4ad357dd0b4293c9a15f502f315596f55d615f45
author Budi Santoso <[email protected]> 1793157000 +0700
committer Budi Santoso <[email protected]> 1793157000 +0700
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQTagECucmErlPfz0/yRYO6fnbrQ5wUCauFniAAKCRCRYO6fnbrQ
 5yTbAQCqWrkVAneSEsxcWiCnT/2By6fcSiJYBjRRMe3DTcFHKQD9EPTMbxMwRCyV
(dipotong — sisa baris tanda tangan dan pesan commit)

Header gpgsig muncul setelah baris committer: tanda tangan ASCII-armored tersimpan di dalam objek commit itu sendiri, bukan berkas terpisah. Angka 1793157000 adalah cap waktu Unix epoch, setara 2026-10-28 10:10 WIB. Ketiga, perintah verifikasi khusus:

bash
git verify-commit HEAD

Output yang Dihasilkan:

text
gpg: Signature made Wed Oct 28 10:10:00 2026 WIB
gpg:                using EDDSA key DA8040AE72612B94F7F3D3FC9160EE9F9DBAD0E7
gpg: Good signature from "Budi Santoso <[email protected]>" [ultimate]

git verify-commit memeriksa satu commit dan keluar kode 0 bila tanda sah — cocok untuk skrip. Tiga perintah di atas membaca objek yang sama.

Menandatangani Tag Rilis #

Tag memakai mekanisme yang sama lewat opsi -s — huruf kecil, sedikit beda dari -S milik commit:

bash
git tag -s v1.0.0 -m "Rilis pertama yang ditandatangani"

Verifikasi memakai git tag -v — yang di chapter Annotated Tag berhenti dengan galat error: no signature found:

bash
git tag -v v1.0.0

Output yang Dihasilkan:

text
gpg: Signature made Wed Oct 28 10:15:00 2026 WIB
gpg:                using EDDSA key DA8040AE72612B94F7F3D3FC9160EE9F9DBAD0E7
gpg: Good signature from "Budi Santoso <[email protected]>" [ultimate]
object b5622016b9af1291ef708d1a7e4d08da18c23b33
type commit
tag v1.0.0
tagger Budi Santoso <[email protected]> 1793157300 +0700

Rilis pertama yang ditandatangani

Tiga baris gpg: di awal membuktikan tanda tag sah: Good signature dari pemegang kunci Budi Santoso, dibuat pukul 10:15 WIB. Setelah itu isi objek tag tercetak utuh — object, type, tag, tagger, pesan rilis: persis struktur annotated tag, kini dengan tanda tangan. Struktur mentahnya:

bash
git cat-file -p v1.0.0

Output yang Dihasilkan:

text
object b5622016b9af1291ef708d1a7e4d08da18c23b33
type commit
tag v1.0.0
tagger Budi Santoso <[email protected]> 1793157300 +0700

Rilis pertama yang ditandatangani
-----BEGIN PGP SIGNATURE-----

iHUEABYKAB0WIQTagECucmErlPfz0/yRYO6fnbrQ5wUCauFotAAKCRCRYO6fnbrQ
5xNbAP9cM7/roGZPry1ZC4s5bfO08fKNZ+OuE2K0aAYjqS3BFQD/eRGpTyetYAVX
lrZzhMt2t3/My0aByPXJ8y93nHuc1AM=
=/Rd5
-----END PGP SIGNATURE-----

Blok -----BEGIN PGP SIGNATURE----- hingga -----END PGP SIGNATURE----- tersimpan di dalam objek tag setelah pesan rilis; hash objek berbeda di mesin pembaca — pola strukturnya yang penting. Tag bertanda tangan di-push seperti tag biasa (Berbagi Tag ke Remote ); opsi -s, -v, dan tag.gpgSign terbaca di git-tag .

Menandatangani Otomatis untuk Semua Commit #

Config commit.gpgsign membuat Git menandatangani setiap commit tanpa opsi -S:

bash
git config commit.gpgsign true
printf '# Toko Berkah\nberanda\nmenu: beranda | kontak\n' > situs.md
git add situs.md
git commit -m "Rapikan teks beranda"

Output yang Dihasilkan:

text
[main 1a69647] Rapikan teks beranda
 1 file changed, 1 insertion(+), 1 deletion(-)

Keluaran komit tetap biasa. Verifikasi membuktikan sebaliknya:

bash
git verify-commit HEAD

Output yang Dihasilkan:

text
gpg: Signature made Wed Oct 28 10:20:00 2026 WIB
gpg:                using EDDSA key DA8040AE72612B94F7F3D3FC9160EE9F9DBAD0E7
gpg: Good signature from "Budi Santoso <[email protected]>" [ultimate]

Commit “Rapikan teks beranda” ternyata juga bertanda, dibuat pukul 10:20 WIB — config bekerja. Dokumentasi git-commit mencatat konsekuensinya: rebase menandatangani ulang banyak commit sekaligus, dan gpg-agent membantu agar passphrase tak diketik berulang. Padanannya untuk tag bernama tag.gpgSign.

GPG atau SSH #

Sejak Git 2.34, tanda tangan bisa dibuat dengan kunci SSH — kunci yang mungkin sudah dipakai untuk akses [email protected]. Tiga config berikut mengalihkan formatnya:

bash
git config gpg.format ssh
git config user.signingKey ~/.ssh/id_ed25519.pub
git config gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers

Nilai user.signingKey untuk format SSH bisa berupa jalur kunci privat, jalur kunci publik saat ssh-agent aktif, atau kunci publik mentah berprefiks key::. Verifikasi oleh pihak lain memakai berkas allowed signers yang memetakan identitas ke kunci publik — pembahasan lengkapnya di chapter SSH Signing ; rincian seluruh config terbaca di git-config . Perbandingan dua formatnya:

AspekGPG (OpenPGP)SSH
Nilai gpg.formatopenpgp (bawaan)ssh
Alat pembuat tandagpg (GnuPG)ssh-keygen
Nilai user.signingKeykey ID, mis. 94168B32ED11AC2Ajalur atau isi kunci SSH
Verifikasi pihak lainkeyring GPG / web of trustberkas allowed signers
Kunci yang dikelolakunci GPG tersendirikunci SSH akses yang sudah ada
Pas untukproyek open source, rilis publiktim yang sudah seragam memakai SSH

Nilai x509 (lewat gpgsm) juga didukung untuk sertifikat organisasi, meski jarang dipakai proyek web. Dengan tanda tangan, section ini lengkap: tag menyimpan versi, alur rilis menggulirkannya, changelog menceritakan, tanda tangan membuktikan. Satu urusan tersisa di repo toko — sampah build dan berkas rahasia yang tak boleh dilacak — pembahasannya membuka section baru: .gitignore .