По умолчанию git commit записывает в коммит поля Author и
Committer - просто строки из user.email в конфиге. Любой может
поставить чужое имя:
git config user.email "linus@kernel.org"
git commit -m "fix: ..."
# Author: Linus Torvalds <linus@kernel.org>
Это не подлог в смысле криптографии - это просто метаданные. Если важно, что коммит реально сделал владелец указанной личности, нужна подпись.
Как настроить GPG-подпись
# Сгенерировать ключ (если ещё нет)
gpg --full-generate-key
# Узнать ID ключа
gpg --list-secret-keys --keyid-format=long
# Прописать в Git
git config --global user.signingkey <KEY-ID>
git config --global commit.gpgsign true
# Опционально - для тегов
git config --global tag.gpgsign true
После этого каждый коммит будет автоматически подписан. Без флага
commit.gpgsign можно подписать единичный:
git commit -S -m "..."
SSH-подпись (Git 2.34+)
Если у тебя уже есть SSH-ключ для GitHub, его можно использовать для подписи коммитов вместо отдельного GPG-ключа:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
Это проще: один ключ для push'а и для подписи. GitHub поддерживает верификацию SSH-подписей через ту же страницу настроек, где загружаются auth-ключи (см. ssh-keys-git).
Что увидит remote
На GitHub подписанные коммиты показываются с зелёным значком
Verified. Подпись проверяется по публичному ключу, который ты
загрузил в настройках профиля. Неподписанные - без значка.
# Локально проверить подпись
git log --show-signature
# commit abc123
# gpg: Signature made ...
# gpg: Good signature from "Your Name <you@example.com>"
Можно ли требовать подписей?
- На GitHub: branch protection → «Require signed commits». Без подписи push отказывается.
- На bare-server: через server-side hook (см. force-push),
pre-receive проверяет
git log --show-signature.
Включать «требовать подписи» имеет смысл, когда подделка идентичности - реальный риск (open-source с тысячами контрибьюторов, enterprise с compliance-требованиями).
Подводные камни
- gpg ругается «Inappropriate ioctl»: gpg не может спросить
парольную фразу из терминала. Лечится:
export GPG_TTY=$(tty)в.bashrc. - Подпись не показывается на GitHub после загрузки ключа. Имя
в
user.emailGit'а должно совпадать с email в GPG-ключе и с подтверждённым email в GitHub-аккаунте. Любое расхождение - нет значка. - Истечение ключа. GPG-ключи обычно создают с expiry. После expiry старые подписи остаются валидными, но новые требуют продлить ключ.
- CI с подписанными коммитами. Если CI делает merge-коммит, у бота тоже нужен ключ. Или включить «squash and merge» без создания merge-коммитов.