SafetyCard Request a review

Mastra

TypeScript framework for AI applications and agents

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

Defense-in-depth score

3.0 / 10

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.

Safest setup

Mastra ships a well-built per-call approval gate, bubblewrap and Seatbelt sandboxing, run timeouts and tracing, but almost none of it is on by default. The safest setup turns those on, keeps the process's keys narrow, and puts containment around it.

SetupHowWhat it gives you
Scoped, low-limit keysGive the process only the model and integration keys this agent needs, each scoped or read-only with a spending limit set at the providerA hijacked agent reaches only the systems and spend you chose, since every tool runs with the process's credentials C1
Server authenticationSet auth in the server config before exposing the bundled server, with mapUserToResourceId on the providerOnly signed-in users reach your agents, with memory scoped to each user C1
Per-call approvalSet requireToolApproval: true in the agent's defaultOptions, and requireApproval: true in the workspace tools configEach tool call pauses until a person approves the exact tool and arguments C2
Only the workspace tools neededSet enabled: false in the workspace tools config for each write, delete or shell tool the task doesn't useThe model sees a smaller set of tools, with write and shell access only where you chose it C3
A sandboxed shellCreate LocalSandbox with isolation: 'bwrap' on Linux or isolation: 'seatbelt' on macOSShell commands write only inside the workspace and have no network unless you allow it C4
Time and step limitsSet totalMs and stepMs under timeout in modelSettings, and a maxSteps default on every sub-agentEach run ends at a deadline you set, and sub-agents keep the step budget you gave them C10
Its own container or VMRun the Mastra process in a container or VM whose network reaches only the hosts the task needsAn outer boundary around in-process tools and MCP servers, and a narrow path for data to leave C5
Tool-call tracingPass an observability instance with an exporter to the Mastra instance, sending spans to storage you keepA structured record of every tool and MCP tool call, with run, thread and resource IDs C9

Approving with confidence

  • Read each prompt and approve calls one at a time; the prompt shows the exact tool name and arguments.
  • A per-tool or MCP server approval function decides in place of the agent-wide flag, so keep those functions as strict as the flag.

Handling data

  • Traces redact fields such as password, token and apiKey by default, but plain logs are not redacted; store logs like the data the agent read.
  • Anonymous usage telemetry is on by default; set MASTRA_TELEMETRY_DISABLED=true to turn it off.

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

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

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

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

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

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

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

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

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

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

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.