BoundBench

Mastra

TypeScript framework for AI applications and agents

github.com/mastra-ai/mastra · 2026-10-03 · 20c9a8c

Defense-in-depth score

3.0 / 10

Minimal

Mastra has a well-built human-approval gate and opt-in sandboxing, but almost none of it is on by default. Tools run without approval, the default LocalSandbox executes shell commands directly on the host, and nothing limits what an agent hijacked through a tool result can do. Deployers should enable requireToolApproval, use bubblewrap/Seatbelt or a remote sandbox, configure server auth, and add timeouts before exposing an agent to untrusted content.

Key gaps (2)

  1. The default LocalSandbox executes model-chosen shell commands directly on the host as the developer's OS user, with isolation 'none'. C4 · Code-execution isolation
  2. A hijacked agent can both leak data and take irreversible actions through any registered tool with no human involved, because approval is off by default and nothing tracks untrusted content. C5 · Untrusted input blast radius

Criteria

C1 Identity & least privilege

Minimal 0.13 / 1.00

Mastra has no agent identity of its own: tools run inside the developer's Node process and use whatever credentials that process holds, with no per-tool or per-request credential scoping. Two good narrowing measures exist: the local command sandbox and MCP stdio servers get a scrubbed environment rather than the full process environment. The bundled HTTP server relies on the developer configuring authentication, and its default access control is not locked down. A hijacked agent can do whatever the developer's integration credentials allow.

C2 Approval gates

Minimal 0.38 / 1.00

Mastra has a well-built human approval mechanism: when enabled, a tool call suspends, the exact tool name and arguments are streamed to the client, and only a decision delivered through the workflow resume boundary (not model-written data) can approve or decline it. But it is off by default: every tool's requireApproval defaults to false, the agent-wide requireToolApproval is unset, and the workspace's file-write, delete and shell tools ship with approval disabled. Nothing in the framework provides undo for actions a tool takes.

C3 Tool & action scoping

Minimal 0.35 / 1.00

Every Mastra tool built with createTool gets its input validated against its schema before it runs, and MCP tool schemas are converted so they are validated too; tools that arrive with a plain JSON schema (e.g. Vercel AI SDK tools) skip validation. The workspace filesystem tools are well scoped: paths are confined to the workspace by default with symlink-aware realpath checks. But the workspace also ships a free-form shell tool whose command string goes to the host shell, and all workspace tools are enabled by default once a workspace is attached.

C4 Code-execution isolation

Moderate 0.50 / 1.00

Agents only execute code if the developer attaches a Workspace with a sandbox, but the default sandbox, LocalSandbox, runs commands directly on the host through the system shell with isolation set to 'none'. Its environment is scrubbed to PATH plus configured variables, but the process still reaches the whole filesystem, the network, and anything else the OS user can. Opt-in isolation is solid: bubblewrap or Seatbelt confine writes to the workspace, deny network by default, and refuse to start if the backend is missing; remote sandboxes (E2B, Daytona, Modal and others) are also available. Because those are opt-in, the criterion is capped.

C5 Untrusted input blast radius

Minimal 0.15 / 1.00

Nothing in the framework structurally limits what a hijacked agent can do. Tool results, MCP results and fetched content enter the conversation the same way as any other message, and no taint tracking or Rule-of-Two enforcement disables egress or writes once untrusted content has been read. Mastra ships an optional LLM-based PromptInjectionDetector, but it only checks the incoming user messages, not tool results, and it is a classifier rather than a boundary. Because approval is off by default, an injected instruction can both leak data and take irreversible actions with no human in the loop.

C6 Memory, context & configuration integrity

Minimal 0.23 / 1.00

Memory is opt-in per agent; the default Memory configuration persists the last 10 messages of each thread and replays them in later turns, with working memory and semantic recall off. Threads are tied to a resource (user) and the agent refuses to use a thread owned by a different resource. Nothing validates what is written: when working memory is enabled the model rewrites a free-text profile that is re-injected on every turn across all of that user's threads. Memory isolation is not a strict boundary.

C7 Third-party extensions

Minimal 0.28 / 1.00

Mastra loads third-party code mainly as MCP servers that the developer lists in code: stdio servers are launched from whatever command is given (often an unpinned npx package) with no version pinning, hash check, or re-approval when tool definitions change. Stdio servers receive only the MCP SDK's curated environment plus explicitly configured variables, not the full process environment. Nothing is enabled automatically. Access control on the optional editor's stored MCP configs is not locked down.

C8 Secrets & sensitive-data protection

Minimal 0.33 / 1.00

Model and integration API keys come from environment variables and stay in the developer's process; Mastra keeps them out of subprocesses by scrubbing the LocalSandbox and MCP stdio environments. When observability is enabled, a SensitiveDataFilter that redacts fields like password, token and apiKey is applied by default to traces. Plain logs are not redacted. Anonymous usage telemetry (token counts and feature use, no prompt content) is sent to PostHog by default unless MASTRA_TELEMETRY_DISABLED is set.

C9 Audit & traceability

Minimal 0.35 / 1.00

Out of the box, Mastra installs a no-op observability layer and logs tool execution only at debug level, which the default logger does not print, so there is no record of what an agent did unless the developer configures it. With observability enabled, every tool and MCP tool call becomes a structured span with arguments, run, thread and resource IDs, nested under the agent run, and can be exported to OpenTelemetry and other backends. Approvals and declines are not recorded as their own events, and exports are best-effort.

C10 Limits & kill switch

Minimal 0.28 / 1.00

Every agent run stops after 5 model steps unless the developer sets maxSteps or a stop condition. There is no default wall-clock or token/cost limit: run and step timeouts exist but are opt-in, and the local sandbox applies a command timeout only when one is passed (its documented 30-second default is not implemented in the process manager). When delegating, the model can raise a sub-agent's step budget if that sub-agent has no configured default, and each sub-agent starts its own budget. Abort signals are passed to tools and background shell processes can be killed by process group.