Подпись коммитов подтверждает, что изменения внесли именно вы, а не кто-то с вашим именем в git config. В open source это давно норма: ядро Linux и Debian требуют подписанные теги, а многие компании включают проверку в защищённых ветках. Настроить GPG-подпись в Linux — задача на полчаса, но только если сразу разобраться с агентом, TTY и форматом ключа. Ниже — рабочий порядок для Linux Mint, Ubuntu и любой системы с GnuPG 2.2 и новее.

Зачем это нужно

git по умолчанию доверяет полю author. Любой может поставить ваше имя и почту и отправить коммит. Подпись GPG привязывает коммит к ключу, а значит, к человеку, который контролирует приватную часть. Проверка помогает в трёх сценариях: аудит истории, защита релизных тегов и требование репозитория.

Подпись не шифрует код и не заменяет code review. Она отвечает только на вопрос, кто автор и не менялись ли байты после подписи.

Создание ключа

Для подписи достаточно ключа с возможностью sign, отдельный encrypt не нужен. Ed25519 короче и быстрее RSA, но старые системы могут его не понимать; для максимальной совместимости берите RSA 4096.

gpg --quick-generate-key "Ivan Petrov <ivan@example.com>" ed25519 sign 2y
gpg --list-secret-keys --keyid-format=long
gpg --fingerprint ivan@example.com
gpg --armor --export-secret-keys ivan@example.com > secret.asc

Вторая команда покажет строку вида sec ed25519/ABCD1234EF567890. Это короткий ID, но для настройки лучше взять полный отпечаток из вывода gpg —fingerprint. Срок 2y означает два года: после истечения подпись перестанет считаться валидной, поэтому напоминание в календаре обязательно. Файл secret.asc нужен только для офлайн-бэкапа, его нельзя коммитить, класть в облако без шифрования или отправлять в чат.

Настройка git

Четыре параметра связывают git с ключом. Первый выбирает ключ, второй включает подпись по умолчанию, третий задаёт программу, четвёртый распространяет правило на теги.

git config --global user.signingkey ABCD1234EF567890
git config --global commit.gpgsign true
git config --global tag.gpgSign true
git config --global gpg.program gpg

Если в системе только gpg2, подставьте его. Проверьте, что почта в user.email совпадает с адресом в ключе: GitHub и GitLab сопоставляют подпись с аккаунтом именно по нему, и при несовпадении коммит получит статус Unverified.

git config --global user.name
git config --global user.email
gpg --list-keys --keyid-format=long ivan@example.com

Подпись коммитов и тегов

При включённом commit.gpgsign флаг -S не нужен, но его полезно знать: он подписывает один коммит, не меняя глобальные настройки. Тег подписывается отдельно: флагом -s или автоматически при включённом tag.gpgSign.

git commit -m "Fix network config"
git commit -S -m "Hotfix for dhcp pool"
git tag -s v1.4.0 -m "Release 1.4.0"
git log --show-signature -1

Вывод содержит строку Good signature и отпечаток ключа. Если вместо неё написано No signature, подпись не создалась или вы смотрите на коммит, сделанный до настройки. Старые коммиты автоматически не подписываются: при необходимости их переписывают интерактивным rebase, но это меняет хеши и требует согласования с командой.

Публикация ключа

Локальной подписи мало: получателю нужен ваш публичный ключ. Его добавляют в GitHub, GitLab или на keyserver. Для сайта и репозитория достаточно armored-файла.

gpg --armor --export ABCD1234EF567890 > public.asc
gpg --keyserver keyserver.ubuntu.com --send-keys ABCD1234EF567890
git verify-commit HEAD
git verify-tag v1.4.0

В GitHub ключ вставляют в Settings → SSH and GPG keys → New GPG key. Экспортируйте по отпечатку, а не по короткому ID, чтобы не перепутать ключи с похожими окончаниями. Публичный ключ можно смело публиковать, приватный — никогда.

Срок жизни ключа — не формальность. Продление делается командой gpg —edit-key, затем expire: старые подписи остаются валидными, если ключ не отозван. Отзыв — отдельный сценарий. Revocation-сертификат создаётся при генерации и лежит в ~/.gnupg/openpgp-revocs.d; если ключ скомпрометирован, сертификат импортируют и публикуют, после чего проверки помечают подпись как revoked. Храните его отдельно от секретного ключа.

В команде достаточно, чтобы каждый подписывал свои коммиты, а CI проверял сам факт подписи; строить паутину доверия внутри компании обычно не требуется.

Проверка на стороне получателя

Коллега или CI может проверить каждый коммит в диапазоне. Для этого импортируют публичный ключ и доверяют ему.

gpg --import public.asc
git verify-commit HEAD
git log --show-signature --pretty="%h %G? %s" -5
git log --format="%h %G? %s" origin/main..HEAD

Символ G означает хорошую подпись, B — плохую, U — неизвестный ключ, N — отсутствие подписи, E — ошибку проверки. В CI удобно проверять всю ветку перед слиянием и падать, если найден N или B. Для защищённой ветки включите Require signed commits в GitHub или push rule в GitLab.

Если подпись не создаётся

Самая частая ошибка — «gpg failed to sign the data» на сервере или в tmux. Причина в pinentry: агенту негде спросить пароль. Решение — выставить GPG_TTY и перезапустить агент.

export GPG_TTY=$(tty)
echo "test" | gpg --clearsign
gpgconf --kill gpg-agent
git config --global gpg.program "$(command -v gpg)"

Строку с GPG_TTY добавляют в конец ~/.bashrc, иначе она не подхватится в новых сессиях. В контейнерах и CI используйте batch-импорт и loopback-pinentry, а пароль передавайте через секрет переменной окружения, не через аргумент командной строки: аргументы видны в списке процессов.

Альтернатива: SSH-подписи

Git 2.34 и новее умеет подписывать коммиты тем же SSH-ключом, что и доступ к серверу. Это проще, если GPG вы не используете, но проверка требует файла allowed_signers.

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
git log --show-signature -1

В allowed_signers добавляют строку вида ivan@example.com ssh-ed25519 AAAA… — почта, пробел, тип ключа и сам ключ. GitHub принимает SSH-подписи, но не все старые клиенты их понимают, поэтому в смешанной команде лучше договориться об одном формате и записать это правило в README.

Чек-лист

  • Ключ с возможностью sign, срок и напоминание о продлении.
  • user.email совпадает с адресом в ключе.
  • commit.gpgsign и tag.gpgSign включены глобально.
  • Публичный ключ добавлен в GitHub или GitLab.
  • Резервная копия секретного ключа и revocation-сертификата лежит офлайн.
  • CI проверяет подписи в защищённых ветках.

Итог

Подпись коммитов — это несколько команд и одна привычка: проверять git log —show-signature после настройки. Начните с ed25519 или RSA 4096, добавьте ключ в Git-хостинг и включите обязательную проверку в защищённой ветке. Тогда история перестанет быть набором анонимных строк и станет проверяемой.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте