- Регистрация
- 21.07.20
- Сообщения
- 40.408
- Реакции
- 1
- Репутация
- 0
Доброго времени суток, читатель!
22 апреля в GitLab выпустили релиз 12.10 и сообщили о том, что теперь CI-процесс может авторизовываться в Hashicorp's Vault через JSON Web Token (JWT), и для авторизации нет необходимости хранить токен для доступа к нужным policy в переменных окружения (или где-либо ещё).
Данная фича показалась нам полезной, поэтому предлагаем перевод соотвествующего туториала из официальной документации GitLab:
Этот туториал демонстрирует пример аутентификации, конфигурации и чтения секретов с HashiCorp’s Vault через GitLab CI/CD.
Требования
Туториал предполагает, что вы знакомы с GitLab CI/CD и Vault.
Чтобы ему последовать, вам понадобятся:
Примечание: вам нужно заменить URL vault.example.com на URL вашего Vault сервера и gitlab.example.com на название вашего GitLab инстанса.
Как это работает
Для каждой задачи (job) генерируется свой уникальный токен JSON Web Token (JWT), доступный только как значение переменной окружения CI_JOB_JWT конкретной задачи. Данный JWT может быть использован для аутентификации в Vault при помощи метода
Пример того, как выглядит JWT в дешифрованном виде:
{
"jti": "c82eeb0c-5c6f-4a33-abf5-4c474b92b558", # Уникальный идентификатор токена
"iss": "gitlab.example.com", # Issuer, т.е. домен вашего инстанса GitLab
"iat": 1585710286, # Время выдачи
"nbf": 1585798372, # Не валиден до
"exp": 1585713886, # Не велиден после
"sub": "22", # Subject (project id)
"namespace_id": "1",
"namespace_path": "mygroup",
"project_id": "22",
"project_path": "mygroup/myproject",
"user_id": "42",
"user_login": "myuser",
"user_email": "[email protected]"
"pipeline_id": "1212",
"job_id": "1212",
"ref": "auto-deploy-2020-04-01", # Название Git-refs для этой задачи
"ref_type": "branch", # Тип Git-refs, это либо(branch) либо тег(tag)
"ref_protected": "true" # true, если это ветка protected, иначе false
}
Токен кодируется по стандарту RS256 и подписывается приватным ключом OpenID Connect вашего GitLab инстанса, причем этот ключ периодически изменяется без вашего ведома. И, если приватный ключ был изменен, при cледующем запуске задания новый JWT будет подписан с новым ключом. Срок валидности токена будет устанавливаться в соотвествии с таймаутом вашего задания, а если он не задан, то срок валидности будет 5 минут.
Вы можете использовать этот JWT-токен и URL (
При настройке ролей в Vault, вы можете задавать значения
Для получения доступа к Vault можно использовать либо его CLI, либо выполнять запросы к API (через curl или другой клиент).
Пример
Предположим, у вас есть пароли для ваших баз данных, отличающиеся для production и staging окружений и они хранятся в Vault, который доступен по адресу
$ vault kv get -field=password secret/myproject/staging/db
pa$$w0rd
$ vault kv get -field=password secret/myproject/production/db
real-pa$$w0rd
Разрешим для нашего Vault-сервера метод аутентификации через JWT:
$ vault auth enable jwt
Success! Enabled jwt auth method at: jwt/
Создаем policy, которые дают доступ на чтение к нужным нам секретам:
$ vault policy write myproject-staging - data/myproject/staging/*' path
path "secret/data/myproject/staging/*" {
capabilities = [ "read" ]
}
EOF
Success! Uploaded policy: myproject-staging
$ vault policy write myproject-production - data/myproject/production/*' path
path "secret/data/myproject/production/*" {
capabilities = [ "read" ]
}
EOF
Success! Uploaded policy: myproject-production
Теперь нам нужны роли, которые будут связывать созданные политики с JWT-токенами.
Для stage под названием myproject-staging:
$ vault write auth/jwt/role/myproject-staging - code>
И для production под названием myproject-production:
$ vault write auth/jwt/role/myproject-production - code>
В этом примере использовались
В сочетании с GitLab
Параметр
Полный лист опций можно посмотреть в Vault’s
Предупреждение: обязательно устанавливайте либо project_id либо namespace_id, иначе любой токен, сгенерированный этим инстансом GitLab, сможет использовать эту роль.
Теперь зададим метод аутентификации через JWT:
$ vault write auth/jwt/config \
jwks_url="
bound_issuer="gitlab.example.com"
Полный список доступных опций можно посмотреть в
Теперь создадим джобу для master-ветки, у которой будут права на чтение secret/myproject/staging/, но при этом не будет прав на чтение secret/myproject/production/:
read_secrets:
script:
# Проверяем имя ref джобы
- echo $CI_COMMIT_REF_NAME
# и является ли она protected
- echo $CI_COMMIT_REF_PROTECTED
# Адрес Vault может быть передан через переменную в CI
- export VAULT_ADDR=
# Проходим аутентификацию и получаем токен. Время истечения жизни токена и другие
# его параметры можно задать при конфигурации
# JWT Auth -
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-staging jwt=$CI_JOB_JWT)"
# Теперь используем VAULT_TOKEN для чтения секретов и сохранения их в перемнных окружения
- export PASSWORD="$(vault kv get -field=password secret/myproject/staging/db)"
# Используем секрет
- echo $PASSWORD
# Здесь получить секрет не получится, потому что роль myproject-staging не может
# читать секреты из secret/myproject/production/*
- export PASSWORD="$(vault kv get -field=password secret/myproject/production/db)"
Следующее задание сможет пройти аутентификацию через роль myproject-production и прочитать секрет в /secret/myproject/production/:
read_secrets:
script:
# Проверяем имя ref джобы
- echo $CI_COMMIT_REF_NAME
# и является ли она protected
- echo $CI_COMMIT_REF_PROTECTED
# Адрес Vault может быть передан через переменную в CI
- export VAULT_ADDR=
# Проходим аутентификацию и получаем токен. Время истечения жизни токена и другие
# его параметры можно задать при конфигурации
# JWT Auth -
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-production jwt=$CI_JOB_JWT)"
# Теперь используем VAULT_TOKEN для чтения секретов и сохранения их в перемнных окружения
- export PASSWORD="$(vault kv get -field=password secret/myproject/production/db)"
# Используем секрет
- echo $PASSWORD
На этом все, надеюсь данный туториал окажется вам полезен!
Мы также ждем следующей фичи GitLab, где можно будет авторизовываться в Vault средствами GitLab в версии 13.4, которая выйдет 22 сентября 2020.
22 апреля в GitLab выпустили релиз 12.10 и сообщили о том, что теперь CI-процесс может авторизовываться в Hashicorp's Vault через JSON Web Token (JWT), и для авторизации нет необходимости хранить токен для доступа к нужным policy в переменных окружения (или где-либо ещё).
Данная фича показалась нам полезной, поэтому предлагаем перевод соотвествующего туториала из официальной документации GitLab:
Этот туториал демонстрирует пример аутентификации, конфигурации и чтения секретов с HashiCorp’s Vault через GitLab CI/CD.
Требования
Туториал предполагает, что вы знакомы с GitLab CI/CD и Vault.
Чтобы ему последовать, вам понадобятся:
- Аккаунт в GItLab
- Запущенный Vault сервер и доступ для настройки аутентификации и создания ролей и политик.
Примечание: вам нужно заменить URL vault.example.com на URL вашего Vault сервера и gitlab.example.com на название вашего GitLab инстанса.
Как это работает
Для каждой задачи (job) генерируется свой уникальный токен JSON Web Token (JWT), доступный только как значение переменной окружения CI_JOB_JWT конкретной задачи. Данный JWT может быть использован для аутентификации в Vault при помощи метода
You must be registered for see links
.Пример того, как выглядит JWT в дешифрованном виде:
{
"jti": "c82eeb0c-5c6f-4a33-abf5-4c474b92b558", # Уникальный идентификатор токена
"iss": "gitlab.example.com", # Issuer, т.е. домен вашего инстанса GitLab
"iat": 1585710286, # Время выдачи
"nbf": 1585798372, # Не валиден до
"exp": 1585713886, # Не велиден после
"sub": "22", # Subject (project id)
"namespace_id": "1",
"namespace_path": "mygroup",
"project_id": "22",
"project_path": "mygroup/myproject",
"user_id": "42",
"user_login": "myuser",
"user_email": "[email protected]"
"pipeline_id": "1212",
"job_id": "1212",
"ref": "auto-deploy-2020-04-01", # Название Git-refs для этой задачи
"ref_type": "branch", # Тип Git-refs, это либо(branch) либо тег(tag)
"ref_protected": "true" # true, если это ветка protected, иначе false
}
Токен кодируется по стандарту RS256 и подписывается приватным ключом OpenID Connect вашего GitLab инстанса, причем этот ключ периодически изменяется без вашего ведома. И, если приватный ключ был изменен, при cледующем запуске задания новый JWT будет подписан с новым ключом. Срок валидности токена будет устанавливаться в соотвествии с таймаутом вашего задания, а если он не задан, то срок валидности будет 5 минут.
Вы можете использовать этот JWT-токен и URL (
You must be registered for see links
) как конечную точку JWKS для аутентификации на Vault сервере, если для него настроен соответствующий метод JWT-аутентификации.При настройке ролей в Vault, вы можете задавать значения
You must be registered for see links
для сопоставления их с полями из JWT и, таким образом, дополнительно ограничить то, к каким секретам какой процесс CI будет иметь доступ.Для получения доступа к Vault можно использовать либо его CLI, либо выполнять запросы к API (через curl или другой клиент).
Пример
Предположим, у вас есть пароли для ваших баз данных, отличающиеся для production и staging окружений и они хранятся в Vault, который доступен по адресу
You must be registered for see links
. Ваш пароль для stage это pa$$w0rd и real-pa$$w0rd для prod:$ vault kv get -field=password secret/myproject/staging/db
pa$$w0rd
$ vault kv get -field=password secret/myproject/production/db
real-pa$$w0rd
Разрешим для нашего Vault-сервера метод аутентификации через JWT:
$ vault auth enable jwt
Success! Enabled jwt auth method at: jwt/
Создаем policy, которые дают доступ на чтение к нужным нам секретам:
$ vault policy write myproject-staging - data/myproject/staging/*' path
path "secret/data/myproject/staging/*" {
capabilities = [ "read" ]
}
EOF
Success! Uploaded policy: myproject-staging
$ vault policy write myproject-production - data/myproject/production/*' path
path "secret/data/myproject/production/*" {
capabilities = [ "read" ]
}
EOF
Success! Uploaded policy: myproject-production
Теперь нам нужны роли, которые будут связывать созданные политики с JWT-токенами.
Для stage под названием myproject-staging:
$ vault write auth/jwt/role/myproject-staging - code>
И для production под названием myproject-production:
$ vault write auth/jwt/role/myproject-production - code>
В этом примере использовались
You must be registered for see links
указывающие, что только JWT-токены с соответствующими значениями смогут пройти аутентификацию.В сочетании с GitLab
You must be registered for see links
, можно разграничивать тех, кто может проходить аутентификацию и читать секреты.
You must be registered for see links
определяет, что выпущенный Vault токен, после аутентификации имеет время жизни 60 секунд.
You must be registered for see links
определяет имя пользователя, которое будет использовать Vault при успешной авторизации. (Прим. Переводчика — В нашем случае "user_claim" = "user_email", то есть имя пользователя будет иметь значение email, которое указано в JWT-токене как "user_email". То есть определяться как (известный GitLab) email пользователя, запустившего задание.)Параметр
You must be registered for see links
задает формат значений bound_claims. Если он установлен в “glob”, то значения будут интерпретироваться в формате glob и будет означать любое количество символов. (Прим. Переводчика — Также доступно значение “string”, в этом случае данные будут хранится в формате строк и “” будет означать только “*”.)Полный лист опций можно посмотреть в Vault’s
You must be registered for see links
.Предупреждение: обязательно устанавливайте либо project_id либо namespace_id, иначе любой токен, сгенерированный этим инстансом GitLab, сможет использовать эту роль.
Теперь зададим метод аутентификации через JWT:
$ vault write auth/jwt/config \
jwks_url="
You must be registered for see links
" \bound_issuer="gitlab.example.com"
You must be registered for see links
определяет, что только токены, выпущенные от gitlab.example.com (iss claim) могут использовать этот метод аутентификации, и в качестве точки валидации токена JWKS должна использоваться страница
You must be registered for see links
.Полный список доступных опций можно посмотреть в
You must be registered for see links
.Теперь создадим джобу для master-ветки, у которой будут права на чтение secret/myproject/staging/, но при этом не будет прав на чтение secret/myproject/production/:
read_secrets:
script:
# Проверяем имя ref джобы
- echo $CI_COMMIT_REF_NAME
# и является ли она protected
- echo $CI_COMMIT_REF_PROTECTED
# Адрес Vault может быть передан через переменную в CI
- export VAULT_ADDR=
You must be registered for see links
# Проходим аутентификацию и получаем токен. Время истечения жизни токена и другие
# его параметры можно задать при конфигурации
# JWT Auth -
You must be registered for see links
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-staging jwt=$CI_JOB_JWT)"
# Теперь используем VAULT_TOKEN для чтения секретов и сохранения их в перемнных окружения
- export PASSWORD="$(vault kv get -field=password secret/myproject/staging/db)"
# Используем секрет
- echo $PASSWORD
# Здесь получить секрет не получится, потому что роль myproject-staging не может
# читать секреты из secret/myproject/production/*
- export PASSWORD="$(vault kv get -field=password secret/myproject/production/db)"
Следующее задание сможет пройти аутентификацию через роль myproject-production и прочитать секрет в /secret/myproject/production/:
read_secrets:
script:
# Проверяем имя ref джобы
- echo $CI_COMMIT_REF_NAME
# и является ли она protected
- echo $CI_COMMIT_REF_PROTECTED
# Адрес Vault может быть передан через переменную в CI
- export VAULT_ADDR=
You must be registered for see links
# Проходим аутентификацию и получаем токен. Время истечения жизни токена и другие
# его параметры можно задать при конфигурации
# JWT Auth -
You must be registered for see links
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-production jwt=$CI_JOB_JWT)"
# Теперь используем VAULT_TOKEN для чтения секретов и сохранения их в перемнных окружения
- export PASSWORD="$(vault kv get -field=password secret/myproject/production/db)"
# Используем секрет
- echo $PASSWORD
На этом все, надеюсь данный туториал окажется вам полезен!
Мы также ждем следующей фичи GitLab, где можно будет авторизовываться в Vault средствами GitLab в версии 13.4, которая выйдет 22 сентября 2020.



