Подпись релизных артефактов
Согласно ADR 0005 каждый релиз Netgap подписывается человеком (maintainer) отдельно по каждой целевой платформе. CI/CD релиз не подписывает — он только пересобирает его и проверяет, что результат побитово совпадает с тем, что подписал maintainer.
Подпись ставится тем же личным ключом, что и подпись коммитов, и так же сверяется с pgp_key_id в CONTRIBUTORS.json — в проекте один источник доверенных ключей.
Как это устроено
Подписывается не каждый артефакт по отдельности, а файл хеш-сумм всех файлов релиза платформы. Это отсоединенная (detached) ASCII-armored подпись: рядом с netgap-vX.Y.Z-<P>.sha256 появляется netgap-vX.Y.Z-<P>.sha256.asc. Проверка складывается из двух шагов: подпись подтверждает подлинность файла хешей, а хеши — целостность самих артефактов.
Порядок действий maintainer
Для каждой целевой платформы <P>:
# 1. Чистая локальная сборка релиза на машине целевой платформы
# (или под эмуляцией/кросс-сборкой)
make clean && make build-prod && make checks
make release-bundle
# 2. Подпись файла хеш-сумм личным ключом
make release-sign GPG_KEY=556B41333653BD5A
# Результат: netgap-vX.Y.Z-<P>.sha256 и netgap-vX.Y.Z-<P>.sha256.asc
# 3. Оба файла коммитятся в release/* отдельным подписанным коммитом
git add netgap-vX.Y.Z-<P>.sha256 netgap-vX.Y.Z-<P>.sha256.asc
git commit -S -s -m "Sign release artifacts for vX.Y.Z (<P>)"
Ключевые правила:
- приватный ключ не покидает машину maintainer и не выдается CI/CD;
- релиз допускается к слиянию в
main, только когда вrelease/*есть валидные подписи по всем целевым платформам; - после первого коммита платформенной подписи
release/*замораживается: любое изменение кода или состава релиза делает подписи недействительными и требует нового-rc.Xи повторной подписи всеми платформами; - файлы хешей и подписей не участвуют в подсчете самих хешей — расхождение по одной платформе не обесценивает подписи остальных.
Проверка подписи релиза
Так подпись проверяет CD, и точно так же ее может проверить любой пользователь скачанного релиза:
# 1. Получить и сверить ключ maintainer
# (способы получения и сверка отпечатка — см. «Где взять ключ участника»)
gpg --locate-keys andrey@ganyushkin.ru
gpg --fingerprint 556B41333653BD5A
# 2. Проверить подпись файла хеш-сумм
gpg --verify netgap-vX.Y.Z-<P>.sha256.asc netgap-vX.Y.Z-<P>.sha256
# 3. Проверить целостность артефактов по хешам
sha256sum -c netgap-vX.Y.Z-<P>.sha256
# macOS: shasum -a 256 -c netgap-vX.Y.Z-<P>.sha256
Ожидаемый результат gpg --verify:
gpg: Good signature from "Andrei Ganiushkin (key for netgap project, for GitHub) <andrey@ganyushkin.ru>"
Предупреждение WARNING: This key is not certified with a trusted signature! при валидной подписи — нормально: доверие к ключу устанавливается сверкой отпечатка с CONTRIBUTORS.json, а не web of trust (см. модель доверия). Любой другой результат (BAD signature, несовпадение хешей) — повод не использовать артефакт и сообщить в проект.
Чеклист maintainer: подпись релиза платформы
- Сборка выполнена локально из чистого состояния:
make clean && make build-prod && make checks. -
make release-bundleсобрал состав релиза платформы. -
make release-sign GPG_KEY=<key-id>создал*.sha256и*.sha256.asc. - Подпись проверена локально:
gpg --verify *.sha256.asc *.sha256. - Оба файла закоммичены в
release/*подписанным коммитомgit commit -S -s. - Процедура повторена для каждой целевой платформы.
- После первого коммита подписи состав релиза не менялся (иначе — новый
-rc.Xи переподпись всех платформ).