# GPG-подпись коммитов _Безопасность · GitLab Knowledge Base_ **TL;DR:** Коммиты в Git можно подписывать GPG-ключом (или SSH-ключом начиная с Git 2.34). Подпись криптографически доказывает, что в момент коммита у подписавшего был доступ к private key. Связь «ключ → конкретный человек» обеспечивается уже не Git, а проверкой ключа (web of trust в OpenPGP, подтверждение через GitHub-аккаунт и т.п.) - сам Git не проверяет, кто ты есть. По умолчанию `git commit` записывает в коммит поля `Author` и `Committer` - просто строки из `user.email` в конфиге. Любой может поставить чужое имя: ```bash git config user.email "linus@kernel.org" git commit -m "fix: ..." # Author: Linus Torvalds ``` Это **не** подлог в смысле криптографии - это просто метаданные. Если важно, что коммит реально сделал владелец указанной личности, нужна подпись. ## Как настроить GPG-подпись ```bash # Сгенерировать ключ (если ещё нет) gpg --full-generate-key # Узнать ID ключа gpg --list-secret-keys --keyid-format=long # Прописать в Git git config --global user.signingkey git config --global commit.gpgsign true # Опционально - для тегов git config --global tag.gpgsign true ``` После этого каждый коммит будет автоматически подписан. Без флага `commit.gpgsign` можно подписать единичный: ```bash git commit -S -m "..." ``` ## SSH-подпись (Git 2.34+) Если у тебя уже есть SSH-ключ для GitHub, его можно использовать для подписи коммитов вместо отдельного GPG-ключа: ```bash 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](/courses/git/kb/ssh-keys-git.md)). ## Что увидит remote На GitHub подписанные коммиты показываются с зелёным значком `Verified`. Подпись проверяется по публичному ключу, который ты загрузил в настройках профиля. Неподписанные - без значка. ```bash # Локально проверить подпись git log --show-signature # commit abc123 # gpg: Signature made ... # gpg: Good signature from "Your Name " ``` ## Можно ли требовать подписей? - **На GitHub**: branch protection → «Require signed commits». Без подписи push отказывается. - **На bare-server**: через server-side hook (см. [force-push](/courses/git/kb/force-push.md)), pre-receive проверяет `git log --show-signature`. Включать «требовать подписи» имеет смысл, когда подделка идентичности - реальный риск (open-source с тысячами контрибьюторов, enterprise с compliance-требованиями). ## Подводные камни - **gpg ругается «Inappropriate ioctl»**: gpg не может спросить парольную фразу из терминала. Лечится: `export GPG_TTY=$(tty)` в `.bashrc`. - **Подпись не показывается на GitHub после загрузки ключа.** Имя в `user.email` Git'а должно совпадать с email в GPG-ключе и с подтверждённым email в GitHub-аккаунте. Любое расхождение - нет значка. - **Истечение ключа.** GPG-ключи обычно создают с expiry. После expiry старые подписи остаются валидными, но новые требуют продлить ключ. - **CI с подписанными коммитами.** Если CI делает merge-коммит, у бота тоже нужен ключ. Или включить «squash and merge» без создания merge-коммитов. ## Команды ```bash git config --global commit.gpgsign true ``` Подписывать каждый коммит ```bash git commit -S -m '...' ``` Подписать единичный коммит ```bash git log --show-signature ``` Проверить подписи в истории ```bash git config --global gpg.format ssh ``` Использовать SSH-ключ вместо GPG (Git 2.34+) ## См. также - [SSH-ключи для Git](/courses/git/kb/ssh-keys-git.md) - [Поиск секретов в репозитории](/courses/git/kb/secret-scanning.md)