Использование секретов Vault в CI/CD¶
В AppSec.Code можно использовать секреты Vault в конвейерах CI/CD. Для аутентификации в Vault применяются ID-токены.
Прежде чем использовать секреты Vault в задании CI/CD, необходимо настроить сервер Vault. Подробнее о настройке Vault и аутентификации с помощью ID-токенов см. в документации Vault.
Примечание
В приведённых ниже примерах замените vault.example.com на URL вашего сервера Vault, а appseccode.example.com — на URL вашего экземпляра AppSec.Code.
Настройка сервера Vault¶
Чтобы настроить сервер Vault, выполните следующие действия:
-
Включите метод аутентификации, выполнив приведённые ниже команды. Они передают серверу Vault OIDC Discovery URL вашего экземпляра AppSec.Code, благодаря чему Vault может получить публичный ключ подписи и проверить JSON Web Token (JWT) при аутентификации:
-
Настройте политики на сервере Vault, чтобы разрешить или запретить доступ к определённым путям и операциям. В этом примере предоставляется доступ на чтение к набору секретов, необходимых для рабочего окружения:
-
Настройте роли на сервере Vault, ограничив их областью проекта или пространства имён.
-
Создайте следующие переменные CI/CD, описывающие параметры сервера Vault (см. раздел «Переменные CI/CD»):
VAULT_SERVER_URL— URL сервера Vault, например,https://vault.example.com:8200.VAULT_AUTH_ROLE— необязательная переменная для указания роли аутентификации. Если роль не указана, Vault использует роль по умолчанию, указанную при настройке метода аутентификации.VAULT_AUTH_PATH— необязательная переменная; путь, по которому подключён метод аутентификации. По умолчаниюjwt.VAULT_NAMESPACE— необязательная переменная; пространство имён Vault Enterprise, используемое для чтения секретов и аутентификации:- Для Vault, пространство имен
root(«/») используется, если пространство имен не указано. - Для Vault Open source, параметр игнорируется.
- Для облачной платформы HCP Vault, требуется указать пространство имен. HCP Vault по умолчанию использует пространство имен администратора в качестве корневого пространства имен, например,
VAULT_NAMESPACE=admin.
- Для Vault, пространство имен
Настройка ролей сервера¶
При попытке аутентификации задание CI/CD указывает роль. Роли позволяют группировать различные политики. При успешной аутентификации эти политики привязываются к выданному токену Vault.
Привязанные утверждения (bound claims) — это предопределённые значения, которые сопоставляются с утверждениями JWT. С их помощью можно ограничить доступ конкретными пользователями, конкретными проектами или даже заданиями, выполняемыми для определённых Git-ссылок. Привязанных утверждений может быть сколько угодно, но для успешной аутентификации должны совпасть все.
Сочетая привязанные утверждения с возможностями AppSec.Code, такими как роли пользователей и защищённые ветки, можно адаптировать эти правила под конкретный сценарий. В следующем примере аутентификация разрешена только для заданий, выполняемых для защищённых тегов с именами, соответствующими шаблону для рабочих релизов:
$ vault write auth/jwt/role/myproject-production - <<EOF
{
"role_type": "jwt",
"policies": ["myproject-production"],
"token_explicit_max_ttl": 60,
"user_claim": "user_email",
"bound_audiences": "https://vault.example.com",
"bound_claims_type": "glob",
"bound_claims": {
"project_id": "42",
"ref_protected": "true",
"ref_type": "tag",
"ref": "auto-deploy-*"
}
}
EOF
Внимание
Всегда ограничивайте роли областью проекта или пространства имён, используя одно из доступных утверждений, например project_id или namespace_id. Без таких ограничений любой JWT, выпущенный этим экземпляром AppSec.Code, сможет пройти аутентификацию с использованием этой роли.
Для выдаваемых токенов Vault можно также задать ряд атрибутов: время жизни (time-to-live), диапазон IP-адресов и число использований. Полный список параметров приведён в документации Vault по созданию ролей для метода аутентификации JSON Web Token.
Использование секретов Vault в задании CI/CD¶
Если в задании определён хотя бы один ID-токен, ключевое слово secrets автоматически использует этот токен для аутентификации в Vault.
После настройки сервера Vault используйте ключевое слово secrets:vault для доступа к секретам, хранящимся в Vault (см. раздел «secrets:vault»):
job_using_vault:
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.example.com
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
token: $VAULT_ID_TOKEN
В этом примере:
production/db— путь к секрету.password— поле.ops— путь монтирования движка секретов.production/db/password@opsпреобразуется в путьops/data/production/db.- Аутентификация выполняется с использованием
$VAULT_ID_TOKEN.
После того как AppSec.Code получает секрет из Vault, его значение сохраняется во временный файл. Путь к этому файлу записывается в переменную CI/CD с именем DATABASE_PASSWORD — аналогично переменным типа file.
Чтобы переопределить поведение по умолчанию, явно задайте параметр file (см. раздел «secrets:file»):
secrets:
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.example.com
DATABASE_PASSWORD:
vault: production/db/password@ops
file: false
token: $VAULT_ID_TOKEN
В этом примере значение секрета помещается непосредственно в переменную DATABASE_PASSWORD, а не указывает на файл с этим значением.
Движки секретов¶
Раннер поддерживает различные движки секретов через ключевое слово secrets:engine:name:
| Движок секретов | Значение secrets:engine:name |
Описание |
|---|---|---|
| KV secrets engine — version 2 | kv-v2 |
Движок, используемый раннером по умолчанию при отсутствии явного указания типа движка. |
| KV secrets engine — version 1 | kv-v1 или generic |
— |
| AWS secrets engine | generic |
— |
| Vault Artifactory Secrets Plugin | generic |
Взаимодействует с сервером JFrog Artifactory версии 5.0.0 и выше, динамически выдаёт токены доступа с заданными правами. |
Использование другого движка секретов¶
По умолчанию используется kv-v2. Чтобы применить другой движок, добавьте секцию engine под vault в конфигурацию.
Пример настройки движка секретов и пути для Artifactory:
job_using_vault:
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.example.com
secrets:
JFROG_TOKEN:
vault:
engine:
name: generic
path: artifactory
path: production/jfrog
field: access_token
file: false
В этом примере значение секрета получается из artifactory/production/jfrog с полем access_token.
Устранение неполадок¶
Ошибка самоподписанного сертификата: certificate signed by unknown authority¶
Если сервер Vault использует самоподписанный сертификат, в логах задания появляется следующая ошибка:
ERROR: Job failed (system failure): resolving secrets: initializing Vault service: preparing authenticated client: checking Vault server health: Get https://vault.example.com:8000/v1/sys/health?drsecondarycode=299&performancestandbycode=299&sealedcode=299&standbycode=299&uninitcode=299: x509: certificate signed by unknown authority
Устранить эту ошибку можно одним из двух способов:
- Добавьте самоподписанный сертификат в хранилище CA на сервере раннера. Если раннер развёрнут с помощью Helm chart, потребуется создать собственный образ раннера (см. раздел «Запуск средства выполнения (раннера)»).
- Используйте переменную окружения
VAULT_CACERT, чтобы настроить раннер на доверие сертификату:- При управлении раннером через systemd добавьте пользовательскую переменную окружения для раннера.
-
Если раннер развёрнут с помощью Helm chart:
- Предоставьте пользовательский сертификат для доступа к серверу Vault и убедитесь, что добавлен именно сертификат сервера Vault, а не сертификат AppSec.Code. Если экземпляр AppSec.Code также использует самоподписанный сертификат, оба сертификата можно добавить в один и тот же
Secret. - Добавьте следующие строки в файл
values.yaml:
- Предоставьте пользовательский сертификат для доступа к серверу Vault и убедитесь, что добавлен именно сертификат сервера Vault, а не сертификат AppSec.Code. Если экземпляр AppSec.Code также использует самоподписанный сертификат, оба сертификата можно добавить в один и тот же
Если сервер Vault запущен локально в режиме разработки, эта ошибка также может возникать. В этом случае можно вручную добавить самоподписанный сертификат сервера Vault в доверенные. Например, для macOS процесс описан в этом руководстве.
Ошибка resolving secrets: secret not found: MY_SECRET¶
Если AppSec.Code не может найти секрет в Vault, может возникнуть следующая ошибка:
Убедитесь, что значение vault корректно настроено в задании CI/CD (см. раздел «Использование секретов Vault в задании CI/CD»).
Для проверки доступности секрета и определения синтаксиса значения vault в конфигурации CI/CD можно использовать команду kv в Vault CLI. Например, чтобы получить секрет: