Когда команда занимается разработкой, рано или поздно возникает необходимость в использовании хранилища типа Amazon S3 (Simple Storage Service), которое предоставляет возможность сохранения и доступа к большим объемам данных. Один из примеров такого хранилища - MinIO, который является надежным и производительным решением, особенно если он находится в High Availability.
При использовании MinIO существуют преимущества, а также некоторые нюансы, о которых можно узнать больше, прочитав эту статью. Но в это же время нам не хочется администрировать аккаунты пользователей ежесекундно, внедряя подобное решение. Поэтому сейчас мы поговорим о том, как настроить подключение OIDC к экземпляру MinIO, используя Keycloak, и избежать возможных ошибок при этом.
Keycloak (подготовка)
Будем разбираться на примере keycloak-v20.0.2.
Создадим новый клиент в реалме с нашими пользователями (чтобы лишний раз ничего не переносить)


Настраиваем `Valid redirect URIs` - `<your_domain:port>/oauth_callback`

Получаем `Client secret`, и сохраняем его в надёжное место, и переходим в minio.
MinIO
Рассмотрим на базе minio-operator-v4.5.6.
Так как S3-подобные хранилища используют PBAC, посмотрим на роли, которые по умолчанию предоставляет minio.

Давайте рассмотрим подробнее политику `readwrite` в качестве примера:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}Первым ключом является версия - она стандартна для всех политик и обычно остаётся одной и той же.
Затем следуют утверждения. Поскольку это список, их может быть неограниченное количество. Утверждения описывают, как (`Effect`), что (`Action`) и к каким ресурсам будет применено утверждение. Есть также некоторые другие поля, но мы их опустим на данный момент.
Все стандартные роли предоставляют доступ ко всем ресурсам и определённым возможностям взаимодействия с ними, поэтому они нам не подходят.
Мы хотим, чтобы каждая команда имела свои собственные бакеты. Тогда пришло время написать наши собственные политики. Вот полезная ссылка.
Actions, resources, and condition keys for Amazon S3 - таблица с правилами, которые можно использовать, но важно понимать, что не все правила aws-s3 поддерживаются в минио.
Поскольку мы хотим дать каждой команде разработки свой собственный бакет и определить управление ресурсами относительно разработчиков и команд разработки, представим, что у нас есть две команды: DS и Backend. Создадим бакет для каждой команды.

Теперь давайте подумаем о политиках. Если у нас есть два бакета, нам понадобится 3 политики.
Просмотр содержимого всех бакетов (позволим каждой команде просматривать содержимое бакетов другой команды) - возьмём стандартную политику readonly и внесём некоторые изменения.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetBucketLocation", "s3:GetObjectVersion", "s3:ListAllMyBuckets", "s3:ListBucket", "s3:GetObject" ], "Resource": [ "arn:aws:s3:::*" ] } ] }Для Backend - разрешение на публикацию объектов в их бакете.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectTagging" ], "Resource": [ "arn:aws:s3:::backend", "arn:aws:s3:::backend/*" ] } ] }Для DS - разрешение на публикацию объектов в их бакете.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectTagging" ], "Resource": [ "arn:aws:s3:::datascience", "arn:aws:s3:::datascience/*" ] } ] }
Теперь нам осталось настроить OIDC в минио следующим образом:
`Config URL` - `https://<your_keycloak_domain>/realms/<your_realm>/.well-known/openid-configuration`
`Claim Name` - это поле, по которому минио будет разбирать названия политик (обязательно должен быть список)

Keycloak
Чтобы минио мог ассоциировать данные из Keycloak с собственными политиками, создадим 3 роли в реалме Keycloak.
readonly
backend
datascience

Затем построим весь внутренний менеджмент ролей на основе групп пользователей, создадим группу `users` и две подгруппы. Распределим роли по подгруппам, оставив основную роль `readonly` в группе `users`. Затем разделим пользователей по их группам. Смысл в том, что роли каждой группы будут наследоваться.

Затем необходимо настроить наш клиент таким образом, чтобы ответ от Keycloak включал `realm-roles` для групп. Переходим на вкладку `Client scopes` -> `minio-tenant-dedicated` и выбираем готовый маппер groups.

Давайте проверим, какой ответ мы получим от Keycloak.

{
"sub": "edc4cdc3-3d88-4fb6-a0c3-1ff375330f53",
"email_verified": true,
"name": "backend backend",
"groups": [
"default-roles-dev",
"readonly",
"offline_access",
"backend",
"uma_authorization"
],
"preferred_username": "backend",
"given_name": "backend",
"family_name": "backend",
"email": "backend@backend.ru"
}Видим, что пользователь `backend backend` имеет две роли от группы, в которой состоит:
readonly
backend
Проверка аутентификации
Давайте войдем под пользователем`backend`:

Получаем, что пользователь может писать только в свой бакет.
P.S.: статья была написана раньше видео с подобным туториалом, поэтому также можно взглянуть и на тутор - https://www.youtube.com/watch?v=mv8I1wvTCrE