Skip to content

Интеграция Harbor и Keycloak (OIDC)

alt text

alt text

Valid Redirect URIs: https://<harbor-domain>/c/oidc/callback

On Harbor:

OIDC Provider Name: keycloak 
OIDC Endpoint: https://keycloak-domain/realms/truedev
OIDC Client ID: harbor
OIDC Client Secret: ***
OIDC Group Filter:
Group Claim Name: groups
OIDC Admin Group: /admins
OIDC Scope: openid,profile,email,offline_access
Verify Certificate: ON
Automatic onboarding: ON
Username Claim: preferred_username

Как это работает

Если мы выйдем из учетной записи администратора (или используем приватную вкладку в браузере) и вернемся на основной URL Harbor, теперь у нас появится опция "Войти с помощью OIDC провайдера". Если мы выберем это, нас перенаправит на страницу входа в Keycloak. Здесь мы должны войти с обычной учетной записью Keycloak из области (по умолчанию master), А НЕ с нашей администраторской учетной записью Keycloak.

После этого мы будем автоматически войти в Harbor, и для нас автоматически будет создана учетная запись на основе нашего предпочитаемого имени пользователя в Keycloak.

Если мы снова войдем под учетной записью администратора и перейдем в "Администрирование" и "Группы", мы увидим, что все группы Keycloak, в которые входил пользователь, теперь были скопированы в Harbor. Это означает, что мы можем привязать определенные группы к определенным проектам, чтобы автоматически предоставлять пользователям доступ к нужным проектам. alt text

Обратите внимание, что по умолчанию все пользователи могут создавать проекты. Поскольку все пользователи Keycloak могут входить в Harbor по умолчанию, может быть предпочтительно ограничить создание проектов только для администраторов, что можно сделать, выбрав "Администрирование / Конфигурация / Настройки системы" и установив "Создание проекта" на "Только для администраторов".

В качестве примера мы можем войти в учетную запись администратора, создать закрытый проект с названием "team1", затем перейти на вкладку "Members" этого проекта и выбрать "+ Group". Затем мы можем ввести /admins в качестве имени группы и выбрать "Project Admin" в качестве роли. Любые пользователи в группе /admins Keycloak автоматически получат роль Project Admin для этого проекта.

Используем с docker

Предположим, что мы создали закрытый проект team1 и предоставили доступ к нему нашему пользователю. Теперь мы можем войти в реестр Docker с нашего локального терминала с помощью следующей команды:

docker login ВАШ_URL_РЕЕСТРА_HARBOR

Затем мы можем использовать имя пользователя нашего пользователя. Для пароля мы не должны использовать наш пароль Keycloak (это не сработает), вместо этого мы должны получить наш секрет CLI из Harbor, нажав на свое имя пользователя в правом верхнем углу, выбрав "User Profile" и скопировав CLI секрет.

Затем мы можем пометить образ для загрузки в этот репозиторий с помощью:

docker tag SOURCE_IMAGE[:TAG] harbor-domain/team1/REPOSITORY[:TAG] и загрузить его с помощью:

docker push harbor-domain/team1/REPOSITORY[:TAG]

Когда нам нужно дать доступ к репозиторию, например, серверам CI или Kubernetes, мы можем перейти на вкладку "Robot Accounts" в Harbor, чтобы сгенерировать ограниченные токены доступа для этого.

В Harbor project представляет собой реестр образов контейнеров, доступный по уникальному URL-адресу. Например, «harbor-registry.truedev.ru/team-demo/», где team-demo — это имя проекта.

Создав множество проектов, вы можете создать multi-tenant репозиторий образов контейнеров для рабочих нагрузок в вашем кластере Kubernetes. alt text

Как показано на рисунке, группа team-demo имеет роль Developer, которая ограничивает права пользователя в этом проекте. alt text

Далее мы хотим, чтобы поды из определенного namespace Kubernetes могли спулить образы контейнеров из частного реестра. Для этой цели созданы Harbor Robots. Я рекомендую создать две учетные записи роботов в каждом проекте Harbor (см. Рисунок 4). Первый — для использования Kubernetes в качестве PullSecret в заданном пространстве имен, а второй — для конвейера CI/CD.

alt text

Приложение Keycloak можно использовать в качестве Identity Provider. В Harbor пользователь может войти в систему, OIDC authentication code flow с помощью Keycloak. После успешной аутентификации пользователь перенаправляется обратно в Harbor с помощью веб-токена JSON (JWT), подписанного indentity provider (Keycloak). JWT содержит ID token.

Harbor может проверить подпись JWT и автоматически назначить пользователю роль и проект на основе groups claims из ID токена.

В следующем фрагменте кода представлен токен идентификатора с утверждением группы:

Как выглядит id token:

 {
 "iss": "https://keycloak.truedev.ru/realms/master",
 "sub": "your-sub",
 "name": "Dev Test",
 "groups": [
 "team-dev",
 "team-demo",
 ],
 "given_name": "Dev",
 "family_name": "Test",
 "email": "dev.test@truedev.ru"
}

Существует пользователь "Dev Test", принадлежащий к группам team-dev и team-demo, которого в Harbor можно сопоставить с предопределенными группами OIDC. Токен ID выдается Keycloak (свойство iss), который работает в том же кластере Kubernetes. Harbor можно настроить для использования токенов идентификатора, указав набор параметров аутентификации, представленных на рисунке 5.

Существует OIDC endpoint URL, который сопоставляется со свойством iss из ID токена. Затем OIDC Client ID с OIDC client secret используются Harbor для аутентификации клиента в Keycloak. Group claim name имеет решающее значение для enabling Harbor OIDC group matching.

Если вы хотите выполнить автоматический процесс регистрации пользователей, вам следует предоставить OIDC scopes: OpenID (iss and sub-properties) and email scope (email and email_verified properties).

Подводные камни

Реестр образов контейнеров, предоставленный Harbor, и интерфейс командной строки Docker не поддерживают протокол OIDC. Вместо этого он использует username/password-based authentication. Это означает, что всякий раз, когда вы выполняете команды Docker Login/push/pull, HTTPS-трафик от клиента Docker в реестр контейнеров не несет JWT. Обязательно исключите пути URI /v1/, /v2/ и /service/ Harbor из проверки JWT. В противном случае вы не сможете пользоваться реестром.

Кроме того, у пользователей OIDC могут возникнуть проблемы с их учетными данными Docker (секретами CLI), которые внезапно становятся недействительными. Секрет CLI зависит от действительности идентификатора токена, который не имеет ничего общего с реестром контейнеров. Это гибридное решение безопасности — это то, чего не ожидает обычный пользователь Docker, и оно может стать источником многих недоразумений.

Больше информации.

Хорошая новость заключается в том, что если ты фанат автоматизации, вам на самом деле не нужны секреты CLI. Вместо этого вы можете использовать учетные записи роботов Harbor, которые не зависят от OIDC authentication.

  • Если ваша организация решит перенести пользователей к другому Identity Provider вы можете столкнуться с ошибкой: "Conflict, the user with the same username or email has been onboarded".

Это связано с тем, что Scopes sub и/или iss из ID токена могут измениться, поэтому тот же пользователь, пытающийся войти в панель управления портом, будет рассматриваться как новый. Процесс регистрации запускается, но завершается неудачей, поскольку Harbor требует, чтобы у каждого пользователя был уникальный адрес электронной почты. В итоге я удалил существующих пользователей OIDC из Harbor и разрешил им снова подключиться. Интересно, что сообщество пользователей Harbor ведет широкую дискуссию по поводу использования протокола OIDC и до сих пор не может прийти к окончательному решению.