Для улучшения работы сайта мы используем файлы cookies. Оставаясь на сайте, вы соглашаетесь с политикой обработки персональных данных.

Методы аутентификации. OIDC провайдеры

В данной статье собраны основные шаги по настройке приложения OIDC для различных провайдеров. Для получения более общей информации об использовании и работе см. документацию по методу StarVault JWT/OIDC.

Провайдеры OIDC часто обладают широкими возможностями настройки, поэтому вам следует ознакомиться с их рекомендуемыми параметрами и передовым опытом. Руководства, перечисленные ниже, в основном составлены сообществом и призваны помочь вам начать работу. Исправления и дополнения могут быть представлены через репозиторий StarVault Github.

1. Gitlab

  1. Перейдите в раздел Настройки  Приложения

  2. Заполните имя и URL перенаправления

  3. Убедитесь, что выбрали область openid

  4. Скопируйте идентификатор и секрет клиента

2. Keycloak

  1. Выберите/создайте пространство и клиента

  2. Выберите клиента и перейдите в раздел Настройки

  3. Проверьте настройки. Они должны соответствовать перечисленным ниже:

    • Протокол клиента: openid-connect

    • Тип доступа: конфиденциальный

    • Стандартный поток: включен

  4. Настройте действительные URL перенаправления

  5. Нажмите Сохранить

  6. Перейдите к разделу Учетные данные

  7. Выберите Client ID  Secret и запишите сгенерированный секрет

3. Kubernetes

Kubernetes может выступать в качестве OIDC-провайдера, чтобы StarVault мог подтверждать токены учетных записей служб с помощью аутентификации JWT/OIDC.

Механизм JWT auth не использует API TokenReview от Kubernetes при аутентификации, а вместо этого использует криптографию с открытым ключом для проверки содержимого JWT. Это означает, что токены, которые были отозваны Kubernetes, будут считаться действительными в StarVault до истечения их срока действия. Чтобы снизить этот риск, используйте короткие TTL для токенов учетных записей сервисов или используйте Kubernetes auth, который использует TokenReview API.

3.1. Использование обнаружения эмитента учетной записи

При использовании обнаружения эмитента учетной записи нужно предоставить только аутентификацию JWT с монтированным URL-адресом обнаружения OIDC, и иногда центр сертификации TLS, которому можно доверять. Это делает данный метод наиболее простым в настройке, если кластер Kubernetes соответствует требованиям.

Требования к кластеру Kubernetes:

  • Функция ServiceAccountIssuerDiscovery включена.

    • Присутствует с версии 1.18, по умолчанию включается с версии 1.20.

  • Флаг kube-apiserver --service-account-issuer установлен на URL, доступный из StarVault. По умолчанию публичный для большинства управляемых решений Kubernetes.

  • При входе в систему необходимо использовать недолговечные токены учетных записей сервисов.

    • Начиная с версии 1.21 токены, устанавливаемые в поды, по умолчанию короткоживущие.

Этапы настройки:

  1. Убедитесь, что URL-адреса обнаружения OIDC не требуют аутентификации:

    kubectl create clusterrolebinding oidc-reviewer  \
       --clusterrole=system:service-account-issuer-discovery \
       --group=system:unauthenticated
  2. Найдите URL-адрес эмитента кластера.

    ISSUER="$(kubectl get --raw /.well-known/openid-configuration | jq -r '.issuer')"
  3. Включите и настройте JWT-аутентификацию в StarVault.

  4. Если StarVault работает в Kubernetes:

    kubectl exec starvault-0 -- starvault auth enable jwt
    kubectl exec starvault-0 -- starvault write auth/jwt/config \
       oidc_discovery_url=https://kubernetes.default.svc.cluster.local \
       oidc_discovery_ca_pem=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  5. В качестве альтернативы, если StarVault не запущен в Kubernetes:

    Когда StarVault находится вне кластера, указанная ниже конечная точка $ISSUER может быть доступна или недоступна. Если это не так, можете настроить JWT-аутентификацию с помощью jwt_validation_pubkeys.

    starvault auth enable jwt
    starvault write auth/jwt/config oidc_discovery_url="${ISSUER}"
  6. Настройте роль и войдите в систему, как описано ниже.

[[open-keys] === Использование открытых ключей с проверкой JWT

Этот метод может быть полезен, если API Kubernetes недоступен из StarVault или если хотите, чтобы одна смонтированная JWT-аутентификация обслуживала несколько кластеров Kubernetes, объединяя их публичные подписанные ключи.

Требования к кластеру Kubernetes:

  • Функция ServiceAccountIssuerDiscovery включена.

    • Присутствует с версии 1.18, по умолчанию включается с версии 1.20.

  • Этого требования можно избежать, если возможно получить доступ к главным узлам Kubernetes для чтения открытого ключа подписи непосредственно с диска по адресу /etc/kubernetes/pki/sa.pub. В этом случае можете пропустить шаги по получению и последующему преобразованию ключа, так как он уже будет в формате PEM.

  • При входе в систему необходимо использовать недолговечные токены учетных записей сервисов.

    • Начиная с версии 1.21 токены, устанавливаемые в поды, по умолчанию короткоживущие.

Этапы настройки:

  1. Получите открытый ключ подписи учетной записи службы из JWKS URI вашего кластера.

    # Query the jwks_uri specified in /.well-known/openid-configuration
    kubectl get --raw "$(kubectl get --raw /.well-known/openid-configuration | jq -r '.jwks_uri' | sed -r 's/.*\.[^/]+(.*)/\1/')"
  2. Конвертируйте ключи из формата JWK в PEM. Вы можете использовать инструмент CLI или онлайн-конвертер.

  3. Настройте монтирование JWT-аутентификации с полученным открытыми ключами.

    starvault write auth/jwt/config \
       jwt_validation_pubkeys="-----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9...
    -----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9...
    -----END PUBLIC KEY-----"
  4. Настройте роль и войдите в систему, как описано ниже.

[[create-role] === Создание роли и вход в систему

После того как JWT-аутентификатор настроен, можете настроить роль и войти в систему. Ниже предполагается, что используется токен учетной записи проектируемого сервиса, доступный во всех подах по умолчанию. Если хотите контролировать аудиторию или TTL, смотрите раздел Указание TTL и аудитории ниже.

  1. Выберите любое значение из массива аудиторий по умолчанию. В этих примерах в массиве aud есть только одна аудитория — https://kubernetes.default.svc.cluster.local.

    Чтобы найти аудитории по умолчанию, либо создайте свежий токен (требуется kubectl v1.24.0+):

    kubectl create token default | cut -f2 -d. | base64 --decode

    Или прочитайте токен из файловой системы запущенного пода:

    kubectl exec my-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -f2 -d. | base64 --decode
  2. Создайте роль для JWT-аутентификации, которую может использовать сервисная учетная запись default из пространства имен default.

    starvault write auth/jwt/role/my-role \
       role_type="jwt" \
       bound_audiences="<AUDIENCE-FROM-PREVIOUS-STEP>" \
       user_claim="sub" \
       bound_subject="system:serviceaccount:default:default" \
       policies="default" \
       ttl="1h"
  3. После этого поды или другие клиенты, имеющие доступ к сервисной учетной записи JWT, могут войти в систему.

    starvault write auth/jwt/login \
       role=my-role \
       jwt=@/var/run/secrets/kubernetes.io/serviceaccount/token
    # ИЛИ эквивалентно:
    curl \
       --fail \
       --request POST \
       --header "X-Vault-Request: true" \
       --data '{"jwt":"<JWT-TOKEN-HERE>","role":"my-role"}' \
       "${STARVAULT_ADDR}/v1/auth/jwt/login"

[[ttl] === TTL и аудитория

Если хотите указать пользовательский TTL или аудиторию для токенов учетных записей сервисов, в следующей спецификации pod показано монтирование тома, которое отменяет встроенный токен по умолчанию. Это особенно актуально, если не можете отключить флаг --service-account-extend-token-expiration для kube-apiserver и хотите использовать короткие TTL.

При использовании полученного токена нужно будет установить значение bound_audiences=starvault при создании ролей в StarVault в монтированном JWT-аутентификаторе.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  # automountServiceAccountToken в этом примере избыточен, потому что используемый
  # mountPath совпадает с default path. Это совпадение не даёт создаться
  # стандартному встроенному токену доступа. Вы можете использовать эту опцию,
  # чтобы быть уверенными, что только один токен будет примонтирован, если используется другой путь монтирования
  automountServiceAccountToken: false
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
      - name: custom-token
        mountPath: /var/run/secrets/kubernetes.io/serviceaccount
  volumes:
  - name: custom-token
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          path: token
          expirationSeconds: 600 # 10 minutes is the minimum TTL
          audience: starvault        # Должен совпадать с `bound_audiences` JWT роли
      # Оставшиеся sources включены, чтобы имитировать оставшиеся стандартные внедряемые тома системы
      # контроля допуска
      - configMap:
          name: kube-root-ca.crt
          items:
          - key: ca.crt
            path: ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace