AppRole: вход для приложений

Как сервис без человека за клавиатурой доказывает Vault, что он — именно тот сервис.

AppRole — auth-метод для машин: приложение логинится парой RoleID (кто я) и SecretID (доказательство), получая токен с политиками роли.

У приложения нет пароля, который можно ввести руками. AppRole даёт ему две «половинки» учётки: относительно публичный RoleID и секретный одноразовый или ограниченный SecretID. По аналогии — это логин и пароль, но спроектированные под автоматизацию.

Настройка роли

vault auth enable approle

# создаём роль с политикой и временем жизни токена
vault write auth/approle/role/myapp \
  token_policies="myapp-read" \
  token_ttl=1h \
  token_max_ttl=4h \
  secret_id_ttl=24h

Получение RoleID и SecretID

RoleID стабилен и привязан к роли — его можно зашить в конфиг деплоя. SecretID генерируется по запросу и хранится в секрете:

# RoleID -- относительно публичный
vault read auth/approle/role/myapp/role-id

# SecretID -- секретный, генерируем
vault write -f auth/approle/role/myapp/secret-id
role_id    7e1f...c2
secret_id  9a3b...f8   (показывается один раз)

Логин приложения

Приложение обменивает обе части на токен:

vault write auth/approle/login \
  role_id="7e1f...c2" \
  secret_id="9a3b...f8"
{
  "auth": {
    "client_token": "hvs.CAES...",
    "token_policies": ["default", "myapp-read"],
    "lease_duration": 3600
  }
}

Зачем разделять RoleID и SecretID

Разделение — главная идея AppRole, борьба с «secret zero» (проблемой первого секрета). RoleID можно поставлять статично (в образ, в манифест) — сам по себе он бесполезен. SecretID доставляют отдельным, более защищённым каналом и делают короткоживущим или одноразовым. Чтобы залогиниться, злоумышленнику нужны обе части из разных источников.

Как работает под капотом: доставка SecretID

Лучшая практика — response wrapping: доверенный оркестратор запрашивает SecretID «в обёртке», получает одноразовый wrapping-токен и передаёт его приложению. Приложение разворачивает токен и достаёт SecretID ровно один раз. Если кто-то перехватил обёртку и развернул раньше — приложение получит ошибку и инцидент будет замечен.

vault write -wrap-ttl=120s -f auth/approle/role/myapp/secret-id

Частые ошибки

  • Хранить SecretID долгоживущим в образе рядом с RoleID — это снова один секрет, secret zero не решён.
  • Не ограничивать secret_id_ttl и число использований — украденный SecretID работает вечно.
  • Логировать SecretID при отладке — он мгновенно компрометируется.

Итог

  • AppRole логинит приложения парой RoleID + SecretID, отдавая токен с политиками роли.
  • RoleID можно поставлять статично; SecretID — короткоживущий и доставляется отдельным каналом.
  • Response wrapping безопасно доставляет SecretID и выявляет перехват.
Проверьте себя
1. Зачем AppRole разделяет вход на RoleID и SecretID?
AДля скорости логина
BЧтобы бороться с secret zero: RoleID можно поставлять статично, SecretID — отдельным защищённым каналом
CRoleID шифрует SecretID
DЭто требование Kubernetes
2. Какая часть AppRole считается относительно публичной и стабильной?
ASecretID
BRoleID
Cclient_token
Dwrapping-токен
3. Что даёт response wrapping при доставке SecretID?
AШифрует весь трафик Vault
BПередаёт SecretID одноразовым токеном; перехват разворачивания обнаруживается
CДелает SecretID бессрочным
DЗаменяет RoleID