Как происходит процесс аутентификации и авторизации через Vault

«Как происходит процесс аутентификации и авторизации через Vault» — вопрос из категории Безопасность, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

HashiCorp Vault — это центральный элемент в нашей системе управления секретами и доступом для инфраструктуры. Я использую его для безопасного хранения credentials, выдачи динамических секретов для БД и управления доступом к облачным ресурсам.

1. Аутентификация (Authentication): "Кто ты?" Vault поддерживает множество методов аутентификации (auth methods). В продакшене мы чаще всего используем:

  • JWT/OIDC для людей: Разработчики и инженеры аутентифицируются через корпоративный SSO (например, Okta). Vault проверяет JWT-токен, выданный провайдером.
  • Kubernetes Service Account для подов: Это основной метод для рабочих нагрузок внутри кластера K8s. Поды аутентифицируются, используя свой JWT-токен и роль службы.
    # Конфигурация метода аутентификации Kubernetes в Vault
    vault auth enable kubernetes
    vault write auth/kubernetes/config 
        token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" 
        kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" 
        kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  • AppRole для автоматизации (CI/CD, Terraform): Для не-human сущностей, которым нужен доступ к секретам. CI-сервер (например, Jenkins) использует свой role_id и secret_id для логина.

2. Авторизация (Authorization): "Что тебе можно?" Права доступа определяются политиками (policies), написанными на HCL. Политика привязывается к методу аутентификации и роли.

  • Пример политики, разрешающей pod'у читать секреты для своей БД:

    # policy.hcl
    path "database/creds/myapp-role" {
      capabilities = ["read"]
    }
    path "secret/data/myapp/*" {
      capabilities = ["read"]
    }

    Эта политика позволяет читать динамические credentials для БД и статические конфиги по определенному пути.

  • Создание роли Kubernetes, которая связывает SA в K8s с политикой в Vault:

    vault write auth/kubernetes/role/myapp-role 
        bound_service_account_names=myapp-sa 
        bound_service_account_namespaces=production 
        policies=myapp-policy 
        ttl=1h

    Теперь любой под в неймспейсе production с ServiceAccount myapp-sa может аутентифицироваться в Vault и получит токен с политикой myapp-policy на 1 час.

3. Практический пример: Получение динамического секрета БД из пода: Приложение в своем манифесте указывает ServiceAccount и использует sidecar-контейнер или библиотеку для взаимодействия с Vault.

# Фрагмент Deployment в Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      serviceAccountName: myapp-sa # SA, привязанная к роли в Vault
      containers:
      - name: app
        image: myapp:latest
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-creds # Секрет, который будет обновляться Vault Agent
---
# Конфигурация Vault Agent Injector (аннотации к поду)
apiVersion: v1
kind: Pod
metadata:
  annotations:
    vault.hashicorp.com/agent-inject: "true"
    vault.hashicorp.com/role: "myapp-role"
    vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/myapp-role"
    vault.hashicorp.com/agent-inject-template-db-creds: |
      {{- with secret "database/creds/myapp-role" -}}
      {
        "username": "{{ .Data.username }}",
        "password": "{{ .Data.password }}"
      }
      {{- end }}

В этом сценарии Vault Agent автоматически инжектируется в под, аутентифицируется, получает короткоживущие логин/пароль от БД и записывает их в том db-creds, откуда основное приложение их считывает. Credentials автоматически ротируются по истечении TTL.