Механизм секретов trdl — встроенный плагин Stronghold EE для безопасной доставки релизов ПО по модели trdl. Плагин собирает артефакты релиза из Git-тега, подписывает их и публикует в S3-хранилище, а также публикует каналы обновлений. Сборка и публикация выполняются только для коммитов, у которых есть требуемое число проверенных PGP-подписей (кворум).

Основные свойства:

  • исходный код и конфигурация релиза (trdl.yaml) хранятся в Git-репозитории;
  • конфигурация каналов обновлений (trdl_channels.yaml) может храниться в отдельной ветке;
  • доверенные открытые PGP-ключи и требуемое число подписей задаются в конфигурации плагина;
  • артефакты релиза подписываются PGP-ключом, которым управляет плагин;
  • поддерживается подпись macOS-сборок и ELF-бинарников через Delivery Kit;
  • сборки выполняются асинхронно в виде задач, статус и журнал которых доступны через API.

Плагин — серверная часть модели trdl (модуль github.com/werf/trdl/server). Форматы конфигурации релиза:

  • trdl.yaml (путь задаётся параметром git_trdl_path): обязательное поле dockerImage (имя образа сборщика с digest) и обязательный список commands, выполняемых в контейнере; результат нужно поместить в /result;
  • trdl_channels.yaml (путь задаётся параметром git_trdl_channels_path): список groups, в каждой группе — name и channels (name и version каждого канала).

Подписи плагином отдельно не хранятся: это PGP-подписи, встроенные в объекты Git. Для аннотированного тега проверяется подпись тега, для легковесного — подпись коммита, на который он указывает. Подписи проверяются по доверенным открытым ключам из конфигурации плагина.

Настройка

  1. Включите механизм секретов:

    d8 stronghold secrets enable -path=trdl-myapp trdl
  2. Настройте плагин: Git-репозиторий, S3-хранилище для публикации и требуемое число проверенных подписей коммита:

    d8 stronghold write trdl-myapp/configure git_repo_url="https://git.example.com/org/myapp.git" required_number_of_verified_signatures_on_commit=2 s3_endpoint="https://s3.example.com" s3_region="ru-central1" s3_bucket_name="myapp-tuf" s3_access_key_id="<S3_ACCESS_KEY_ID>" s3_secret_access_key="<S3_SECRET_ACCESS_KEY>"

    Где <S3_ACCESS_KEY_ID> и <S3_SECRET_ACCESS_KEY> — идентификатор ключа доступа и секретный ключ доступа к S3-хранилищу.

    Обязательные параметры:

    ПараметрОписание
    git_repo_urlURL Git-репозитория.
    required_number_of_verified_signatures_on_commitТребуемое число проверенных подписей коммита.
    s3_endpoint, s3_region, s3_bucket_nameЭндпоинт, регион и имя бакета S3-хранилища.
    s3_access_key_id, s3_secret_access_keyУчётные данные доступа к S3-хранилищу.

    Дополнительные параметры:

    ПараметрОписание
    git_trdl_pathПуть к файлу конфигурации релиза в репозитории. По умолчанию trdl.yaml.
    git_trdl_channels_pathПуть к файлу конфигурации каналов. По умолчанию trdl_channels.yaml.
    git_trdl_channels_branchОтдельная ветка Git для файла конфигурации каналов.
    initial_last_published_git_commitНачальный коммит последней успешной публикации.
    buildx_driver, buildx_driver_optsДрайвер buildx для сборки (docker-container по умолчанию или kubernetes) и его опции.
    buildkitd_addressАдрес запущенного buildkitd (unix://, tcp://, docker-container:// или kube-pod://).
    buildkitd_driver, buildkitd_driver_optsЭфемерный buildkitd для каждой сборки (например, kubernetes) и его опции.

    Секреты сборки передаются демону buildkitd. Канал tcp:// не шифруется и не аутентифицируется, поэтому защитите канал и изолируйте демон самостоятельно.

  3. Добавьте доверенные открытые PGP-ключи, подписи которых учитываются при проверке кворума:

    d8 stronghold write trdl-myapp/configure/trusted_pgp_public_key name="developer-1" public_key=@developer-1.asc

    Список добавленных ключей:

    d8 stronghold list trdl-myapp/configure/trusted_pgp_public_key
  4. Если репозиторий закрытый, настройте учётные данные Git:

    d8 stronghold write trdl-myapp/configure/git_credential username="trdl-bot" password="<GIT_ACCESS_TOKEN>"

    Где <GIT_ACCESS_TOKEN> — токен доступа пользователя trdl-bot на Git-сервере.

  5. При необходимости добавьте секреты сборки, которые будут доступны при сборке артефактов:

    d8 stronghold write trdl-myapp/configure/build/secrets id="npm-token" data="<SECRET_VALUE>"

    Где <SECRET_VALUE> — значение секрета сборки.

  6. При необходимости настройте менеджер задач:

    d8 stronghold write trdl-myapp/task/configure task_timeout=30m task_history_limit=10

Подпись артефактов

  • Открытую часть PGP-ключа, которым плагин подписывает артефакты релиза, можно прочитать по пути configure/pgp_signing_key:

    d8 stronghold read trdl-myapp/configure/pgp_signing_key

    Ключ подписи генерируется автоматически при первом обращении (RSA, хранится в хранилище плагина). Чтение configure/pgp_signing_key возвращает открытую часть в поле public_key. Операция delete по этому пути удаляет текущий ключ, новый будет сгенерирован по требованию.

  • Для подписи macOS-сборок задайте сертификат и параметры Notary в configure/build/mac_signing_identity (data, password, notary_issuer, notary_key, notary_key_id).

  • Для подписи ELF-бинарников через Delivery Kit задайте сертификат и закрытый ключ в configure/delivery_kit_elf_signing. Ключ можно передать в base64 или ссылкой hashivault://<KEY_NAME> на ключ механизма секретов Transit; в этом случае задайте параметры vault_*.

Использование

  1. Выполните релиз для подписанного Git-тега:

    d8 stronghold write trdl-myapp/release git_tag="v1.2.3"

    Плагин проверяет подписи, собирает и публикует артефакты. Операция выполняется асинхронно: в ответе возвращается идентификатор задачи.

    В ответе возвращается UUID задачи в поле task_uuid.

  2. Опубликуйте каналы обновлений из файла trdl_channels.yaml:

    d8 stronghold write -force trdl-myapp/publish
  3. Отслеживайте задачи:

    d8 stronghold read trdl-myapp/task
    d8 stronghold read trdl-myapp/task/<TASK_UUID>
    d8 stronghold read trdl-myapp/task/<TASK_UUID>/log

    Где <TASK_UUID> — идентификатор задачи из списка задач.

    Чтобы отменить выполняющуюся задачу:

    d8 stronghold write -force trdl-myapp/task/<TASK_UUID>/cancel

Последний опубликованный коммит хранится по пути configure/last_published_git_commit; его можно прочитать или удалить.

Полный список эндпоинтов и параметров приведён в справочнике API механизмов секретов.