Подпись защищает не канал загрузки, а саму метаинформацию сборки. Даже если CDN
или S3 отдаст подменённый manifest, клиент отклонит его до проверки файлов.
Signed envelope
SignedEnvelope связывает одной Ed25519-подписью:
- тип payload;
key_id публичного ключа;
- монотонное
generation;
- длину и точные protobuf bytes payload.
Подмена типа, номера поколения или любого байта manifest нарушает подпись.
key_id является коротким SHA-256 идентификатором публичного ключа и не
содержит секретных данных.
Подготовка ключа
Команда создаёт 32-byte Ed25519 seed в hex. Делать это нужно один раз на
защищённой операторской машине.
Publisher читает seed локально, создаёт manifest.envelope.pb, загружает его
рядом с прежним manifest.json и не добавляет сам ключ в upload plan. Если
настроен [control_plane], тот же envelope устанавливается через authenticated
admin gRPC либо общий volume только после успешного завершения S3-транзакции.
Не генерируйте production-ключ при запуске контейнера. Потеря seed без
заранее подготовленного следующего ключа блокирует выпуск новых доверенных
сборок; утечка требует немедленной ротации и отзыва ключа.
Поколения
release.generation увеличивается при каждой новой публикации. Launcher хранит
последнее принятое поколение и не принимает более старое, даже если его подпись
математически корректна. Повторять номер для другого содержимого нельзя.
Ротация
Ротация выполняется офлайн через wraithbound-keyctl, а не через админку:
- Создайте следующий private key и экспортируйте его public key.
- Командой
registry-add --state active добавьте public key в keys.json.
- Разверните реестр с двумя
active ключами, продолжая подписывать bundle
прежним ключом.
- Выпустите launcher, который принял обновлённый bundle.
- Замените mounted private key сервиса на новый. Launcher-server проверит,
что он присутствует в реестре со статусом
active.
- Переведите старый key ID в
retiring, а после переходного периода — в
revoked.
Каждое изменение реестра увеличивает generation. Новый JSON сначала пишется
во временный файл; при Windows-замене существующая версия сохраняется как
backup до успешной активации. Точные команды и порядок ротации описаны в
tools/keyctl/README.md.
Корневой ключ trust bundle должен быть отделён от online manifest key. Текущий
первый этап использует единый ключ сервиса; перед production rollout требуется
закрепить offline root public key в проверяющих native binaries.