IlmHamroh
JavaScript Full-stack/32-qism. Professional Git va jamoada ishlash4/19-dars18 daqiqa
Mundarija (33)

Commit imzolash: SSH va GPG imzo, Verified belgisi

Qisqacha: Git'da commit muallifi — oddiy matn: git -c user.email=… commit bilan istalgan odamning nomidan commit qilish mumkin. Imzo buni tuzatadi: commit maxfiy kalit bilan imzolanadi, ochiq kalit bilan tekshiriladi. Eng oson yo'l — SSH kaliti: gpg.format ssh, user.signingkey va commit.gpgsign true. Lokal tekshiruv uchun allowed_signers fayli kerak, GitHub'da esa kalit "Signing Key" sifatida qo'shiladi va commit yonida Verified belgisi chiqadi. Kanon tajribasida begona kalit bilan imzolangan commit "No principal matched" bilan rad etildi — imzo to'g'ri, lekin kalit egasi noma'lum.

Bu darsda

  • user.email bilan soxta muallif yaratib, nega imzo kerakligini ko'rasiz.
  • SSH kaliti bilan commit va tag imzolashni sozlaysiz.
  • allowed_signers, git verify-commit, log --show-signature va %G? bilan imzoni tekshirasiz.
  • GPG bilan imzoni SSH bilan solishtirasiz.
  • GitHub'dagi Verified belgisi, vigilant mode va "Require signed commits" qoidasini tushuntirasiz.

Oldin bilishingiz kerak: SSH kalit va GitHub autentifikatsiyasi, Git ichkaridan: obyektlar, SHA va snapshot, Tag va relizlar, Branch himoyasi va rulesets.

1. Nega bu kerak?

Git'ni o'rnatish va birinchi sozlash darsida user.name va user.email ni yozgansiz. Git ularni tekshirmaydi — bu shunchaki satrlar. Kim xohlasa, istalgan ismni yozadi.

Bu nimaga olib keladi? GitHub commit yonida email bo'yicha egasining avatarini ko'rsatadi. Begona odam taniqli dasturchining emailini yozib, PR yuborishi mumkin. Tarixda "bu kodni tajribali hamkasb yozgan" degan taassurot qoladi. Ochiq loyihalarda bu — ta'minot zanjiri hujumining eshigi: zararli kod ishonchli ism ortiga yashirinadi.

Hayotiy o'xshatish: konvertga "Jo'natuvchi: bank" deb istalgan kishi yozadi. Ishonch faqat muhr va imzodan keladi — ularni soxtalashtirish ancha qiyin. Git'da ham shunday: user.email — konvertdagi yozuv, imzo — muhr.

2. Tajriba: soxta muallif

Biz sinov repo'da (faqat lokal, hech qayerga yuborilmagan) boshqa odam nomidan commit qildik:

bash
git -c user.name="Linus Torvalds" \
  -c user.email="torvalds@linux-foundation.org" \
  commit -m "chore: soxta muallif"
git log -1 --format='%h %an <%ae>'

Terminalda:

text
f99757e Linus Torvalds <torvalds@linux-foundation.org>

Git hech narsa so'ramadi. -c — bitta buyruq uchun sozlamani almashtirish. Commit tarixda Linux yaratuvchisi nomidan turibdi. Agar bu commit GitHub'ga yuborilsa, u yerda ham shu ism ko'rinadi.

Diqqat: Bu tajribani faqat o'zingizning lokal sinov repo'ngizda qiling. Birovning nomidan commit yuborish — aldash. Biz buni zaiflikni ko'rsatish uchun qildik.

3. Imzo qanday ishlaydi

Imzo g'oyasini SSH kalit darsidan bilasiz: ikki kalit, maxfiy va ochiq. Maxfiy kalit bilan imzo qo'yiladi, ochiq kalit bilan tekshiriladi. Maxfiy kalitsiz to'g'ri imzo yasab bo'lmaydi.

sequenceDiagram
  participant A as Aziz (maxfiy kalit)
  participant G as Git
  participant T as Tekshiruvchi (ochiq kalit)
  A->>G: commit + imzo
  G->>T: commit obyekti, ichida gpgsig
  T->>T: imzo shu matnga mosmi?
  T->>T: kalit kimga tegishli?

Diagrammadagi oxirgi ikki savol alohida. Birinchisi — matematika: imzo commit mazmuniga mosmi, hech narsa o'zgarmaganmi. Ikkinchisi — ishonch: bu ochiq kalit haqiqatan Azizga tegishlimi. Ikkinchi savolga Git o'zi javob bera olmaydi — unga ro'yxat kerak. Lokal'da bu allowed_signers fayli, GitHub'da — akkauntingizdagi kalitlar.

Imzo qayerda saqlanadi? Commit obyektining ichida (Git ichkaridan darsi). Kanon imzolangan commitni git cat-file -p bilan ochdi (boshi, qatorlar 80 belgida kesilgan):

text
tree f4b354863caa9cea99b95422c9dab70465757d87
parent 060e6046a3473415ac4d3794f73ec5aba28a23c9
author Aziz Karimov <aziz@example.com> 1793789399 +0500
committer Aziz Karimov <aziz@example.com> 1793789399 +0500
gpgsig -----BEGIN SSH SIGNATURE-----
 U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgy0AOfYBBck+EI6IDYzaxOad2CG
 Hx/WHN7Iv/uxz9RaIAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
 AAAAQNKOt2pBXzjHabbYcTLz5ACcgwDSO1NxWdBhYRDb/ep9+mshCDCKRhEtIoSbj/CU7I

gpgsig — commit sarlavhalaridan biri. Nomi tarixiy (avval faqat GPG bor edi), ichida esa SSH imzosi. Imzo ham commit matnining qismi — demak u SHA'ga ta'sir qiladi. Imzolangan va imzosiz commit bir xil o'zgarish bilan ham turli SHA oladi.

4. SSH bilan imzolash

4.1 Kalit

Imzo uchun mavjud SSH kalitingizni ishlatsa bo'ladi. Lekin alohida kalit ochish tozaroq: kirish va imzo vazifalari ajraladi, birini almashtirish ikkinchisiga tegmaydi. SSH kalit darsidagi buyruq, boshqa fayl nomi bilan:

bash
ssh-keygen -t ed25519 -C "aziz@example.com" -f ~/.ssh/imzo_ed25519

Kanon kalitlarni faqat vaqtinchalik papkada yaratdi, tajribadan keyin o'chirdi va hech qayerga qo'shmadi. Siz esa o'z kalitingizni saqlab qolasiz — parol (passphrase) bilan.

4.2 Sozlash

To'rtta sozlama:

bash
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/imzo_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true
  • gpg.format ssh — imzo turi. Sukut openpgp (GPG).
  • user.signingkey — qaysi kalit. GitHub hujjati SSH uchun ochiq kalit (.pub) fayli yo'lini yozishni aytadi. Imzoni Git ssh-keygen dasturiga topshiradi. Biz sinagan OpenSSH 10.3p1 maxfiy kalitni yonidagi .pub siz fayldan o'zi topdi (ssh-agent ishlamagan holda ham).
  • commit.gpgsign true — har commit imzolanadi. Bitta commit uchun: git commit -S.
  • tag.gpgsign true — annotated taglar ham imzolanadi.

Kanon bu sozlamalarni faqat sinov repo'sida (--global siz) qildi — kompyuterning umumiy sozlamasiga tegmaslik uchun. Siz o'z kompyuteringizda --global bilan qilasiz.

4.3 Tekshirish: birinchi urinish

Imzolangan commit qilamiz va tekshiramiz. Biz ishga tushirdik:

bash
git commit -m "feat: imzolangan commit"
git verify-commit HEAD
text
error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification

"SSH imzosini tekshirish uchun gpg.ssh.allowedSignersFile sozlangan va mavjud bo'lishi kerak." Chiqish kodi 1. Commit imzolangan, lekin Git uni tekshira olmaydi — chunki "kalit kimniki?" degan savolga javob yo'q. Bu «Imzo qanday ishlaydi» bo'limidagi ikkinchi savol.

4.4 allowed_signers — kim qaysi kalit egasi

Fayl oddiy: har qatorda email, namespaces="git" va ochiq kalit.

bash
KALIT=$(cat ~/.ssh/imzo_ed25519.pub)
echo "aziz@example.com namespaces=\"git\" $KALIT" \
  >> ~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile \
  ~/.ssh/allowed_signers

Bizning sinovdagi qatorning boshi:

text
aziz@example.com namespaces="git" ssh-ed25519 AAAAC3NzaC1lZD

namespaces="git" — bu kalit faqat Git imzolari uchun ishonchli (SSH imzosi boshqa maqsadlarda ham ishlatiladi). Endi tekshiruv:

bash
git verify-commit HEAD
text
Good "git" signature for aziz@example.com with ED25519 key SHA256:ULbt2THx1iWzjHN07XfLhYaXu+qY11d5jxfWD3RMh98

"aziz@example.com uchun yaxshi imzo, ED25519 kaliti, barmoq izi …". Chiqish kodi 0. SHA256:… — kalitning barmoq izi (fingerprint): uzun kalitning qisqa, solishtirish oson ko'rinishi. Sizda u boshqa bo'ladi.

Tarixda imzolarni ko'rish:

bash
git log -1 --show-signature
text
commit 8a96aa2c461e79fc4023cff3bb55daa9115b1660 (HEAD -> main)
Good "git" signature for aziz@example.com with ED25519 key SHA256:ULbt2THx1iWzjHN07XfLhYaXu+qY11d5jxfWD3RMh98
Author: Aziz Karimov <aziz@example.com>
Date:   Wed Nov 4 10:05:00 2026 +0500

    feat: imzolangan commit

4.5 Begona kalit

Endi eng qiziq holat. Kimdir o'z kaliti bilan commitni imzoladi, lekin muallif sifatida Azizning emailini yozdi:

bash
git -c user.signingkey=../kalit/begona.pub \
  commit -m "fix: begona imzo"
git verify-commit HEAD

Biz ishga tushirdik:

text
Good "git" signature with ED25519 key SHA256:tfdQYXchG1IA6g+4HEF+pCuPcK70AMWwiLKM9NDAqO0
No principal matched.

Birinchi qator "Good" deydi — imzo matematik jihatdan to'g'ri, commit o'zgarmagan. Lekin ikkinchi qator: "Hech qaysi egasi mos kelmadi" — bu kalit allowed_signers da yo'q. Chiqish kodi 1. Git aldovni ushladi: email — Azizniki, kalit — Azizniki emas.

4.6 Holat belgisi: %G?

Ko'p commitni birdaniga ko'rish uchun git log formatida %G? bor. Kanon tarixining xulosasi:

bash
git log --format='%h %G? %an — %s'
text
d05b0ed U Aziz Karimov — fix: begona imzo
2daa376 G Aziz Karimov — feat: imzolangan commit
060e604 N Linus Torvalds — chore: soxta muallif
Belgi Ma'nosi
G yaxshi imzo, kalit ishonchli
U imzo to'g'ri, lekin kalit egasi noma'lum
N imzo yo'q
B imzo buzuq — commit o'zgartirilgan
E tekshirib bo'lmadi (masalan, allowed_signers yo'q)

Git hujjatida yana uchta belgi bor — X, Y, R: imzo yaxshi, lekin imzo yoki kalit muddati o'tgan, yoki kalit bekor qilingan. Ular asosan GPG kalitlarida uchraydi.

Uch qator — uch xil hikoya. N — oddiy imzosiz commit (sozlashdan oldingi). G — haqiqiy Aziz. U — Aziz nomidan, lekin boshqa kalit bilan. Faqat ism va emailga qarasangiz, U va G bir xil ko'rinadi.

4.7 Tag imzolash

Relizlar uchun tag imzosi ayniqsa muhim (CHANGELOG va reliz darsidagi v4.0.1): "bu reliz haqiqatan jamoadan" degan isbot. tag.gpgsign true bo'lsa, git tag -a o'zi imzolaydi; bitta tag uchun — git tag -s. Tekshiruv:

bash
git tag -m "v1.0.0" v1.0.0 HEAD~1
git tag -v v1.0.0

Biz ishga tushirdik:

text
Good "git" signature for aziz@example.com with ED25519 key SHA256:ULbt2THx1iWzjHN07XfLhYaXu+qY11d5jxfWD3RMh98
object 8a96aa2c461e79fc4023cff3bb55daa9115b1660
type commit
tag v1.0.0
tagger Aziz Karimov <aziz@example.com> 1793769000 +0500

v1.0.0

Imzo qatori va tag obyektining mazmuni. git verify-tag v1.0.0 ham xuddi shunday tekshiradi.

4.8 Narxi

Har commitda imzo — maxfiy kalit bilan bitta hisob. Kanon 20 ta commitni imzo bilan va imzosiz o'lchadi: 10.5 s va 7.9 s (bitta mashina, shovqinli — nisbat taxminiy). Har commitga ~0.13 s qo'shimcha. Kundalik ishda sezilmaydi.

Haqiqiy narx boshqa joyda: kalitni saqlash. Maxfiy kalit o'g'irlansa, o'g'ri sizning nomingizdan "Verified" commit qiladi. Kalitga parol qo'ying, uni hech qachon repo'ga, chatga yoki bulutdagi papkaga qo'ymang.

Tekshirib ko'ring: Imzolangan commitni git commit --amend bilan tahrirladingiz, lekin shu safar -c commit.gpgsign=false bilan. %G? nima ko'rsatadi va nega?

Javob

N — imzosiz. Amend yangi commit obyekti yaratadi, eski imzo eski obyektda qoldi. Biz sinab ko'rdik: 9c9dd23 N fix: begona imzo. Imzo commitga "yopishtirilmaydi" — u har yangi obyekt uchun qaytadan qo'yiladi. Rebase, amend, cherry-pick — hammasi yangi commit, shuning uchun commit.gpgsign true bo'lsa, ular sizning kalitingiz bilan qayta imzolanadi. Tarixni butunlay qayta yozadigan git filter-repo esa imzolarni qayta qo'ymaydi — olib tashlaydi. Buni keyingi darsda ko'rasiz.

5. GPG — klassik yo'l

SSH imzosi Git'ga ancha keyin qo'shilgan: GitHub hujjatiga ko'ra, SSH imzoni tekshirish uchun Git 2.34 yoki undan yangisi kerak. Undan oldin yagona yo'l GPG (GnuPG, OpenPGP standarti) edi. Git uchun ishlashi bir xil: gpg.format sukut — openpgp, user.signingkey — GPG kalit ID'si.

Taqqoslash uchun GPG bilan ham sinadik (GnuPG 2.4.9, kalit vaqtinchalik papkada, keyin o'chirildi). Kalit ro'yxati:

text
sec   ed25519/67657B97D728F83C 2026-11-04 [SC]
      F61A3F06B084CED623B949E167657B97D728F83C
uid                 [ultimate] Aziz Karimov <aziz@example.com>

git commit -S va git verify-commit HEAD:

text
gpg: Signature made Wed Nov  4 17:52:49 2026 WAST
gpg:                using EDDSA key F61A3F06B084CED623B949E167657B97D728F83C
gpg: Good signature from "Aziz Karimov <aziz@example.com>" [ultimate]

WAST — Git Bash'dagi gpg vaqt zonasini noto'g'ri qisqartmada ko'rsatdi; vaqt o'zi to'g'ri (Toshkent). %G? — G.

SSH GPG
Kalit sizda allaqachon bor alohida yaratiladi
Kim ekani allowed_signers yoki GitHub akkaunti kalit ichidagi uid, ishonch tarmog'i
Muddat, bekor qilish allowed_signers da valid-after / valid-before; kalitni ro'yxatdan o'chirasiz kalit ichidagi muddat, revocation sertifikati
Murakkablik kam ko'p (agent, keyserver)

Kanon SSH ni tanladi: kalit 07-qismdan beri bor, sozlash to'rt qator. GPG'ning ustunligi — muddat va rasmiy bekor qilish kalitning o'zida yuradi, har tekshiruvchining ro'yxatida emas. Ular ko'p yillik ochiq loyihalarda, paket imzolashda kerak bo'ladi.

Bizning tajribada bitta tuzoq chiqdi: gpg'ni maxsus papka (GNUPGHOME) bilan ishlatganda Windows'dagi git u yo'lni gpg'ga noto'g'ri uzatdi va error: gpg failed to sign the data oldik. Odatdagi sukut papka bilan bu muammo yo'q. Xato chiqsa, avval gpg --list-secret-keys kalitni ko'rsatayotganini tekshiring.

6. GitHub'da: Verified belgisi

6.1 Kalitni qo'shish

GitHub imzoni tekshirishi uchun ochiq kalitingizni bilishi kerak. SSH kalit darsida kirish kaliti "Authentication Key" sifatida qo'shilgan edi. Imzo kaliti xuddi shu sahifaga, boshqa tur bilan qo'shiladi (docs.github.com, "Adding a new SSH key to your GitHub account", 2026-11-04 da o'qildi; o'zimiz sinamadik):

  1. Istalgan GitHub sahifasida o'ng yuqoridagi profil rasmi → Settings.
  2. Chap menyuning Access bo'limida SSH and GPG keys.
  3. New SSH key, Title ga nom (masalan, "Noutbuk — imzo").
  4. Kalit turi — imzo (Signing Key); hujjat "authentication or signing" deb yozadi.
  5. Key maydoniga imzo_ed25519.pub mazmunini qo'yib, Add SSH key. GitHub parolni yoki 2FA kodini qayta so'rashi mumkin.

Bitta kalitni ham kirish, ham imzo uchun ishlatmoqchi bo'lsangiz, hujjatga ko'ra uni ikki marta — ikki tur bilan qo'shasiz.

Kalit qo'shilgach, shu kalit bilan imzolangan commitlar yonida Verified chiqadi: GitHub imzoni akkauntingizdagi ochiq kalit bilan tekshiradi. Commitdagi email akkauntingizda tasdiqlangan bo'lsin — hujjat buni committer emaili uchun tavsiya qiladi. Kanon kalitni akkauntga qo'shmadi — Verified belgisini sinov reposida ko'rmadik.

6.2 GitHub o'zi imzolaydigan commitlar

Bir qiziq topilma bor. Sinov reposidagi ikki commitni GitHub API'dan so'radik (faqat o'qish; repo nomi va muallif login ga almashtirildi; ikkinchi qator — xuddi shu buyruq 9c395ca uchun):

bash
gh api repos/login/vazifalar-api/commits/22a1226 \
  --jq '{sha: .sha[0:7], verified: .commit.verification.verified,
    reason: .commit.verification.reason,
    committer: .commit.committer.name}'
text
{"committer":"GitHub","reason":"valid","sha":"22a1226","verified":true}
{"committer":"login","reason":"unsigned","sha":"9c395ca","verified":false}

22a1226 — PR #9 ning squash commiti. Uni GitHub'ning o'zi yaratgan va o'z kaliti bilan imzolagan: committer — "GitHub", Verified. Hujjatga ko'ra, veb interfeysda yaratilgan commitlarni GitHub GPG kaliti bilan imzolaydi; ochiq kaliti — https://github.com/web-flow.gpg. 9c395ca — terminaldan to'g'ridan push qilingan import commiti: imzosiz. Demak, Jamoa workflow'lari darsidagi squash merge'lar main da avtomatik "Verified" bo'ladi. Lekin bu imzo "GitHub bu commitni yaratdi" deydi, "Aziz yozdi" demaydi. PR ichidagi commitlarning imzosi alohida tekshiriladi.

6.3 Vigilant mode va ruleset

Yana ikki imkoniyat (docs.github.com, sinalmagan, 2026-11):

  • Vigilant mode — Settings → SSH and GPG keys sahifasida, "Vigilant mode" ostidagi "Flag unsigned commits as unverified" belgisi. Yoqilsa, siz committer yoki muallif bo'lgan imzosiz commitlar "Unverified" deb belgilanadi. Demak, kimdir emailingizni yozib imzosiz commit qilsa, u ishonchli ko'rinmaydi (bu — hujjatdan xulosa, sinalmagan).
  • Require signed commits — ruleset qoidasi (Branch himoyasi darsidagi ro'yxatda). Himoyalangan branch'ga faqat tasdiqlangan imzoli commitlar tushadi.

Birinchisi — sizning nomingizni himoya qiladi, ikkinchisi — repo'ni.

7. Loyiha qadami: imzoni yoqish

Bu dars — tajriba darsi: vazifalar-api kodi o'zgarmaydi va commit yo'q. Lekin bundan keyingi commitlaringiz imzolansin:

  1. Imzo kaliti yarating («Kalit» bo'limi) va unga parol qo'ying.
  2. To'rtta git config --global sozlamasini yozing va allowed_signers yarating.
  3. Bo'sh commit bilan sinang: git commit --allow-empty -m "chore: imzo sinovi", keyin git log -1 --show-signature — "Good" chiqishi kerak.
  4. Sinov commitini bekor qiling: git reset --hard HEAD~1 (reset darsi; faqat push qilinmagan bo'lsa).
  5. GitHub'ga kalitni Signing Key sifatida qo'shing va xohlasangiz vigilant mode'ni yoqing.

Kanon bu qadamlarning 1–3 tasini lokal sinov repo'sida bajardi. 5-qadam sinalmagan — Verified belgisini o'zingiz birinchi bo'lib ko'rasiz.

8. Hujumchi nigohi

Imzo qaysi hujumlarga qarshi turadi va qaysilariga — yo'q?

  • Soxta muallif. Hujumchi taniqli dasturchining emailini yozib, PR yuboradi. Imzosiz repoda u ishonchli ko'rinadi. Vigilant mode yoqilgan bo'lsa — commit "Unverified", ruleset'da "Require signed commits" bo'lsa — main ga umuman tushmaydi.
  • Begona kalit. Hujumchi o'z kalitini yaratib, commitni imzolaydi va emailni sizniki deb yozadi. Imzo matematik jihatdan to'g'ri — lekin allowed_signers da va GitHub akkauntingizda bu kalit yo'q. Natija: U va "No principal matched". Bu holatni biz o'z ko'zimiz bilan ko'rdik.
  • O'g'irlangan kalit. Bunga imzo qarshi tura olmaydi: o'g'ri sizning kalitingiz bilan "Verified" commit qiladi. Himoya — kalitdagi parol, uni repo va bulutga qo'ymaslik, yo'qolsa GitHub'dan darhol o'chirish.
  • Ishonchli muallif, zararli kod. Imzo kodni tekshirmaydi. Shuning uchun review va testlar baribir majburiy.

9. Ko'p uchraydigan xatolar

9.1 allowedSignersFile needs to be configured

text
error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification

Imzo bor, tekshiruv ro'yxati yo'q. Davosi: allowed_signers fayli va gpg.ssh.allowedSignersFile sozlamasi. GitHub'da bu kerak emas — u kalitlarni akkauntdan oladi.

9.2 No principal matched.

Kalit allowed_signers da yo'q yoki undagi email commitdagi bilan mos emas. O'z commitingizda chiqsa — fayldagi email va user.email ni solishtiring. Birovnikida chiqsa — ehtiyot bo'ling: kimdir begona kalit bilan imzolagan.

9.3 error: gpg failed to sign the data

Commit umuman yaratilmadi:

text
error: gpg failed to sign the data:
...
fatal: failed to write commit object

Sabablari: kalit fayli yo'li noto'g'ri, GPG kaliti topilmadi, gpg dasturi ishga tushmadi. Davosi: git config user.signingkey ni tekshiring; SSH uchun — .pub fayl mavjudmi.

9.4 Imzosiz verify

Imzosiz commitga git verify-commit hech narsa yozmaydi, faqat chiqish kodi 1 qaytaradi (biz sinadik). Skriptda kodni tekshiring, matnni emas.

9.5 "Verified — demak xavfsiz"

Verified faqat kim yozganini aytadi, nima yozilganini emas. Imzolangan commitda ham xato yoki zararli kod bo'lishi mumkin. Imzo code review o'rnini bosmaydi.

10. Mashqlar

Mashqlar kurs/mashqlar/32/04-imzo/ da. 2-mashq yechimi Node 24.21.0 da, 3-mashq yechimi Git 2.54.0 va OpenSSH 10.3p1 da tekshirilgan (biz ishga tushirdik).

1-mashq (oson): bo'shliqlarni to'ldiring

  • SSH bilan imzolash uchun gpg.format qiymati —
  • Har commitni avtomatik imzolaydigan sozlama — commit.
  • Imzo to'g'ri, lekin kalit egasi noma'lum bo'lsa %G? belgisi —
  • Imzolangan tagni tekshiradigan buyruq — git tag
  • O'z nomingizdagi imzosiz commitlarni "Unverified" qiladigan GitHub sozlamasi —
Yechim
  • ssh — sukut openpgp.
  • gpgsign — bitta commit uchun git commit -S.
  • U — "No principal matched": kalit allowed_signers da yo'q.
  • -v — yoki git verify-tag.
  • vigilant mode — "Flag unsigned commits as unverified".

2-mashq (o'rta): imzo hisoboti

imzoHisoboti(qatorlar) funksiyasini yozing. Kirish — git log --format='%h %G? %an — %s' chiqishining qatorlari. Funksiya har holatdan nechta borligini (soni) va G bo'lmagan commitlar ro'yxatini (diqqat, ko'rinishi "hash: ma'no") qaytarsin. Ma'nolar «Holat belgisi: %G?» bo'limidagi jadvaldan. Ishora: qatorni split(" ") bilan bo'lsangiz, birinchi ikki bo'lak — hash va belgi (Massiv destructuring).

Yechim
js
const MANO = {
  G: "yaxshi", U: "kalit egasi noma'lum", N: "imzosiz",
  B: "buzuq", E: "tekshirib bo'lmadi",
};

function imzoHisoboti(qatorlar) {
  const soni = {};
  const diqqat = [];
  for (const q of qatorlar) {
    const [hash, holat] = q.split(" ");
    soni[holat] = (soni[holat] ?? 0) + 1;
    if (holat !== "G") {
      diqqat.push(`${hash}: ${MANO[holat] ?? holat}`);
    }
  }
  return { soni, diqqat };
}

console.log(imzoHisoboti([
  "d05b0ed U Aziz Karimov — fix: begona imzo",
  "2daa376 G Aziz Karimov — feat: imzolangan commit",
  "060e604 N Linus Torvalds — chore: soxta muallif",
]));

Konsolda:

text
{
  soni: { U: 1, G: 1, N: 1 },
  diqqat: [ "d05b0ed: kalit egasi noma'lum", '060e604: imzosiz' ]
}

Kirish — kanon tarixining haqiqiy xulosasi. Ikki commit diqqat talab qiladi. Node apostrofli satrni qo'shtirnoqda, qolganini bittalik tirnoqda chiqardi — ma'nosi bir xil. Bunday hisobot reliz oldidan foydali: "oxirgi tagdan beri imzosiz commit bormi?" — git log v4.0.0..HEAD --format=… chiqishini shu funksiyaga bering.

3-mashq (qiyin): uch commit, uch hikoya

Vaqtinchalik papkada butun tajribani o'zingiz takrorlang: ikki kalit (aziz va begona), allowed_signers faqat Aziz kaliti bilan, uchta commit — imzosiz, Aziz kaliti bilan, begona kalit bilan. Keyin %G? va oxirgi ikki commitning verify-commit natijasini chiqaring. Global sozlamaga tegmang: hammasi shu repo'ning sozlamasi bo'lsin. Oxirida papkani o'chiring — kalitlar ham ketadi.

Ishora: bitta commit uchun kalitni git commit -S --gpg-sign=<ochiq-kalit-fayli> bilan berish mumkin. Barmoq izi har safar boshqa — uni sed 's/SHA256:.*/SHA256:…/' bilan qisqartiring. ${PIPESTATUS[0]} — quvurdagi birinchi buyruqning chiqish kodi (Bisect darsidagi skriptlar kabi).

Yechim
bash
mkdir imzo-sinov && cd imzo-sinov
ssh-keygen -q -t ed25519 -N "" -C "aziz@example.com" -f aziz
ssh-keygen -q -t ed25519 -N "" -C "begona" -f begona
echo "aziz@example.com namespaces=\"git\" $(cat aziz.pub)" \
  > allowed_signers

git init -q -b main repo && cd repo
git config user.name "Aziz Karimov"
git config user.email "aziz@example.com"
git config gpg.format ssh
git config gpg.ssh.allowedSignersFile ../allowed_signers

echo 1 > a.txt && git add a.txt
git commit -q -m "chore: imzosiz"
echo 2 > b.txt && git add b.txt
git commit -q -S --gpg-sign=../aziz.pub -m "feat: o'z kalitim"
echo 3 > c.txt && git add c.txt
git commit -q -S --gpg-sign=../begona.pub -m "fix: begona kalit"

git log --format='%G? %s'
for r in HEAD~1 HEAD; do
  git verify-commit $r 2>&1 | sed 's/SHA256:.*/SHA256:…/'
  echo "exit ${PIPESTATUS[0]}"
done
cd ../.. && rm -rf imzo-sinov

Biz ishga tushirdik:

text
U fix: begona kalit
G feat: o'z kalitim
N chore: imzosiz
Good "git" signature for aziz@example.com with ED25519 key SHA256:…
exit 0
Good "git" signature with ED25519 key SHA256:…
No principal matched.
exit 1

Uch commit — uch hikoya: N (imzo yo'q), G (Aziz), U (imzo bor, lekin egasi ro'yxatda yo'q). -N "" — kalitga parol qo'ymaslik; bu faqat bir martalik sinov uchun. Haqiqiy kalitingizga parol qo'ying. --gpg-sign ga kalit fayli berilgani uchun user.signingkey kerak bo'lmadi — bitta repo'da ikki kalitni almashtirib ko'rishning qulay yo'li.

11. Real ishda

  • Qayerda uchraydi: ko'p ochiq loyihalar va kompaniyalarda himoyalangan branch'ga faqat imzolangan commit tushadi. Paket kelib chiqishini isbotlash (npm provenance) ham shu g'oyaga tayanadi: "bu paketni aynan shu repo'dan, shu CI yig'gan".
  • Kalit gigiyenasi: kalitga parol; bitta qurilma — bitta kalit; noutbuk yo'qolsa, GitHub'dan kalitni darhol o'chirish.
  • Intervyu savollari: "Commitni nega imzolash kerak?", "Verified belgisi nimani kafolatlaydi va nimani kafolatlamaydi?", "SSH va GPG imzo farqi?"

Xulosa

  • user.name va user.email — tekshirilmaydigan matn: istalgan kishi istalgan nomdan commit qila oladi.
  • Imzo — maxfiy kalit bilan qo'yiladi, ochiq kalit bilan tekshiriladi; u commit obyektining ichida (gpgsig).
  • SSH imzo: gpg.format ssh, user.signingkey, commit.gpgsign, tag.gpgsign; lokal tekshiruvga allowed_signers kerak.
  • %G?: G — yaxshi, U — kalit egasi noma'lum, N — imzosiz; "No principal matched" — begona kalit.
  • GitHub: kalit "Signing Key" sifatida qo'shiladi → Verified; vigilant mode — nomingizni, ruleset — repo'ni himoya qiladi.
  • Verified — kim yozganini aytadi, kod xavfsizligini emas.

Keyingi dars: Tarixni qayta yozish va sirlarni tozalash — .env tarixga tushib qolsa nima qilish kerak: git filter-repo, --fixup va nega tozalash kalitni almashtirish o'rnini bosmaydi.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Commit imzolash: SSH va GPG imzo, Verified belgisi — IlmHamroh