Skip to main content
Intelliger
AI Agent Authorization Engineering

AI Agent Permissions: From Scopes to Transaction Constraints

Design AI agent permissions that constrain the exact action, resource, destination, value, time and delegation path instead of relying on broad OAuth scopes.

A permission ladder narrowing access from an application scope to one constrained agent transaction
Intelliger
9 minute read · Security expert review required before publication

AI agent permissions should describe the transaction an agent may perform, not only the API it may reach. A scope such as payments:write is useful access control. It cannot express a EUR 2,000 limit, one approved supplier, a verified bank destination, a two-hour window, or a ban on further delegation. Those conditions belong in request-time authorization.

This guide is for identity, platform and application security teams extending access control to consequential agent actions. The broader AI agent authorization guide defines the full model. Here, the focus is the permission object and the tests that keep it narrow.

Use a permission ladder

Treat permission as four related layers:

LayerQuestionExample
AuthenticationWho or what presented the credential?agent:ap-worker-3
Resource accessWhich service may it reach?payments:write for api.payments.example
Delegated authorityWhat class of work was assigned?settle approved supplier invoices
Transaction constraintIs this exact request inside the assignment?supplier, destination, amount, currency and expiry match

The earlier layers do not imply the later ones. RFC 8707 can bind an OAuth request to a target resource. RFC 9700 recommends audience restriction and minimum privilege. Neither standard models an enterprise invoice, refund, purchase order or production change.

Encode constraints as data

A permission record should be typed, versioned, revocable and specific enough for deterministic evaluation.

type AgentGrant = {
  grantId: string;
  subject: string;
  audience: string;
  actions: string[];
  resources: string[];
  counterparties?: string[];
  destinations?: string[];
  limits?: {
    currency?: string;
    maxAmountMinor?: number;
    maxUses?: number;
  };
  delegation: { allowed: boolean; maxDepth: number };
  notBefore: string;
  expiresAt: string;
  policyVersion: string;
};

Absence needs one meaning. For a high-risk action, a missing destinations field should not mean every destination. Either reject the grant or define an explicit wildcard that policy forbids for that action class. Use integer minor units for money, stable identifiers for counterparties, and absolute timestamps.

At runtime, compare the normalized request with every applicable constraint. Reserve limited uses atomically. A check followed by a separate increment permits two concurrent workers to consume the same final use.

Test mutations, not only valid requests

A happy-path test proves little about the boundary. Start with one allowed fixture, mutate one field at a time, and expect a stable denial code.

MutationExpected result
amount 200000 becomes 200001AMOUNT_LIMIT_EXCEEDED
destination changesDESTINATION_NOT_ALLOWED
audience changesreject before policy evaluation
expiry is one second in the pastGRANT_EXPIRED
child grant has a later expiryDELEGATION_WIDENS_AUTHORITY
two requests consume the last useexactly one reservation succeeds

Add tests for Unicode normalization, duplicate JSON keys, unexpected fields and integer overflow. The runtime authorization pattern shows where these checks run. Exact human approval covers requests that require another decision.

Know what the record proves

A signed grant can prove what its issuer attested and whether the record changed. It cannot prove that the supplier record is accurate, that no bypass route exists, or that the protected service enforced the decision. Record the grant digest, request digest, policy version, decision and enforcement point in the AI agent audit trail.

NIST's AI Risk Management Framework treats governance, mapping, measurement and management as continuing functions. Permission review should therefore include owner changes, revocation freshness, unused grants, denial rates and evidence completeness, not just a one-time design review.

Intelliger's public OATI materials include schemas, examples and verification paths in developer preview. They do not establish that a customer production fleet has completed independent security review. Review the OATI architecture or contact Intelliger to evaluate the pattern against a specific workflow.

Questions to settle in design review

Should permissions live in tokens or in a separate grant?

Put stable resource access in short-lived tokens and transaction constraints in a separately versioned grant when those constraints change independently. A token can carry a grant identifier and digest so the enforcement point detects substitution. Embedding every counterparty, limit and usage state in the token creates oversized credentials and stale authority. Keeping everything remote also creates a live dependency. Many systems use locally verifiable grant snapshots plus fresh checks for revocation, usage and business state.

How narrow should an action name be?

Choose an action that corresponds to a domain operation with one policy meaning. write is usually too broad. supplier-payment.create and supplier-destination.propose separate value movement from a non-executable proposal. Avoid action names tied to UI buttons or model tool descriptions, which can change without the business control changing. The protected service should map the action to one idempotent adapter and reject an action-resource combination it does not recognize.

What happens when a constraint source is unavailable?

Decide per action class. If the approved-destination registry is unavailable, a payment request cannot establish a required fact and should normally stop or enter review. A low-risk public read may continue under a bounded-stale snapshot. Return a dependency-specific reason internally and record the snapshot version and age. Do not catch a lookup exception and interpret a missing list as unrestricted access.

How are cumulative limits enforced?

A per-transaction comparison is not enough for a daily or monthly budget. Reserve the proposed amount atomically against the grant and period before dispatch. Finalize, release or reconcile that reservation according to the external outcome. Define whether uncertain transactions continue to consume budget; releasing them immediately can permit another payment while the first may still settle. Test concurrent requests at the final available amount.

How should teams review existing permissions?

Start from protected domain actions and work backward to every credential and route that can reach them. Compare actual use with granted action, counterparty, destination, value and time. Remove stale grants, but also test revocation propagation. A clean administration screen does not prove an old token, queued job or child grant stopped working. Sample domain-system operations and find the decision record that permitted each one.