IAM — identity и доступ¶
iam-service — единый сервис identity платформы Taimen. Он отвечает на вопрос
«кто действует и в каком tenant», выпускает короткоживущие access token для
конкретного сервиса и публикует события identity. Раздел предназначен для
администраторов инсталляции и инженеров, подключающих новый сервис к платформе.
Что делает IAM и чего не делает¶
IAM владеет identity и credentials, но не решает, что конкретному пользователю разрешено сделать с ресурсом. Итоговое разрешение действия складывается из нескольких независимых проверок:
IAM identity (кто и в каком tenant)
AND лицензия/feature (entitlement-service, если включён)
AND организационная и доменная авторизация (resource service / policy-service)
AND транзакционные инварианты ресурса (claims, fencing и т. п.)
= разрешённое действие
| IAM владеет | IAM не владеет |
|---|---|
| Tenant и членство principal в tenant | Workspace, Project, Task, Run |
Principal видов human, agent, service_account, workload |
Namespace памяти, документы |
External identity (issuer + subject) и группы |
Продуктовые планы, лицензии, квоты |
| Platform Access Token (PAT), client credentials service account | Доменные роли и права сервисов |
| Реестр audiences и допустимых scopes | Решения «может ли P сделать A над R» |
| Федерация внешних IdP (OIDC), SCIM-провижининг | Пароли пользователей (их проверяет IdP) |
| Подпись access token и JWKS | |
| Журнал событий (outbox) и audit |
Валидный токен — не разрешение
Access token IAM подтверждает только identity, tenant и потолок
полномочий (scope). Конкретное право на ресурс сервис выводит сам:
Control Plane — через binding IAM principal к своему principal и его права
(см. Авторизация и права).
Обоснование границ — TAI-ADR-0013 (раздельные IAM и Entitlement) и
TAI-ADR-0012 (вход через токен для локальных плагинов и SCIM).
Место в архитектуре¶
flowchart LR
subgraph clients["Клиенты"]
H["Человек: MCP-плагин,<br/>CLI, Human Harness"]
A["Автономный агент<br/>(runner)"]
B["Браузер → platform-api"]
S["Сервис платформы<br/>(service account)"]
end
KC["Keycloak / внешний OIDC IdP"]
IAM["iam-service<br/>:8010"]
CP["control-plane"]
MEM["memory-service"]
OTH["другие resource services"]
H -- "PAT → :exchange" --> IAM
A -- "PAT → :exchange" --> IAM
B -- "upstream token → federation:exchange" --> IAM
S -- "client credentials → tokens/exchange" --> IAM
B -. "вход (OIDC)" .-> KC
IAM -. "discovery + JWKS" .-> KC
IAM -- "access token aud=control-plane" --> CP
IAM -- "access token aud=memory-service" --> MEM
IAM -- "access token aud=…" --> OTH
CP -. "JWKS" .-> IAM
MEM -. "JWKS" .-> IAM
OTH -. "JWKS" .-> IAM
Ключевой принцип: один токен — один сервис. Долгоживущий credential (PAT, секрет service account, upstream-токен IdP) предъявляется только IAM и обменивается на короткоживущий (по умолчанию 300 с) access token ровно одного audience. Сервис принимает токен только своего audience; токен Control Plane не принимается памятью, и наоборот.
Три пути получить access token¶
| Кто | Долгоживущий credential | Эндпоинт обмена | principal_type в токене |
|---|---|---|---|
| Человек в локальном harness (CLI, MCP-плагин) | PAT iam_pat_… |
POST /api/v1/platform-access-tokens:exchange |
human |
| Автономный агент (runner) | PAT iam_pat_… |
POST /api/v1/platform-access-tokens:exchange |
agent |
| Человек в браузере (через шлюз platform-api) | upstream OIDC token IdP | POST /api/v1/tenants/{t}/federation:exchange |
human |
| Сервис платформы | clientId + clientSecret |
POST /api/v1/tokens/exchange |
service_account |
Подробности — в статьях Credentials и PAT, Токены, audiences, scopes, Service accounts и Федерация identity.
Модель данных в двух словах¶
erDiagram
TENANT ||--o{ TENANT_MEMBERSHIP : ""
PRINCIPAL ||--o{ TENANT_MEMBERSHIP : ""
PRINCIPAL ||--o{ EXTERNAL_IDENTITY : "issuer+subject"
PRINCIPAL ||--o{ PLATFORM_ACCESS_TOKEN : "human/agent"
PRINCIPAL ||--o| SERVICE_ACCOUNT : "service_account"
PRINCIPAL ||--o{ AUTHENTICATION_CONTEXT : "human"
TENANT ||--o{ AUDIENCE : "allowedScopes"
TENANT ||--o{ IDENTITY_PROVIDER : ""
TENANT ||--o{ GROUP : ""
GROUP ||--o{ GROUP_MEMBER : ""
IDENTITY_PROVIDER ||--o{ EXTERNAL_IDENTITY : ""
- Tenant — изолированная организация. Всё, кроме самого principal, адресуется в разрезе tenant.
- Principal — субъект действия. Связан с tenant через membership.
- Audience — зарегистрированный сервис-получатель токенов со списком
допустимых scopes (
allowedScopes). - External identity — привязка principal к учётной записи внешнего IdP.
- Authentication context — зафиксированный факт свежего входа человека; без него человеку нельзя выпустить PAT.
См. Tenants и principals.
Администрирование: bootstrap-токен¶
Управляющие операции (создание tenant, principals, audiences, выпуск PAT и
т. д.) защищены общим секретом IAM_BOOTSTRAP_TOKEN, который передаётся
заголовком X-IAM-Bootstrap-Token. Отдельной административной роли в IAM нет.
curl -s -X POST "$IAM_URL/api/v1/tenants" \
-H "X-IAM-Bootstrap-Token: $IAM_BOOTSTRAP_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"slug":"acme","name":"Acme"}'
Bootstrap-токен — ключ ко всей identity
Владелец IAM_BOOTSTRAP_TOKEN может завести principal, выпустить ему PAT
и отключить любого пользователя. Храните его только в .env (0600),
не передавайте клиентам и не выставляйте административные эндпоинты
наружу без необходимости — см. Конфигурация.
Неверный или пустой заголовок даёт 401 unauthorized без пояснений.
В типовой инсталляции первичное наполнение IAM делает make bootstrap
(скрипт deploy/bootstrap.py): tenant, audiences, principal оператора,
service accounts ядра и PAT. См. Bootstrap.
Развёртывание¶
В корневом compose.yml IAM входит в профиль core:
| Контейнер | Назначение |
|---|---|
iam-db |
PostgreSQL 16, база iam |
iam-service |
API на порту 8010; при старте выполняет alembic upgrade head |
- Наружу хоста сервис публикуется только на
127.0.0.1:${IAM_HOST_PORT:-18010}. - Периметр (Caddy) отдаёт IAM по пути
/iam/*с отрезанием префикса, поэтому публичный адрес IAM —${TAIMEN_PUBLIC_URL}/iam, и он же issuer токенов. - Административные пути (
/api/v1/tenants/*, кромеfederation:*, и/api/v1/events) на периметре отвечают404, а заголовокX-IAM-Bootstrap-Tokenсрезается. Bootstrap и скрипты стенда работают через127.0.0.1:${IAM_HOST_PORT:-18010}— см. Периметр и TLS, раздел «Административная поверхность IAM». - Сервисы внутри сети compose берут ключи по внутреннему адресу
http://iam-service:8010/.well-known/jwks.json. - Ключ подписи монтируется docker-секретом
iam_signing_key(файлIAM_SIGNING_KEY_FILE).
Проверка живости:
curl -s http://127.0.0.1:18010/healthz
# {"status":"ok"}
curl -s https://platform.example.com/iam/.well-known/jwks.json
Что читать дальше¶
| Задача | Статья |
|---|---|
| Завести tenant, людей, агентов; отключить пользователя | Tenants и principals |
Выпустить, ротировать, отозвать PAT; настроить iam auth |
Credentials и PAT |
| Понять формат токена, audiences и scopes; ротировать ключ подписи | Токены, audiences, scopes |
| Дать сервису собственную identity | Service accounts |
| Подключить Keycloak или другой IdP, SCIM | Федерация identity |
| Полный список эндпоинтов | API |
| Переменные окружения и типичные ошибки конфигурации | Конфигурация |
См. также¶
- Модель безопасности
- Авторизация и права Control Plane
- Identity агента
- platform-auth-sdk — как сервисы проверяют токены IAM
- Диагностика: аутентификация и доступ