Открой любой свой коммит и посмотри, кто его автор. Имя и почта в полях author и committer - это просто строки, которые Git берёт из твоего user.name и user.email. Никакой проверки. Я прямо сейчас могу настроить себе чужое имя и закоммитить от лица твоего тимлида:
Код: Выделить всё
git config user.name "Linus Torvalds"
git config user.email "torvalds@linux-foundation.org"
git commit -m "fix: critical security patch"
Второй мотив - требование форджей и регуляторов. GitHub и GitLab показывают бейдж Verified рядом с подписанными коммитами, а во многих компаниях правило ветки прямо требует, чтобы в main попадали только verified commit. В supply-chain-аудитах (SLSA, требования заказчиков) подпись - часть чек-листа. Так что подпись - это не паранойя сеньоров, а гигиена 2026 года.
Важно сразу понять границы. Подпись доказывает: "этот коммит создан владельцем ключа K". Она НЕ доказывает, что код хороший, что человек реально тот, за кого себя выдаёт в паспорте, и не шифрует ничего. Это аутентификация авторства плюс защита целостности (изменишь хоть байт в дереве - подпись разъедется), не более.

Три способа подписи и почему SSH стал дефолтом 2026
Исторически в Git был один путь - GPG. Он работает, но болит: генерация ключа с правильным типом, экспирация, web of trust, демон gpg-agent, который то спит, то не находит pinentry, ключи в отдельном keyring. Куча людей бросали подпись именно на этапе "почему gpg висит и ничего не спрашивает".
В Git 2.34 (конец 2021) появилась git ssh подпись - подпись тем же SSH-ключом, которым ты и так пушишь. С тех пор это де-факто рекомендованный дефолт, а к 2026 - просто здравый смысл для большинства. Логика железная: ключ у тебя уже есть, агент уже настроен, форджи умеют его верифицировать. Раскладка по трём вариантам такая:
- SSH-подпись - дефолт 2026. Ключ уже есть, настройка за 5 минут, ноль возни с keyring. Берёшь её, если нет причины не брать.
- GPG - легаси и enterprise. Жив там, где уже выстроена корпоративная PKI, smartcard/YubiKey в GPG-режиме, политики на GPG. Новый проект с нуля на GPG в 2026 заводить смысла мало.
- Sigstore/gitsign - keyless OIDC-подпись для CI и ботов, где нельзя держать долгоживущий приватный ключ на раннере.
Практический SSH-setup за 5 минут
Сначала ключ. Если у тебя уже есть ~/.ssh/id_ed25519, которым ты пушишь - можно подписывать им же. Хочешь отдельный ключ под подпись (хорошая практика - разделить аутентификацию и подпись) - сгенерь новый:
Код: Выделить всё
ssh-keygen -t ed25519 -C "signing key" -f ~/.ssh/git_sign_ed25519
Код: Выделить всё
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/git_sign_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true
Код: Выделить всё
git commit --allow-empty -m "test: signed commit"
Код: Выделить всё
git log --show-signature -1
Код: Выделить всё
commit 4f1c2a9... (HEAD -> main)
Good "git" signature with ED25519 key SHA256:3xY...
Author: Ivan <ivan@example.com>
Date: Sun Jun 15 12:40:11 2026 +0300
test: signed commit
allowedSignersFile: без него проверка не работает
SSH-подпись по своей природе не знает, какому человеку принадлежит ключ - это просто пара ключей, без удостоверяющего центра, как в GPG/PKI. Чтобы Git мог сказать не просто "подпись валидна", а "подпись валидна И принадлежит ivan@example.com", ему нужен список доверенных подписантов - allowedSignersFile. Без него ты увидишь:
Код: Выделить всё
error: gpg.ssh.allowedSignersFile needs to be configured and exist
for ssh signature verification
Код: Выделить всё
mkdir -p ~/.config/git
echo "ivan@example.com $(cat ~/.ssh/git_sign_ed25519.pub)" \
>> ~/.config/git/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers
Код: Выделить всё
Good "git" signature for ivan@example.com with ED25519 key SHA256:3xY...
Код: Выделить всё
git verify-commit HEAD
git verify-tag v1.0.0
Verified-бейдж на GitHub и GitLab
Локальная проверка - это про твою машину. Чтобы получить verified commit github, форджу нужно знать твой публичный ключ. Шаги:
- GitHub: Settings -> SSH and GPG keys -> New SSH key, и в типе выбрать Signing Key (не Authentication!). Это критично: один и тот же ключ можно добавить дважды - отдельно как auth, отдельно как signing.
- GitLab: Preferences -> SSH Keys, при добавлении выбрать usage type Signing (или Authentication & Signing).
GPG как легаси-путь
Если на проекте уже принят git gpg - формат тот же, бэкенд другой. Коротко, чтобы ты узнал это в чужих конфигах. Смотрим/генерим ключ и берём его long id:
Код: Выделить всё
gpg --list-secret-keys --keyid-format=long
gpg --full-generate-key
Код: Выделить всё
git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign true
Для форжа публичный GPG-ключ экспортируется так и вставляется в Settings -> SSH and GPG keys -> New GPG key:
Код: Выделить всё
gpg --armor --export 3AA5C34371567BD2
Отдельная история - боты и пайплайны. Держать долгоживущий приватный ключ подписи на CI-раннере опасно: утёк раннер - утёк ключ, и им можно подписывать что угодно месяцами. Решение - gitsign sigstore, keyless-подпись.
Идея такая. Раннер аутентифицируется по OIDC (короткоживущий identity-token от GitHub Actions, Google и т.п.). Этот токен уходит в Fulcio - центр сертификации Sigstore, который выдаёт сертификат, живущий минуты, привязанный к OIDC-личности (например к workflow-идентичности репозитория). Этим эфемерным сертификатом подписывается коммит, а сам факт подписи плюс сертификат записываются в публичный прозрачный журнал Rekor. Сертификат протух через минуты - но запись в Rekor вечна, и по ней подпись проверяется и спустя год: "в такой-то момент эта личность подписала этот коммит". Долгоживущих секретов на раннере - ноль.
Ставится gitsign отдельно (это не часть Git), а подключается через тот же механизм форматов - как кастомный gpg-program:
Код: Выделить всё
git config --global gpg.x509.program gitsign
git config --global gpg.format x509
git config --global commit.gpgsign true
Типичные грабли
- Подписал, а форж пишет Unverified - почта коммита не совпадает с почтой, привязанной к аккаунту, либо ключ загружен как auth, а не как signing.
- error про allowedSignersFile - забыл создать файл или указать на него; на SSH-подписи это обязательный шаг для верификации.
- Rebase/cherry-pick/amend пересоздают коммиты, и старые подписи теряются - новые коммиты подпишутся заново только если включён commit.gpgsign. После переписывания истории проверяй, что всё осталось подписанным.
- Слияния и коммиты, сделанные через веб-интерфейс или ботом без подписи, разрывают цепочку verified - учитывай это в правилах ветки.
- Указал в user.signingkey приватный ключ вместо .pub для SSH - бывает работает, но правильно и переносимо указывать публичную часть.
- GPG висит без запроса пароля - проблема gpg-agent/GPG_TTY, а не Git.
Повтори руками по шагам, это минут десять:
- Сгенерь ключ подписи: ssh-keygen -t ed25519 -f ~/.ssh/git_sign_ed25519 -C "signing".
- Настрой Git: gpg.format ssh, user.signingkey на .pub, commit.gpgsign true, tag.gpgsign true (команды выше).
- Сделай git commit --allow-empty -m "signed" и подписанный тег: git tag -s v0.0.1 -m "first signed tag".
- Создай ~/.config/git/allowed_signers со строкой "своя-почта содержимое-pub" и пропиши gpg.ssh.allowedSignersFile.
- Проверь: git log --show-signature -1 и git verify-tag v0.0.1 - убедись, что есть Good signature for твоя-почта.
- Загрузи .pub на GitHub как Signing Key, запушь и найди бейдж Verified.
- Что именно доказывает подпись коммита, а что НЕ доказывает?
- Почему для SSH-подписи без allowedSignersFile верификация падает, а для GPG такого файла не нужно?
- В чём принципиальная разница между ключом, добавленным на GitHub как Authentication, и как Signing?
- Почему для CI выгоднее keyless-подпись Sigstore, чем положить приватный ключ в секреты раннера?
Имя автора в коммите - недоверенная строка, и подпись превращает её в проверяемый факт. В 2026 дефолт - SSH-подпись: gpg.format=ssh, user.signingkey, commit.gpgsign=true, плюс allowedSignersFile для верификации. GPG оставляем легаси и enterprise-инфраструктуре, а Sigstore/gitsign берём для CI и ботов, где долгоживущий ключ - это риск. Загрузи публичный ключ на форж, получи Verified - и твоя история перестанет быть подделываемой.