Skip to content

CapabilityManifest ↔ OWASP Agentic Top 10 — Coverage Matrix

Audience: security architects, AI risk officers, procurement evaluating "agent platforms" against OWASP Agentic Applications Top 10 (2025-12) and EU AI Act / Colorado AI Act / ISO 42001 control families.

Question this doc answers: for each of the 10 OWASP risk categories, what is the runtime primitive in wasmagent-js that enforces it, and where exactly does it stop?

Posture (read this first): CapabilityManifest is not a governance product. It is the deny-all, runtime-enforced layer that a governance product calls into to actually stop a violation in flight. Microsoft's Agent Governance Toolkit (2026-04-02, MIT) decides whether an action should run; wasmagent's kernel decides whether it can — and isolates the blast radius if it does. The two layers compose; neither replaces the other.


0. The primitive itself (one-paragraph spec)

CapabilityManifest (packages/core/src/executor/types.ts) is a single object every kernel honours uniformly:

ts
interface CapabilityManifest {
  allowedHosts: string[];          // outbound HTTP allow-list (deny-all default)
  allowedReadPaths: string[];      // FS read prefixes (deny-all default)
  allowedWritePaths: string[];     // FS write prefixes (deny-all default)
  extraCapabilities: string[];     // named caps (e.g. "tool:web_search")
  env?: Readonly<Record<string, string>>;  // explicit value allow-list (NOT host pass-through)
  cpuMs?: number;                  // hard per-invocation deadline
  memoryLimitBytes?: number;       // soft per-invocation memory ceiling
}

Every absent field = an empty allow-list = nothing permitted. This is the deny-all property. The same manifest is honoured by JsKernel, QuickJSKernel, PyodideKernel, WasmtimeKernel, and RemoteSandboxKernel. Honouring matrix in types.ts.


1. Coverage matrix

For each OWASP Agentic Top 10 risk:

  • What it is (one line).
  • Primitive that enforces it (CapabilityManifest field or kernel mechanism).
  • Where the line is (what we stop and what we do not).
  • What still belongs to the consumer (governance/product layer above us).
#OWASP riskPrimitive that enforcesWhere the line is
1Goal hijacking — adversarial input rewrites the agent's objectiveOutside the kernel boundary by design. Kernel does not see the agent's planMitigation: governance layer (e.g. MS Agent Governance Toolkit) does prompt-injection detection / policy-on-paths; wasmagent's job is that even if the goal flips, the kernel still refuses unauthorised tool/network/FS calls — extraCapabilities, allowedHosts, allowedReadPaths/WritePaths all remain in force regardless of the LLM's reasoning.
2Tool misuse / unauthorised tool invocationextraCapabilities: string[] — the kernel only resolves named tools present in this allow-listA tool not listed cannot be called from inside sandboxed code, full stop. Not covered: tool selection inside the LLM's reasoning trace before the call reaches the kernel — that's the governance layer's job.
3Identity abuse / credential misuseenv?: Readonly<Record<string, string>> — explicit value allow-list, not a process.env pass-through. The kernel never sees host environmentSandboxed code sees only the values explicitly placed in env. The host's API keys, DB passwords, OAuth refresh tokens cannot leak into sandboxed execution unless the consumer explicitly puts them there. Not covered: what the consumer chooses to put in env (and whether that's appropriate per session) — see Gravitee's State of AI Agent Security 2026: only 22% of agents have independent identity. The primitive supports independent identity; using it remains a consumer choice.
4Memory poisoning — adversarial inputs persist into long-term memory and re-corrupt later runsPartial. Kernel reset() clears cross-step variables. Memory persistence (@wasmagent/memory, MemoryBlockSet) is a separate packageThe kernel guarantees no implicit cross-session state in WASM linear memory after reset(). Not covered: what MemoryAdapter writes to durable storage, and whether the consumer validates incoming memory blocks. Recommended pairing: governance-layer input validation + MemoryBlockSet size caps.
5Cascading failures / runaway loopscpuMs: number (hard deadline, lower-of with KernelOptions.timeoutMs — defence-in-depth) and memoryLimitBytes (soft ceiling, hard on QuickJS/Wasmtime/Remote, advisory on Pyodide/Js)A single kernel invocation cannot exceed cpuMs real time. Not covered: application-level retry storms — that's the consumer's orchestration layer. wasmagent's WorkflowEngine (packages/core/src/workflow/) provides resumable, terminable workflow steps that compose with this limit.
6Rogue agents — an unauthorised agent inserts itself into a multi-agent conversationOutside the kernel boundary. Mitigation belongs to the agent-id / session layerKernel does not authenticate the calling agent. We support it indirectly: RemoteSandboxKernel requires consumers to attach their own auth headers, and the a2a package's identity primitives (separate package) compose with CapabilityManifest per-session.
7Excessive agency / over-broad tool surfaceThe combination of allowedHosts (network), allowedReadPaths/allowedWritePaths (filesystem), extraCapabilities (named tools), env (secrets), cpuMs / memoryLimitBytes (resources) — each defaulting to deny-allThe blast radius of a compromised tool call is bounded by what the manifest grants. Not covered: whether the manifest itself was over-granted at construction time — that's the consumer's policy layer (and the place where a governance product's "least privilege" recommendation feeds in).
8Data exfiltrationallowedHosts: string[] — empty = network is fully offSandboxed code with allowedHosts: [] cannot DNS-resolve, cannot fetch, cannot WebSocket. WASM kernels have no socket primitive at all. Not covered: exfiltration via allowed hosts (e.g. agent uploads stolen data to the same documentation host it's allowed to read). Mitigation: keep allowedHosts to specific paths if your kernel transport supports it, plus governance-layer egress monitoring.
9Insecure tool chains — agent invokes a downstream tool that itself executes untrusted codeKernel choice + extraCapabilities namespacing. The 5 kernels ladder from "Node vm" (JsKernel) to "Wasmtime" (full WASM) to "remote" (E2B) — see docs/kernels/comparison.mdConsumer picks the isolation tier matching their threat model. Not covered: the consumer running a high-privilege tool inside a low-tier kernel — picking the right kernel for the threat is a deployment decision, not a runtime check.
10Cascading misconfigurations — a downstream agent inherits a more permissive policy than intendedCapabilityManifest is not mergeable with Object.assign. Each call to kernel.run(code, capabilities) replaces, never extends, the prior manifestA child agent never silently inherits a parent's allowedHosts. The consumer must explicitly construct a new manifest per call. Not covered: whether the consumer's orchestration layer constructs that manifest correctly — but the primitive forces them to think about it (no implicit inheritance).

2. Compared to: Microsoft Agent Governance Toolkit

The toolkit (2026-04-02, MIT) is the closest comparable open-source primitive. It is complementary, not competing:

CapabilityMS Agent Governance Toolkitwasmagent-js CapabilityManifest + kernels
OWASP Agentic Top 10 coverage10/10 (declared)7/10 directly enforced; 3/10 boundary-acknowledged (1 / 4 / 6)
Framework-neutral✅ (20+ adapters)✅ (5 kernels, framework-agnostic API)
Determinism✅ deterministic policy decisions✅ deterministic — CapabilityManifest is data, not code
p99 enforcement latency< 0.1 msdepends on kernel; typically < 1 ms (manifest check is a hashmap lookup before tool dispatch)
Provides isolation❌ — pure policy✅ — real WASM isolation (QuickJS/Pyodide/Wasmtime)
Decides "should it run?"(delegates to caller)
Decides "can it run?"(delegates to runtime)
Stops a violation in flightonly by being checked beforehand✅ — sandbox boundary halts execution

Recommended composition: governance toolkit decides should, wasmagent kernel enforces can and isolates the blast radius. A worked example is in examples/governance-toolkit-integration.md (placeholder — to be added 2026-Q3).


3. Compared to: protocol-layer authorization (MCP / A2A)

Both protocols solve authentication ("which agent is calling?") and explicitly delegate authorization ("what is this agent allowed to do?") to the implementation. See:

  • MCP specification 2026-06 (draft): authorization is "implementation-defined".
  • A2A specification (Linux Foundation, 2026-Q1): authorization scopes per agent are implementation responsibility.
  • arXiv 2601.02371 Permission Manifests for Web Agents — academic work in this exact gap.

CapabilityManifest is the implementation-side primitive that fills this gap: it is a permission manifest in the sense of the arXiv paper, but enforced at WASM boundary rather than at HTTP boundary. The mcp-server package (packages/mcp-server/) carries the manifest through MCP tool calls into kernel execution.


4. Regulatory mapping

For procurement teams evaluating against current regulation:

Regulation / StandardArticle / ControlPrimitive in wasmagent-js
EU AI Act Art. 14 (human oversight)High-risk system must allow human interventionWorkflowEngine terminable contract + cpuMs deadline (packages/core/src/workflow/)
EU AI Act Art. 15 (accuracy / cybersecurity)Robustness, resilience, securityKernel boundary (WASM) + CapabilityManifest deny-all + evals-runner paired statistical accuracy reporting
EU AI Act Annex IV (technical documentation)Document architecture, capabilities, limitationsThis document + docs/kernels/comparison.md + api-stability.md
Colorado AI Act (executable 2026-06)Algorithmic discrimination prevention, transparencyOut of CapabilityManifest scope; supported by evals-runner Pareto reports including fairness axes when configured
ISO/IEC 42001 (AI management systems)A.6.1.2 (impact assessment), A.7.4.1 (data quality), A.8.2 (lifecycle)evals-runner synthetic-fixture isolation (no train/test contamination), CI-gated reproducibility, public CHANGELOG
OWASP Agentic Top 10(above 10 entries)This document, §1

This mapping is claims about the primitives we ship, not a compliance audit. Procurement teams should pair this with their own attestation process; we are happy to participate in that process — see SECURITY.md §"Reporting and disclosure".


5. What we explicitly do NOT cover

A short, honest list. This is what a governance/product layer above us must own:

  1. Prompt-injection detection — wasmagent does not parse the agent's prompt for adversarial content. Use a governance toolkit.
  2. Decision logging / audit trail formatting — kernels emit structured events (see packages/core/src/types/events.ts); transforming those into your SIEM's audit format is your code.
  3. Multi-tenant key managementenv accepts whatever values you put in it; rotating, vaulting, and per-session scoping of those values is your platform's job.
  4. Cross-agent identitya2a provides the agent-id primitive; pairing identities to manifests is a session-layer decision.
  5. Compliance attestation — we provide architecture, threat model, and primitive documentation. We do not (and cannot) certify your system as EU AI Act compliant; that requires your full system context.

6. Verifying the claims in this document

Every "primitive" referenced in §1 is testable. The deny-all defaults are exercised by packages/core/src/executor/CapabilityManifest.test.ts (placeholder — verify path during 2026-Q3 doc audit). To reproduce the honouring matrix:

sh
git clone https://github.com/WasmAgent/wasmagent-js
cd wasmagent-js
bun install
bun run -F '@wasmagent/core' test:capability

The matrix in packages/core/src/executor/types.ts is the source of truth; this document is a derived view. If they disagree, the code wins — file an issue.


7. Changelog

  • 2026-06-17 — Initial version. Authored in response to OWASP Agentic Top 10 (2025-12) + Colorado AI Act executable date (2026-06) + EU AI Act high-risk obligations (2026-08).

Last reviewed: 2026-06-17. Next scheduled review: 2026-Q3 (post MCP 2026-06 spec + Q3 MCP/A2A interop). Open an issue if a regulatory or OWASP update lands before then.

Released under the Apache-2.0 License.