Tool permissions для AI агентів (least privilege) + Код

Коли ти даєш credentials ймовірнісній системі, потрібен least privilege. Як зробити tool permissions enforceable, auditable і зі scope.
На цій сторінці
  1. Проблема (з реального продакшену)
  2. Чому це ламається в продакшені
  3. 1) “Дамо доступ, обмежимо потім” закінчується інцидентом
  4. 2) Tools — це capabilities, а не “функції”
  5. 3) Default-allow = шлях до витоків
  6. Приклад реалізації (реальний код)
  7. Реальний інцидент (з цифрами)
  8. Компроміси
  9. Коли НЕ варто
  10. Чекліст (можна копіювати)
  11. Безпечний дефолтний конфіг (JSON/YAML)
  12. FAQ (3–5)
  13. Пов’язані сторінки (3–6 лінків)
Інтерактивний флоу
Сценарій:
Крок 1/3: Execution

Action is proposed as structured data (tool + args).

Проблема (з реального продакшену)

Агент — “просто текст”. Поки ти не дав йому tools.

Як тільки агент може викликати tools, ти побудував permission систему. Хочеш ти цього чи ні.

І неприємна правда: prompts — не permissions. “будь ласка, не роби X” — не control layer.

Чому це ламається в продакшені

1) “Дамо доступ, обмежимо потім” закінчується інцидентом

Якщо ти думаєш “guardrails додамо після того, як доведемо value” — це вступ до postmortem.

2) Tools — це capabilities, а не “функції”

db.write — це не “функція”. Це capability: вона змінює state. Side effects бувають дорогі або незворотні.

Проєктуй permissions як capability graph:

  • read vs write
  • scoped ресурси (tenant/project/user)
  • limits (rate/cost/steps)

3) Default-allow = шлях до витоків

Default-allow + один неправильний tool call і ти маєш:

  • PII у логах
  • writes у неправильне середовище
  • cross-tenant доступ

Приклад реалізації (реальний код)

Мінімальна модель:

  • capability-based allowlist
  • scope checks (tenant_id)
  • write tools опційно за approvals
PYTHON
from dataclasses import dataclass


@dataclass(frozen=True)
class ToolPermission:
  name: str
  scopes: set[str]  # e.g. {"tenant:acme"}
  mode: str = "allow"  # allow | approve


class PolicyDenied(RuntimeError):
  pass


def check_permission(perms: list[ToolPermission], *, tool: str, scope: str) -> ToolPermission:
  for p in perms:
      if p.name == tool and scope in p.scopes:
          return p
  raise PolicyDenied(f"policy_denied:{tool}:{scope}")
JAVASCRIPT
export class PolicyDenied extends Error {}

export function checkPermission(perms, { tool, scope }) {
for (const p of perms) {
  if (p.name === tool && p.scopes.includes(scope)) return p;
}
throw new PolicyDenied("policy_denied:" + tool + ":" + scope);
}

Реальний інцидент (з цифрами)

Агент мав доступ до “admin” DB wrapper’а, бо так було “зручніше”. Він мав робити triage support тікетів.

Prompt injection у тікеті змусив його виконати запит, який повернув більше даних, ніж треба.

Імпакт:

  • зовнішнього витоку не було (пощастило)
  • але PII потрапили в внутрішні логи (це все одно інцидент)
  • ~6 годин інциденту + cleanup + audit

Fix:

  1. least privilege на кожен tool (scoped creds)
  2. redaction outputs у tool gateway
  3. allowlist + approvals для writes

Компроміси

  • Permission модель коштує інженерного часу. Це дешевше, ніж час інцидентів.
  • Більше scope’ів = більше менеджменту policy.
  • Занадто жорстко може гальмувати продукт → потрібні хороші defaults і зрозуміла ескалація.

Коли НЕ варто

  • Навіть для read-only tools потрібні scopes (tenant boundaries).
  • Якщо tool не можна scope’нути (він може “все”) — виправ tool, а не policy.

Чекліст (можна копіювати)

  • [ ] Capability-based назви tools (read vs write)
  • [ ] Default-deny allowlist
  • [ ] Scoped credentials per tenant/user/project
  • [ ] Approval mode для irreversible writes
  • [ ] Output redaction (PII) + logging
  • [ ] Stop reasons: policy_denied

Безпечний дефолтний конфіг (JSON/YAML)

YAML
tool_permissions:
  default: "deny"
  grants:
    - tool: "kb.read"
      scopes: ["tenant:acme"]
      mode: "allow"
    - tool: "ticket.close"
      scopes: ["tenant:acme"]
      mode: "approve"
logging:
  redact_outputs: true

FAQ (3–5)

Чому prompt не достатній як permission?
Бо prompt не enforce. Модель може помилятись, галюцинувати або бути injected.
Scopes реально потрібні?
Так, якщо ти multi-tenant або маєш кілька середовищ. Інакше витік станеться рано чи пізно.
Як комбінувати permissions і budgets?
Permissions відповідають ‘можна?’, budgets — ‘скільки часу/скільки $?’. Потрібні обидва.
Де enforce це все?
У tool gateway. Не в UI і не в prompt.

Q: Чому prompt не достатній як permission?
A: Бо prompt не enforce. Модель може помилятись, галюцинувати або бути injected.

Q: Scopes реально потрібні?
A: Так, якщо ти multi-tenant або маєш кілька середовищ. Інакше витік станеться рано чи пізно.

Q: Як комбінувати permissions і budgets?
A: Permissions відповідають “можна?”, budgets — “скільки часу/скільки $?”. Потрібні обидва.

Q: Де enforce це все?
A: У tool gateway. Не в UI і не в prompt.

Пов’язані сторінки (3–6 лінків)

Не впевнені, що це ваш кейс?

Спроєктувати агента →
⏱️ 4 хв читанняОновлено Бер, 2026Складність: ★★★
Реалізувати в OnceOnly
Budgets + permissions you can enforce at the boundary.
Використати в OnceOnly
# onceonly guardrails (concept)
version: 1
budgets:
  max_steps: 25
  max_tool_calls: 12
  max_seconds: 60
  max_usd: 1.00
policy:
  tool_allowlist:
    - search.read
    - http.get
writes:
  require_approval: true
  idempotency: true
controls:
  kill_switch: { enabled: true }
Інтегровано: продакшен-контрольOnceOnly
Додай guardrails до агентів з tool-calling
Зашип цей патерн з governance:
  • Бюджетами (кроки / ліміти витрат)
  • Дозволами на інструменти (allowlist / blocklist)
  • Kill switch та аварійна зупинка
  • Ідемпотентність і dedupe
  • Audit logs та трасування
Інтегрована згадка: OnceOnly — контрольний шар для продакшен агент-систем.
Автор

Цю документацію курують і підтримують інженери, які запускають AI-агентів у продакшені.

Контент створено з допомогою AI, із людською редакторською відповідальністю за точність, ясність і продакшн-релевантність.

Патерни та рекомендації базуються на постмортемах, режимах відмов і операційних інцидентах у розгорнутих системах, зокрема під час розробки та експлуатації governance-інфраструктури для агентів у OnceOnly.