НОВОСТИ [Перевод] Аутентификация и чтение секретов в HashiCorp's Vault через GitLab CI

NewsBot
Оффлайн

NewsBot

.
.
Регистрация
21.07.20
Сообщения
40.408
Реакции
1
Репутация
0
Доброго времени суток, читатель!


22 апреля в GitLab выпустили релиз 12.10 и сообщили о том, что теперь CI-процесс может авторизовываться в Hashicorp's Vault через JSON Web Token (JWT), и для авторизации нет необходимости хранить токен для доступа к нужным policy в переменных окружения (или где-либо ещё).

bxa5cebbb0_hmjtk5x6eiielbii.png


Данная фича показалась нам полезной, поэтому предлагаем перевод соотвествующего туториала из официальной документации 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 при помощи метода .


Пример того, как выглядит 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 ( ) как конечную точку JWKS для аутентификации на Vault сервере, если для него настроен соответствующий метод JWT-аутентификации.


При настройке ролей в Vault, вы можете задавать значения для сопоставления их с полями из JWT и, таким образом, дополнительно ограничить то, к каким секретам какой процесс CI будет иметь доступ.


Для получения доступа к Vault можно использовать либо его CLI, либо выполнять запросы к API (через curl или другой клиент).

Пример



Предположим, у вас есть пароли для ваших баз данных, отличающиеся для production и staging окружений и они хранятся в Vault, который доступен по адресу . Ваш пароль для 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>


В этом примере использовались указывающие, что только JWT-токены с соответствующими значениями смогут пройти аутентификацию.


В сочетании с GitLab , можно разграничивать тех, кто может проходить аутентификацию и читать секреты.


определяет, что выпущенный Vault токен, после аутентификации имеет время жизни 60 секунд.


определяет имя пользователя, которое будет использовать Vault при успешной авторизации. (Прим. Переводчика — В нашем случае "user_claim" = "user_email", то есть имя пользователя будет иметь значение email, которое указано в JWT-токене как "user_email". То есть определяться как (известный GitLab) email пользователя, запустившего задание.)


Параметр задает формат значений bound_claims. Если он установлен в “glob”, то значения будут интерпретироваться в формате glob и будет означать любое количество символов. (Прим. Переводчика — Также доступно значение “string”, в этом случае данные будут хранится в формате строк и “” будет означать только “*”.)
Полный лист опций можно посмотреть в Vault’s .


Предупреждение: обязательно устанавливайте либо project_id либо namespace_id, иначе любой токен, сгенерированный этим инстансом GitLab, сможет использовать эту роль.


Теперь зададим метод аутентификации через JWT:


$ vault write auth/jwt/config \
jwks_url=" " \
bound_issuer="gitlab.example.com"


определяет, что только токены, выпущенные от gitlab.example.com (iss claim) могут использовать этот метод аутентификации, и в качестве точки валидации токена JWKS должна использоваться страница .


Полный список доступных опций можно посмотреть в .


Теперь создадим джобу для 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)"

3m1gajspltz8vbsih_z5uxbs648.png


Следующее задание сможет пройти аутентификацию через роль 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

yirfyaz-d3pfaevjtbz7jksz9m8.png



На этом все, надеюсь данный туториал окажется вам полезен!


Мы также ждем следующей фичи GitLab, где можно будет авторизовываться в Vault средствами GitLab в версии 13.4, которая выйдет 22 сентября 2020.
 
Сверху Снизу