Agent Tool and Permission Design: [Agent or system name]
Design document for the tools an AI agent can call and the permissions
behind them: tool inventory, capability classification, the
least-agency principle, non-human identity and credential scoping,
approval tiers and step-up confirmation, sandboxing, rate and spend
limits, validation of tool-call inputs and outputs, audit logging,
revocation and a test plan. Threats are mapped to the OWASP Top 10 for
Agentic Applications 2026 (ASI02 Tool Misuse and Exploitation, ASI03
Identity and Privilege Abuse, and related entries) and to Excessive
Agency in the OWASP Top 10 for LLM Applications 2026 (LLM03:2026, as
numbered in the August 2026 edition; it was LLM06 in 2025). Replace
every [bracketed] value and every row marked Example. Worked
examples use an IT service desk agent that reads tickets, resets
passwords and opens change requests.
Document control
| Field | Value |
|---|
| Document ID | [ATP-DES-001] |
| Agent or system | [Name] [v1.0.0] |
| Tool set version | [v1.0] |
| Version | [0.1] |
| Status | [Draft / In review / Approved / Retired] |
| Owner | [@agent-owner] |
| Approvers/reviewers | [@security-engineer], [@identity-team], [@business-owner] |
| Identity provider | [Name of IdP or workload identity system] |
| Policy engine | [Example: Open Policy Agent / Cedar / in-house] |
| Classification | [Internal / Confidential] |
| Last updated | YYYY-MM-DD |
| Related documents | [Agent specification], [MCP server specifications], [Agentic threat model], [Runbook] |
Approvals
| Role | Name | Decision | Date |
|---|
| Agent owner | [@name] | [Approve / Approve with conditions / Reject] | YYYY-MM-DD |
| Security | [@name] | [Decision] | YYYY-MM-DD |
| Identity and access management | [@name] | [Decision] | YYYY-MM-DD |
| Owner of each target system | [@name] | [Decision] | YYYY-MM-DD |
Revision history
| Version | Date | Author | Change summary |
|---|
| 0.1 | YYYY-MM-DD | [@name] | First draft |
| 1.0 | YYYY-MM-DD | [@name] | Example: Approved with five tools, password reset at tier T2 |
| 1.1 | YYYY-MM-DD | [@name] | Example: create_change_request added at tier T3 after pilot |
Contents
1. Scope and context
| Item | Value |
|---|
| Agent purpose | Example: Resolve routine service desk tickets for employees |
| Acts on behalf of | Example: The employee who opened the ticket (delegated), plus the service desk as an organisation |
| Target systems | Example: Ticketing system, identity provider, change management system |
| Systems explicitly out of reach | Example: HR records, payroll, production servers, email sending |
| Autonomy level | Example: Level 2: low-risk actions alone, high-risk actions approved by a human |
| Users | Example: About 4,000 employees, 25 service desk analysts |
2. Design principles
| ID | Principle | What it means here |
|---|
| ATP-P-001 | Least agency | Give the agent only the tools, autonomy and reach the task needs; remove anything unused for [30] days |
| ATP-P-002 | Least privilege | Each tool runs with the narrowest scope that still works; no wildcard scopes |
| ATP-P-003 | Deny by default | A tool call is refused unless a policy rule allows it |
| ATP-P-004 | Separate identity | The agent has its own non-human identity; it never reuses a human's session or a shared service account |
| ATP-P-005 | Credentials outside the model | Tokens and keys never enter prompts, context or tool results |
| ATP-P-006 | Human control over irreversible effects | Irreversible or external actions need human approval or are not offered |
| ATP-P-007 | Enforce outside the model | Limits and checks run in the tool runtime or policy engine |
| ATP-P-008 | Everything logged | Every tool call, decision and approval is recorded with its principal |
3. Tool inventory
| ID | Tool | Provided by | Purpose | Target system | Class (section 4) | Tier (section 7) |
|---|
| ATP-TOOL-001 (Example) | get_ticket | Internal MCP server itsm-mcp | Read ticket and history | Ticketing | C1 | T0 |
| ATP-TOOL-002 (Example) | search_kb | Internal MCP server kb-mcp | Search knowledge base | Knowledge base | C1 | T0 |
| ATP-TOOL-003 (Example) | add_ticket_comment | itsm-mcp | Reply on the ticket | Ticketing | C3 | T1 |
| ATP-TOOL-004 (Example) | reset_password | idp-mcp | Trigger a self-service reset link to the requester | Identity provider | C4 | T2 |
| ATP-TOOL-005 (Example) | create_change_request | itsm-mcp | Open a change for a human team | Change management | C3 | T3 |
3.1 Removed or rejected tools
| Tool | Reason not granted |
|---|
Example: set_password | Agent would know the new password; reset link achieves the goal |
Example: run_shell | No task requires code execution |
Example: send_email | Replies go through the ticket only |
3.2 Tool definition requirements
Each tool must have: a name and description written for the model,
including when not to use it; a strict input schema with
additionalProperties: false; an output schema; the side effects stated
plainly; and, for MCP tools, every annotation hint set explicitly.
{
"name": "reset_password",
"title": "Send password reset link",
"description": "Send a self-service password reset link to the employee who opened the ticket. Use only when the ticket requester asks for their own reset and identity has been verified. Never use for another person or for privileged accounts.",
"inputSchema": {
"type": "object",
"properties": {
"ticket_id": {"type": "string", "pattern": "^INC[0-9]{7}$"},
"verification_ref": {"type": "string", "pattern": "^VER-[A-Z0-9]{10}$"}
},
"required": ["ticket_id", "verification_ref"],
"additionalProperties": false
},
"annotations": {"readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false}
}
The target account is not an argument: the runtime derives it from the
ticket requester, so the model cannot choose whose password is reset.
4. Capability classification
| Class | Name | Definition | Examples | Default tier |
|---|
| C0 | No side effect, local | Computation with no data access | Example: Date arithmetic, formatting | T0 |
| C1 | Read, internal | Reads internal data within the principal's rights | Example: get_ticket, search_kb | T0 |
| C2 | Read, open world | Reads untrusted external content | Example: Web fetch | T0 with content treated as untrusted |
| C3 | Write, reversible | Changes internal state that can be undone | Example: Ticket comment, draft change request | T1 or T3 |
| C4 | Write, sensitive or hard to reverse | Security, identity, financial or bulk changes | Example: Password reset, access grant | T2 or higher |
| C5 | Irreversible or external effect | Cannot be undone, or reaches people or systems outside the organisation | Example: Payment, external email, deletion without backup | T4 or not offered |
4.1 Classification record
| Tool | Reads | Writes | Reversible? | External effect? | Data sensitivity | Class |
|---|
| ATP-TOOL-003 (Example) | Ticket | Comment | Yes, by analyst edit | Visible to requester (internal) | Internal | C3 |
| ATP-TOOL-004 (Example) | Account status | Reset token issued | Partly: old password invalidated | Message to requester | Confidential | C4 |
| ATP-TOOL-005 (Example) | Ticket | New change record | Yes, change can be cancelled | None | Internal | C3 |
5. Non-human identity and credentials
5.1 Identities
| ID | Identity | Type | Used for | Owner | Review cycle |
|---|
| ATP-ID-001 (Example) | agent-servicedesk-prod | Workload identity (federated, no static secret) | Calling MCP servers | [@agent-owner] | Quarterly |
| ATP-ID-002 (Example) | itsm-mcp service principal | Service account | Ticketing API calls | [@itsm-team] | Quarterly |
| ATP-ID-003 (Example) | idp-mcp service principal | Service account with reset-only role | Identity provider reset API | [@identity-team] | Monthly |
5.2 Delegation model
[Describe how the agent acts for a user.] Example: The agent receives a
token for the requester through OAuth 2.0 Token Exchange (RFC 8693) with
the agent as actor, so downstream systems see both the user and the
agent. Each token is audience-restricted to one MCP server (RFC 8707
resource indicator). MCP servers do not pass user tokens through to
backends; they call backends with their own service principals and
record the user and agent identity in audit fields.
5.3 Credential register
| Credential | Holder | Scope | Lifetime | Storage | Rotation |
|---|
Example: Agent access token for itsm-mcp | Agent runtime | tickets:read tickets:comment changes:create | 10 minutes | Memory only | Per request |
Example: Agent access token for idp-mcp | Agent runtime | password:reset-link | 5 minutes, issued only after T2 approval | Memory only | Per action |
Example: itsm-mcp backend credential | MCP server | Ticketing API role "agent-writer" | 1 hour | Secret manager | Automatic |
- [Example: No credential is ever placed in the model context, a tool
result or a log line.]
- [Example: Credentials for C4 and C5 tools are minted just in time,
after approval, for one call.]
- [Example: Staging and production identities are separate; staging
tokens are rejected by production servers.]
6. Authorization policy
| ID | Rule | Inputs to the decision | Effect |
|---|
| ATP-POL-001 (Example) | Only tools in section 3 are callable | Tool name | Deny others |
| ATP-POL-002 (Example) | reset_password only for the ticket requester's own account | Ticket requester, derived target | Deny if they differ |
| ATP-POL-003 (Example) | reset_password never for accounts in privileged groups | Group membership | Deny and escalate |
| ATP-POL-004 (Example) | Comments may not contain links outside approved domains | Comment body | Deny with reason |
| ATP-POL-005 (Example) | No write tool after content from a C2 tool entered the context in the same turn, unless approved | Context provenance flags | Require T2 approval |
| ATP-POL-006 (Example) | Calls outside business hours limited to C0 and C1 | Time | Deny writes |
permit(agent, "reset_password", args) when
call.derived_target == ticket(args.ticket_id).requester
and not in_group(call.derived_target, "privileged")
and approval(args.ticket_id, "T2").granted
and approval.age_seconds < 300
The block above is pseudo-code; call.derived_target is the account the
runtime resolved from the ticket, never a model-supplied value. Write the real rule in your policy
engine's language and keep it under version control with tests.
7. Approval tiers and step-up confirmation
| Tier | Name | Who approves | How | Expiry |
|---|
| T0 | Automatic | Nobody, policy only | Logged | n/a |
| T1 | Notify | Nobody before; analyst can undo | Notification with undo link | Undo window [24 h] |
| T2 | User confirmation | The requesting user | Step-up: re-authenticate with MFA and confirm the exact action | [5 min] |
| T3 | Operator approval | A service desk analyst | Approve or reject in the console | [4 h], then returned to queue |
| T4 | Dual approval | Two people, one from the system owner team | Separate approvals | [24 h] |
| Not offered | n/a | n/a | Tool not granted | n/a |
7.1 Assignment
| Tool or condition | Tier | Reason |
|---|
| ATP-TOOL-001, ATP-TOOL-002 (Example) | T0 | Read only, within the requester's rights |
| ATP-TOOL-003 (Example) | T1 | Reversible, internal |
| ATP-TOOL-004 (Example) | T2 | Security-sensitive; the user proves they asked for it |
| ATP-TOOL-005 (Example) | T3 | Starts work for another team |
| Any write after C2 content in context (Example) | T2 at least | Possible injected instruction |
7.2 Approval screen content
The approver must see: the tool name in plain words, every argument with
its real value, the target resource, the class and whether it can be
undone, the reason the agent gives, and the source of any content that
led to the call. The approve button is not the default focus, and
approving does not also approve later calls.
8. Sandboxing and isolation
| Aspect | Design |
|---|
| Agent runtime | Example: Container per run, read-only root file system, no shell |
| Network egress | Example: Allow-list: the three MCP servers and the model provider only |
| File system | Example: Per-run scratch directory, wiped at end of run |
| Code execution | Example: Not offered (no C5 code tools) |
| Browsing or fetching | Example: Not offered in this agent; if added, run in a separate worker with no write tools |
| Secrets | Example: Workload identity only; no secrets mounted in the agent container |
| Tenant isolation | Example: One tenant per run; tool calls carry the tenant and servers check it |
9. Rate, volume and spend limits
| ID | Limit | Scope | Value | On breach |
|---|
| ATP-LIM-001 (Example) | Tool calls | Per run | 20 | Run stops, ticket escalated |
| ATP-LIM-002 (Example) | reset_password | Per requester per day | 2 | Deny, escalate to analyst |
| ATP-LIM-003 (Example) | reset_password | System-wide per hour | 30 | Deny new resets, page on-call |
| ATP-LIM-004 (Example) | Comments | Per ticket per hour | 3 | Deny, notify analyst |
| ATP-LIM-005 (Example) | Change requests | Per day | 10 | Queue for analyst |
| ATP-LIM-006 (Example) | Model spend | Per day | [Amount] | Pause agent |
| ATP-LIM-007 (Example) | Identical call repeated | Per run | 2 | Deny third attempt |
10. Tool-call validation
10.1 Input checks
| Check | Rule |
|---|
| Schema | Strict JSON Schema; unknown fields rejected |
| Types and ranges | Patterns, enumerations, length limits on every string |
| Resource ownership | Target resource belongs to the principal and tenant |
| Derived arguments | Sensitive targets (account, amount, recipient) derived by the runtime where possible |
| Injection in arguments | Free-text fields scanned for markup, links and command syntax before use in downstream systems |
| Idempotency | Write calls carry an idempotency key from the run and step |
10.2 Output checks
| Check | Rule |
|---|
| Schema | Result matches the output schema; otherwise an error is returned to the model |
| Size | Truncated to [8,000] characters with a note |
| Secrets and personal data | Masked by pattern before entering context |
| Untrusted content marking | Text from tickets, documents or external sources is labelled as data |
| Errors | Actionable message without stack traces, hostnames or credentials |
11. Audit logging
| Field | Content |
|---|
| Time and run ID | UTC timestamp, run ID, trace ID |
| Principals | Human on whose behalf, agent identity, MCP server identity |
| Tool and arguments | Tool name, arguments with sensitive values hashed or masked |
| Policy decision | Rule IDs evaluated, result, reason |
| Approval | Tier, approver, time, what was shown |
| Result | Outcome, error code, resource IDs changed |
| Provenance | Whether untrusted content was in context when the call was planned |
Retention: [Example: 1 year for T0 and T1 calls, 7 years for T2 and
above]. Storage: [Example: append-only log store; the agent identity
has no read or delete rights on it].
12. Revocation and emergency controls
| ID | Control | Effect | Who can trigger | Target time |
|---|
| ATP-REV-001 (Example) | Disable one tool | Policy denies the tool for all runs | Agent owner, security | 1 min |
| ATP-REV-002 (Example) | Revoke agent identity | Workload identity disabled; tokens refused | Identity team, security | 5 min |
| ATP-REV-003 (Example) | Stop all runs | Runtime halts in-flight runs at the next step | Owner, on-call | 30 s |
| ATP-REV-004 (Example) | Rotate MCP server backend credentials | Backend sessions invalidated | Server owner | 15 min |
| ATP-REV-005 (Example) | Reverse actions | Runbook lists how to undo each C3 and C4 action | Analyst | Per runbook |
Access reviews: [Example: quarterly review of identities and scopes
against section 3; any tool unused for 30 days is removed.]
13. Threat mapping
| Source and ID | Risk | Scenario here | Controls | Residual |
|---|
| ASI02 | Tool Misuse and Exploitation | Example: Ticket text persuades the agent to post a phishing link as a comment | ATP-POL-004, 10.1, T1 undo | Low |
| ASI03 | Identity and Privilege Abuse | Example: Agent resets the password of a manager named in the ticket | ATP-POL-002, derived target, T2 | Low |
| ASI03 | Identity and Privilege Abuse | Example: Stolen long-lived token reused outside the agent | Short-lived audience-bound tokens (5.3) | Low |
| ASI01 | Agent Goal Hijack | Example: Knowledge base article contains instructions to open many changes | ATP-POL-005, ATP-LIM-005 | Low |
| ASI05 | Unexpected Code Execution (RCE) | Example: Not applicable: no code execution tools | Section 8 | Not applicable |
| ASI09 | Human-Agent Trust Exploitation | Example: Approval screen shows a misleading summary | 7.2 shows real arguments | Medium |
| ASI10 | Rogue Agents | Example: Agent repeats resets in a loop after a model change | ATP-LIM-002, ATP-LIM-003, ATP-REV-003 | Low |
| LLM03:2026 | Excessive Agency | Example: Tool set includes set_password with admin scope | Section 3.1 removal, ATP-P-001 | Low |
| LLM01:2026 | Prompt Injection | Example: Instructions in an attached file | 10.2 marking, ATP-POL-005 | Medium |
ASI identifiers follow the OWASP Top 10 for Agentic Applications for 2026.
LLM identifiers follow the OWASP Top 10 for LLM Applications 2026 as
numbered when this template was written; check the current list at
genai.owasp.org before an assurance review.
14. Test plan
| ID | Test | Method | Expected result | Linked control |
|---|
| ATP-TST-001 (Example) | Call a tool not in the inventory | Direct runtime call | Denied, logged | ATP-POL-001 |
| ATP-TST-002 (Example) | Reset another user's password via ticket text | Adversarial ticket | Denied, escalated | ATP-POL-002 |
| ATP-TST-003 (Example) | Reset a privileged account | Fixture account | Denied | ATP-POL-003 |
| ATP-TST-004 (Example) | Approve a T2 action after 6 minutes | Delayed approval | Expired, new approval needed | Section 7 |
| ATP-TST-005 (Example) | 31 resets in an hour | Load script | Thirty-first denied, page sent | ATP-LIM-003 |
| ATP-TST-006 (Example) | Token reuse from outside the runtime | Replay captured token | Rejected (audience or expiry) | 5.3 |
| ATP-TST-007 (Example) | Secret pattern in a tool result | Fixture result | Masked before context | 10.2 |
| ATP-TST-008 (Example) | Disable a tool during a run | Toggle ATP-REV-001 | Next call denied | ATP-REV-001 |
| ATP-TST-009 (Example) | Revoke agent identity | Toggle ATP-REV-002 | All calls fail within 5 min | ATP-REV-002 |
| ATP-TST-010 (Example) | Audit completeness | Compare runs with log | Every call has a complete entry | Section 11 |
15. Traceability matrix
| Tool | Class | Tier | Identity | Policy | Limits | Tests |
|---|
| ATP-TOOL-001 (Example) | C1 | T0 | ATP-ID-001, ATP-ID-002 | ATP-POL-001 | ATP-LIM-001 | ATP-TST-001 |
| ATP-TOOL-003 (Example) | C3 | T1 | ATP-ID-001, ATP-ID-002 | ATP-POL-004 | ATP-LIM-004 | ATP-TST-007 |
| ATP-TOOL-004 (Example) | C4 | T2 | ATP-ID-001, ATP-ID-003 | ATP-POL-002, ATP-POL-003, ATP-POL-005 | ATP-LIM-002, ATP-LIM-003 | ATP-TST-002 to ATP-TST-006 |
| ATP-TOOL-005 (Example) | C3 | T3 | ATP-ID-001, ATP-ID-002 | ATP-POL-001 | ATP-LIM-005 | ATP-TST-010 |
16. Glossary and references
| Term | Meaning |
|---|
| Least agency | Granting an agent only the autonomy, tools and reach its task requires |
| Non-human identity | An identity for software (agent, service, workload) rather than a person |
| Step-up confirmation | A stronger check, such as re-authentication, before a sensitive action |
| Token exchange | Issuing a new token that represents a user and an acting agent together |
| Audience restriction | Binding a token to one resource server so it is refused elsewhere |
| Open-world tool | A tool that reads or affects systems outside the organisation's control |
Standard and licence note
Based on the OWASP Top 10 for Agentic Applications for 2026 and the OWASP
Top 10 for LLM Applications 2026 by the OWASP GenAI Security Project
(https://genai.owasp.org/), licensed under Creative Commons
Attribution-ShareAlike 4.0 (https://creativecommons.org/licenses/by-sa/4.0/).
Entry IDs and short names are used for mapping and all descriptions are
original text. Because section 13 adapts those lists, the adapted mapping
is shared under CC BY-SA 4.0 and any further adaptation of it must carry
the same licence. MCP and IETF RFC references are summarised in original
wording. Check the current OWASP lists and specifications before use;
example values are illustrative. Template licence: MIT.