PermDock
Security

OWASP Top 10 for Agentic Applications

How PermDock features map to the OWASP Top 10 for Agentic Applications (December 2025), with detailed coverage of ASI02 Tool Misuse and ASI03 Identity and Privilege Abuse.

The OWASP Top 10 for Agentic Applications (December 2025) names the ways autonomous agents fail their operators. Two of its entries, ASI02 Tool Misuse and ASI03 Identity and Privilege Abuse, describe the exact problem a permissions library exists to solve, and the document's recommended controls read like a specification for permission on registerTool. This page maps PermDock features to the list so a team, or an agent auditing a team's code, can check coverage item by item.

Scope of this mapping

The names below are the official entry names, checked against the OWASP GenAI Security Project's release announcement. PermDock addresses authorization. For goal hijack, supply chain, code execution, memory poisoning and rogue agents the primary control lives elsewhere (the model host, the package manager, the sandbox, the memory store); PermDock's part there is the blast radius: what a compromised agent can still reach, and the audit trail of what it tried.

Mapping table

IDNamePermDock mitigation
ASI01Agent Goal HijackA hijacked goal still runs through the same decide: subjects come from verified credentials, never from model output; tool arguments are validated at the boundary; destructive permissions carry approval: 'human', so an injected instruction reaches a person before it reaches data. PermDock does not detect injection.
ASI02Tool Misusepermission on each tool (scope, condition, approval, limit); boundary validation of arguments; list_tools and capabilityMiddleware filtering; simulate() pre-flight; denied with alternatives; see below
ASI03Identity and Privilege AbuseTwo-principal subject (principal, actor, delegation); decision = principal grants ∩ delegation; monotonic attenuation across hops; actor in every audit event; see below
ASI04Agentic Supply Chain VulnerabilitiesA tool or MCP server added at runtime is not callable until registered with a permission, and a generated server bound through x-permdock-permissions fails closed on unknown operations. Zero runtime dependencies in core; snapshots, catalogs and hosted policy documents are data, never executed.
ASI05Unexpected Code ExecutionConditions are a JSON AST with no eval or new Function; paths never traverse __proto__, constructor or prototype; a shell or code tool is a permission like any other and can require approval per call. Sandboxing the execution is the runtime's job.
ASI06Memory and Context PoisoningDecisions read subject and context from the application, never from conversation memory, so a poisoned memory cannot grant; on('decision') and permdock/otel record what the poisoned agent attempted.
ASI07Insecure Inter-Agent CommunicationA2A extended card filtered per caller; agent-to-agent calls need a verified actor and a delegation (none is no-delegation); Web Bot Auth signatures that fail verification throw rather than becoming anonymous.
ASI08Cascading FailuresFail-closed on every error path (a thrown closure, a down PDP, a missing limit store); limit grants cap how often one agent can act; the CAEP receiver and RevocationFeed stop open connections on session-revoked; longRunning MCP tools re-check before returning a result.
ASI09Human-Agent Trust ExploitationApproval requests show the permission key, the resource identity and the bound token, not the agent's own summary; neither the actor nor the principal can approve their own request unless the grant sets distinct: false (doctor PD024), and requireDistinctApprover enforces the separation handler-wide; a batch approval is never issued.
ASI10Rogue AgentsLeast agency (guardTools, filtered tools/list), per-subject limit quotas, revocation through SSF and RevocationFeed, and an audit event naming principal and actor for every decision, so a drifting agent is bounded and visible. Detecting the drift is outside PermDock.

ASI02 Tool Misuse

OWASP asks for "per-tool least-privilege profiles (scopes, maximum rate, and egress allowlists) ... expressed as authorization policy stanzas attached to each tool", deterministic validation of tool arguments, human-in-the-loop gates for consequential actions, and "Least Agency": give the agent the minimum capability the task needs.

Authorization policy stanzas attached to each tool

That phrase is permission on registerTool. The stanza is the permission reference plus its grants in the policy:

guarded.registerTool(
  "delete_post",
  {
    permission: permissions.post.delete,
    inputSchema,
    data: (args) => loadPost(args.id),
  },
  handler,
);

const member = role("member", [
  allow(permissions.post.delete, {
    where: { authorId: principal.id },
    approval: "human",
  }),
  allow(permissions.billing.invoice.pay, { limit: { count: 10, per: "1h" } }),
]);
  • Scopes: permission.scope (post:delete) is the OAuth scope, emitted as the MCP scopeChallenge, the OpenAPI scope and the A2A securityRequirements entry.
  • Maximum rate: limit grants bound how often a subject may exercise a permission, enforced by a server-owned LimitStore. can never consumes.
  • Egress allow-lists: not a PermDock feature, and never enforced by it. A permission may carry free-form meta describing the egress a tool needs, so the catalog documents it for the runtime's network policy; PermDock defines no schema for it, because an allow-list that PermDock published but did not enforce would read as a control it is not.

Deterministic argument validation

Tool arguments are model output and therefore untrusted. validate: 'boundary' runs the resource's Standard Schema on them before any rule executes, because no agent or MCP adapter marks tool data trusted: true; failures are denied with issues, never a thrown exception that the runtime might swallow into "tool executed". See validation.

Human-in-the-loop gates

approval: 'human' on a grant produces outcome: 'approval-required', which the adapters surface as AI SDK user-approval, WorkflowAgent needsApproval, Claude Agent SDK canUseTool asking, or an MCP input_required result, always with a replay-safe token. An organisation adds its own gates as data through an ApprovalPolicySource, for example "an agent paying more than 1000 needs finance": entries apply only to the actor kinds they list, only add approval stages, and deny every allowed call when they fail to load. See approvals and approval policies as data.

Least Agency

  • capabilityMiddleware (AI SDK) and list_tools filtering (MCP) narrow the tools a model sees to those the subject may call, before the model plans.
  • simulate([[permission, data], ...]) batch-evaluates an agent's intended calls (an AuthZEN boxcar request) so a plan can be trimmed or rejected before the first side effect. It is a runtime-side pre-flight; no adapter exposes it to the model as a tool.
  • denied decisions carry alternatives: permitted permissions on the same resource, so the model picks a smaller action instead of retrying or escalating.

Audit

Every check emits on('decision') with outcome, matched grant, denials, actor and delegation; permdock/otel adds a span per check. A tool-misuse investigation can reconstruct what the agent tried, under whose authority, and why it was refused.

ASI03 Identity and Privilege Abuse

The failure is an agent operating with more authority than the human it serves, or with an identity that cannot be traced back to anyone. PermDock's answer is structural rather than procedural:

  • Two principals. createPermDock(policy, user, { actor, delegation }). The human is principal, the agent is actor, and delegation is the authority the human granted (OAuth scopes, RFC 9396 authorization_details, or an attenuated chain). Adapters fill actor and delegation from verified authInfo, never from prompt content.
  • Intersection, not union. A decision is the principal's grants intersected with the delegation. An agent with post:delete scope acting for a user who lacks post.delete is denied. An agent acting for an admin but delegated only post:read is denied everything else. "An agent can never exceed its user" is not a rule the developer writes; it is how decide works.
  • Monotonic attenuation. Delegation-chain hops can only narrow. The token layer enforces it when it issues the token; core evaluates the final delegation and carries the chain for audit (delegation).
  • No anonymous agents. An actor without delegation has no authority: every check is denied with no-delegation, and agent adapters apply no default delegation; a Web Bot Auth signature that fails verification is rejected, not downgraded.
  • Traceability. actor.id (MCP client id, CIMD URL, AI SDK agent name, signing key, A2A card) is in every decision event and in the AuthZEN subject.properties, so privilege use is attributable to a specific agent and a specific human.
  • Revocation propagates. CAEP session-revoked and credential-change events invalidate the principal's snapshots, so a compromised human session does not leave agents holding stale authority.
  • Hosted authority stays bounded. When PermDock Cloud is the directory of record, the roles it mints into tokens are limited to declared, assignable roles, and every change is a membership event naming the admin. Hosted grants apply only to permissions the code marks hostable and never drop a code approval gate. Neither path lets the Cloud, or an agent reading it, decide at request time.

Using this page in an audit

The permdock-audit skill walks a repository and reports, per ASI02 and ASI03 control: tools registered without permission, routes without protect, permissions granted with no approval on destructive actions, agent adapters constructed without actor, and decision events not consumed by any sink. permdock doctor reports the same findings from the CLI. See Agent docs standards.

Sources

Last updated on

On this page