---
title: Аутентификация и гранты
description: Как выпускаются агент-токены, что такое грант-пул, ловушка «токен заменяет пул» и два безопасных обхода, плюс каждая причина 401/403 с её решением.
locale: ru
version: 0.2.0
canonical: https://enterium-developer-docs.pages.dev/developers/ru/guides/authentication/
---

> Documentation index: https://enterium-developer-docs.pages.dev/developers/llms.txt — every page of this portal has a Markdown twin at <route>.md; the frozen API contract is at https://enterium-developer-docs.pages.dev/developers/api/openapi.json.

У платформы три тира доступа: полный (владелец/админ), read-only
scoped-токены и **агент-токены** — про них эта страница. Агент-токен —
это JWT с широким чтением (секреты всегда вымараны) и записью **только**
в явно выданный пул контрактов.

## Как выпускается агент-токен

Токены агентов минтит только суперпользователь (владелец) — `POST
/api/v1/auth/agent-token` отвечает всем остальным `403`. Агент не может
выпустить или продлить свой токен сам. Запрос владельца выглядит так:

```json
{
  "email": "my-agent@example.dev",
  "expires_days": 90,
  "revoke_prior": true,
  "grants": [
    { "salescontract": 12345, "capabilities": ["submit", "launch", "cancel", "edit_config"] }
  ]
}
```

- `grants` **обязателен и непуст** — токен без пула отклоняется (`400`).
- `expires_days` (1–365, по умолчанию 90) задаёт срок жизни JWT.
- `revoke_prior: true` (по умолчанию) немедленно гасит **все ранее
  выпущенные токены** этой агент-личности.

Ответ содержит `access_token` (отправляй как
`Authorization: Bearer <token>`), срок в секундах и id агента.

## Грант-пул

Права записи живут в одной таблице: строка на пару (агент, контракт) со
списком capabilities — подмножество `submit`, `launch`, `cancel`,
`edit_config`, `publish`. **Default deny**: нет строки — нет доступа, а
`publish` на прод-контрактах не выдаётся по умолчанию — его нужно
запрашивать явно. Управление задачами/дефектами — отдельная **глобальная**
capability (`manage_task`), не привязанная к контрактам.

## ⚠️ Ловушка «токен заменяет пул»

Минт токена **удаляет весь грант-пул агента и вставляет ровно то, что
перечислено в запросе**. Перевыпуск токена «чтобы добавить один контракт»
со списком из одного контракта молча срежет все остальные гранты. Два
безопасных способа расширить пул:

1. **Перечислить весь пул** в запросе: сначала получить текущие гранты,
   затем передать старые + новый вместе.
2. **Аддитивный грант без перевыпуска**: санкционированный путь — вставка
   одной новой грант-строки напрямую (операция владельца) — действующий
   токен подхватывает её сразу, всё остальное не меняется.

После любого перевыпуска агенту стоит перепроверить `my_capabilities`
до действий.

## Если не работает

| Ответ | Причина | Действие |
| --- | --- | --- |
| `401` с деталью о токене | Подпись невалидна, токен истёк или не тот тип | Запросить свежий токен у владельца |
| `401 token revoked` | Для твоей личности выпущен более новый токен с `revoke_prior: true` — твой мёртв, даже если срок не вышел | Используй новейший токен; он всегда один |
| `401 user not found or inactive` | Агент-личность деактивирована | Эскалируй владельцу |
| `403 superuser required` | Ты позвал owner-only роут (например, минт токена) | Не надо — попроси владельца |
| `403` с именем контракта/capability | Токен валиден, но запись целится в контракт вне пула или требует невыданной capability | Проверь `my_capabilities`; запроси конкретный грант |
| `403` на read-роуте | Часть read-поверхностей (например, REST-чтения доски) — team-only по дизайну | Используй MCP read-тулы — это поддерживаемый путь агента |

## Где принуждается аутентификация

Два слоя, оба активны: грубый allowlist роутов для агент-записей (агент-
токены вообще принимает лишь небольшой набор write-роутов), затем
объектная проверка в каждом хендлере — что целевой контракт в твоём пуле
с нужной capability. MCP-тулы не обходят ничего из этого: маунт MCP
требует валидный токен на **каждый** вызов, а каждый тул повторяет те же
проверки в своём теле.
