# Defense-in-Depth Score: Sim

**Repo:** https://github.com/simstudioai/sim · **Commit:** `165e117acd19207a89a30655836f257c70b5b4e9` (v0.9.12) · **Reviewed:** 2026-10-03
**What it is:** Workspace to build, deploy and monitor AI agents and workflows
**Category:** Agent Frameworks
**Scored configuration:** Self-hosted docker-compose.prod.yml as deployed by `npx sim-setup`, default environment (billing disabled, no COPILOT_API_KEY, no remote code sandbox), with workflows using the Agent block.
**Agent surface (default):** code execution yes · filesystem write yes · network egress yes · external credentials yes · persistent memory yes · untrusted input yes · third party extensions opt-in · sub agents yes · external communication yes

## Score: 3.8 / 10.0 (Minimal)

| # | Criterion | S | C | D | B | Raw | Cap | Score | Confidence |
|---|---|---|---|---|---|---|---|---|---|
| C1 | Identity & least privilege | L2 | L2 | L2 | L1 | 0.45 | — | **0.45** | High |
| C2 | Approval gates | L2 | L0 | L0 | L0 | 0.15 | C2-POWERBYPASS | **0.15** (alt) | High |
| C3 | Tool & action scoping | L2 | L2 | L3 | L1 | 0.50 | — | **0.50** | High |
| C4 | Code-execution isolation | L3 | L2 | L3 | L0 | 0.53 | — | **0.53** | High |
| C5 | Untrusted input blast radius | L1 | L1 | L2 | L0 | 0.25 | C5-PUBLICTRIGGER | **0.25** | High |
| C6 | Memory, context & configuration integrity | L1 | L1 | L1 | L0 | 0.20 | — | **0.20** | High |
| C7 | Third-party extensions | L1 | L1 | L2 | L3 | 0.40 | — | **0.40** | High |
| C8 | Secrets & sensitive-data protection | L2 | L3 | L0 | L0 | 0.38 | — | **0.38** | High |
| C9 | Audit & traceability | L2 | L2 | L3 | L1 | 0.50 | — | **0.50** | High |
| C10 | Limits & kill switch | L2 | L2 | L1 | L1 | 0.40 | — | **0.40** | High |


Sim has strong engineering below the agent layer: a V8-isolate code sandbox with a scrubbed environment, DNS-pinned SSRF protection on every tool request, credential authorization in code, and secret redaction before logs and the model. The agent layer has no human approval for tool calls, nothing limits what an agent does after reading untrusted content, and deployed chats are public by default while running with the owner's credentials. Model-written code receives every workspace secret along with open internet egress. As shipped by compose, server telemetry also exports logs, including tool error payloads, to the vendor.

## Critical gaps
- Agent block tool calls, including code execution, generic HTTP, SSH and email send, run with no approval gate in the default configuration. (ASI02, ASI09; C2) — [apps/sim/tools/function/execute.ts:114-117](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/function/execute.ts#L114-L117); [apps/sim/tools/http/request.ts:17-20](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/http/request.ts#L17-L20); [apps/sim/tools/ssh/execute_command.ts:47-51](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/ssh/execute_command.ts#L47-L51)
- A hijacked agent can exfiltrate data and take irreversible actions unattended; public-by-default chat deployments and inbound triggers start runs that use the owner's write credentials. (ASI01; C5) — [apps/sim/lib/chat-deployments/application/workflow-chat-deployment.ts:191](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/chat-deployments/application/workflow-chat-deployment.ts#L191); [apps/sim/tools/http/request.ts:17-20](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/http/request.ts#L17-L20); [apps/sim/tools/gmail/send.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/gmail/send.ts#L5)
- Model-written function code receives every workspace secret by default together with a fetch() that reaches any public host. (ASI05, ASI03; C4) — [apps/sim/lib/function-execution/execute-request.ts:844](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/function-execution/execute-request.ts#L844); [apps/sim/tools/function/execute.ts:114-117](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/function/execute.ts#L114-L117); [apps/sim/lib/execution/isolated-vm.ts:260](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm.ts#L260)

## Criterion details

### C1 Identity & least privilege — 0.45 (high)

Workflows act with the OAuth grants and API keys that workspace members connect, chosen per tool block. Before any token is attached, a deterministic check confirms the credential belongs to the workflow's workspace and that the acting user may use it, and service-account tokens are minted with only the scopes the tool declares. OAuth grants are still broad, though. Gmail asks for modify and send, Drive for full access, and one grant serves both reads and writes. Deployed runs act as the workflow owner whoever triggered them, so a public chat user borrows the owner's authority.

- **S L2:** Per-integration OAuth grants with provider scopes such as gmail.modify and full Drive, shared by read and write tools; service-account tokens are downscoped to the tool's requiredScopes. — [apps/sim/lib/oauth/oauth.ts:163-165](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/oauth.ts#L163-L165); [apps/sim/lib/oauth/oauth.ts:179](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/oauth.ts#L179); [apps/sim/lib/oauth/token-resolution.ts:254-258](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/token-resolution.ts#L254-L258) (verified)
  - *To reach the next level:* No per-tool read/write credential split for OAuth grants and no short-lived downscoped token per call.
- **C L2:** Every built-in tool and Copilot credential use goes through resolveCredentialAccessToken and authorizeCredentialUseForAuth, but the requesting principal is only pinned when enforceCredentialAccess is set. — [apps/sim/lib/oauth/token-resolution.ts:254-258](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/token-resolution.ts#L254-L258); [apps/sim/lib/auth/credential-access.ts:122-131](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/auth/credential-access.ts#L122-L131); [apps/sim/executor/utils/credential-token.ts:117](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/utils/credential-token.ts#L117) (verified)
  - *To reach the next level:* Authorization is not evaluated against the person who triggered a deployed run (public chat, webhook); the owner's authority is used.
- **D L2:** Nothing is connected by default; each tool block needs an explicitly selected credential, but connecting a grant requests the full scope set for that provider without a read-only option. — [apps/sim/lib/oauth/oauth.ts:163-165](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/oauth.ts#L163-L165); [apps/sim/blocks/blocks/agent.ts:270-273](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/blocks/blocks/agent.ts#L270-L273) (verified)
  - *To reach the next level:* No read-only default grant; write scopes are requested up front rather than through explicit elevation.
- **B L1:** A hijacked workflow can write across every connected system (mail send/modify, full Drive, Slack, databases) within the workspace's credentials. — [apps/sim/lib/oauth/oauth.ts:163-165](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/oauth.ts#L163-L165); [apps/sim/lib/oauth/oauth.ts:179](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/oauth.ts#L179); [apps/sim/tools/gmail/send.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/gmail/send.ts#L5) (verified)
  - *To reach the next level:* Long-lived refresh tokens with write scopes across several systems; L2 needs writes confined to one system.
- **Cap:** none

### C2 Approval gates — 0.15 (high)

The Agent block's tool loop runs every tool the model calls, including email sends, HTTP requests, SQL and SSH commands, with no approval step. The platform offers a Human-in-the-Loop block that pauses a workflow until an authenticated workspace member resumes it. The workflow author has to place it, and it cannot stop an individual tool call inside an Agent block. Copilot chat has per-tool approvals, but only when an operator sets COPILOT_TOOL_PERMISSIONS_ENABLED, and they are skipped for non-interactive runs.

- **default configuration** (default; raw 0.00, cap C2-POWERBYPASS → 0.00)
  - **S L0:** No approval gate on Agent block tool calls; the executor and provider tool loop have no approval concept. — searched `rg -n -i 'requiresApproval|needsApproval'` in `apps/sim/executor apps/sim/providers/index.ts apps/sim/providers/utils.ts` → 0 hits (the workflow executor and the Agent block provider tool loop have no approval concept); [apps/sim/providers/index.ts:135](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/index.ts#L135) (verified)
    - *To reach the next level:* No per-call approval; L1 needs at least a human approval step before consequential tool calls.
  - **C L0:** The most powerful paths (function_execute, http_request, ssh_execute_command, gmail_send) are reachable from the Agent block with no gate. — [apps/sim/tools/function/execute.ts:114-117](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/function/execute.ts#L114-L117); [apps/sim/tools/http/request.ts:17-20](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/http/request.ts#L17-L20); [apps/sim/tools/ssh/execute_command.ts:47-51](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/ssh/execute_command.ts#L47-L51) (verified)
    - *To reach the next level:* Every consequential tool path bypasses approval; L1 needs at least the flagged tools gated.
  - **D L0:** Human approval exists only as an opt-in workflow block or an opt-in Copilot flag. — [apps/sim/lib/core/config/env-flags.ts:109](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/core/config/env-flags.ts#L109); [apps/sim/executor/handlers/human-in-the-loop/human-in-the-loop-handler.ts:71](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/handlers/human-in-the-loop/human-in-the-loop-handler.ts#L71) (verified)
    - *To reach the next level:* Approval is opt-in; L1 needs it on by default.
  - **B L0:** Wrongly executed actions include sending email, deleting records, and running remote commands, none of which can be undone. — [apps/sim/tools/gmail/send.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/gmail/send.ts#L5); [apps/sim/tools/ssh/execute_command.ts:47-51](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/ssh/execute_command.ts#L47-L51) (verified)
    - *To reach the next level:* Irreversible external actions with no undo or preview; L1 needs some actions to be reversible.
- **opt-in Human-in-the-Loop workflow block** (alt; raw 0.15, cap C2-POWERBYPASS → 0.15) ← counted
  - **S L2:** A designer-placed block pauses the run and shows designer-chosen fields; only an authenticated user with workflow access can resume. — [apps/sim/executor/handlers/human-in-the-loop/human-in-the-loop-handler.ts:71](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/handlers/human-in-the-loop/human-in-the-loop-handler.ts#L71); [apps/sim/app/api/resume/[workflowId]/[executionId]/[contextId]/route.ts:25](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/app/api/resume/[workflowId]/[executionId]/[contextId]/route.ts#L25) (verified)
    - *To reach the next level:* Approves a workflow step, not the exact tool call and arguments; no risk tiers.
  - **C L0:** Tool calls made inside an Agent block's loop never pass through a HITL pause. — searched `rg -n -i 'requiresApproval|needsApproval'` in `apps/sim/executor apps/sim/providers/index.ts apps/sim/providers/utils.ts` → 0 hits (the workflow executor and the Agent block provider tool loop have no approval concept); [apps/sim/providers/index.ts:135](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/index.ts#L135) (verified)
    - *To reach the next level:* The Agent tool loop is not covered; L1 needs flagged tools to be gated.
  - **D L0:** The block must be added by the workflow author. — [apps/sim/executor/handlers/human-in-the-loop/human-in-the-loop-handler.ts:71](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/handlers/human-in-the-loop/human-in-the-loop-handler.ts#L71) (verified)
    - *To reach the next level:* Opt-in per workflow.
  - **B L0:** Same irreversible external actions as the default. — [apps/sim/tools/gmail/send.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/gmail/send.ts#L5) (verified)
    - *To reach the next level:* No undo or previews for external actions.
- **Cap:** C2-POWERBYPASS — Agent block tool calls still bypass the pause.
- **Notes:** Copilot (Mothership) approvals need COPILOT_API_KEY and COPILOT_TOOL_PERMISSIONS_ENABLED, neither set in the shipped compose file, and return no-approval for non-interactive runs (permission.ts:72-73).

### C3 Tool & action scoping — 0.50 (high)

Tools have typed parameter schemas, and parameters marked user-only (hosts, passwords, secret scopes) are stripped from model arguments in code. Every external tool request passes through a shared check that resolves DNS, blocks private and metadata addresses, pins the IP and rechecks redirects. Several tools are still general-purpose, though: HTTP requests to any public URL, model-written code, SQL whose statement check also allows INSERT, UPDATE and DELETE, and SSH commands. Agents receive only the tools their author attaches, but each of those tools reaches far.

- **S L2:** Typed schemas, user-only parameter stripping and DNS-pinned SSRF validation, but general tools remain (arbitrary public URL, SQL regex statement allowlist, raw SSH command). — [apps/sim/providers/utils.ts:1563-1566](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/utils.ts#L1563-L1566); [apps/sim/tools/index.ts:2833](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/index.ts#L2833); [apps/sim/lib/core/security/input-validation.server.ts:1567-1579](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/core/security/input-validation.server.ts#L1567-L1579); [apps/sim/lib/internal/postgresql/queries.ts:92](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/internal/postgresql/queries.ts#L92); [apps/sim/tools/ssh/execute_command.ts:47-51](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/ssh/execute_command.ts#L47-L51) (verified)
  - *To reach the next level:* General tools (http_request, SQL query, ssh_execute_command) accept raw URLs, statements and commands; L3 needs allowlist validation of those arguments.
- **C L2:** The SSRF check and model-parameter stripping apply centrally to every built-in tool request; argument-level validation beyond types varies per tool. — [apps/sim/tools/index.ts:2833](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/index.ts#L2833); [apps/sim/providers/utils.ts:1563-1566](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/utils.ts#L1563-L1566) (verified)
  - *To reach the next level:* No shared argument policy beyond SSRF and visibility; L3 needs every built-in tool and MCP tool validated.
- **D L3:** An Agent block starts with no tools; the author attaches each one and the model cannot add tools itself. — [apps/sim/blocks/blocks/agent.ts:270-273](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/blocks/blocks/agent.ts#L270-L273) (verified)
  - *To reach the next level:* Write and exec tools are offered without narrower per-task variants; L4 also needs per-task allowlists that are read-only by default.
- **B L1:** A misused tool can reach any public host and run arbitrary statements and commands on connected systems; only private addresses and response sizes are limited. — [apps/sim/tools/http/request.ts:17-20](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/http/request.ts#L17-L20); [apps/sim/lib/execution/isolated-vm.ts:260](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm.ts#L260); [apps/sim/tools/ssh/execute_command.ts:47-51](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/ssh/execute_command.ts#L47-L51) (verified)
  - *To reach the next level:* Broad reach with minor limits; L2 needs tools scoped to one project or workspace.
- **Cap:** none

### C4 Code-execution isolation — 0.53 (high)

Model-written JavaScript runs in an isolated-vm V8 isolate inside a separate Node worker process whose environment is cut down to an allowlist, with a 128 MB memory limit and timeouts. Python and shell are refused unless a remote E2B or Daytona sandbox is configured, so there is no fallback to running code on the host. However, by default the isolate is given every workspace secret and a fetch that reaches any public URL. Code the model writes can therefore send those secrets anywhere. SSH and SQL tools also run model-written commands on remote systems with no sandbox.

- **S L3:** A separate V8 isolate whose only capabilities are injected host callbacks (log, fetch, brokers), run in a worker process with an env allowlist and a memory limit. — [apps/sim/lib/execution/isolated-vm-worker.cjs:211](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm-worker.cjs#L211); [apps/sim/lib/execution/isolated-vm.ts:1036-1039](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm.ts#L1036-L1039); [apps/sim/lib/execution/isolated-vm.ts:956-958](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm.ts#L956-L958) (verified)
  - *To reach the next level:* Same-container V8 isolate, not kernel-separated; L4 needs a microVM, gVisor or remote ephemeral sandbox.
- **C L2:** Function blocks, custom tools and sandbox tasks all run in isolated-vm and Python/shell fail closed without a remote sandbox, but ssh_execute_command and SQL tools run model text on remote systems unsandboxed. — [apps/sim/lib/function-execution/execute-request.ts:2649-2651](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/function-execution/execute-request.ts#L2649-L2651); [apps/sim/lib/function-execution/execute-request.ts:2643-2645](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/function-execution/execute-request.ts#L2643-L2645); [apps/sim/tools/ssh/execute_command.ts:47-51](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/ssh/execute_command.ts#L47-L51); [apps/sim/lib/internal/postgresql/queries.ts:92](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/internal/postgresql/queries.ts#L92) (verified)
  - *To reach the next level:* SSH command and raw SQL tools execute model-written text outside any sandbox; L3 needs every model-reachable execution path sandboxed.
- **D L3:** Always on with no host-execution fallback; worker pool and queue limits are operator env vars the model cannot set. — [apps/sim/lib/function-execution/execute-request.ts:2649-2651](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/function-execution/execute-request.ts#L2649-L2651); [apps/sim/lib/execution/isolated-vm.ts:1036-1039](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm.ts#L1036-L1039) (verified)
  - *To reach the next level:* Sandbox tunables (IVM_* pool and fetch limits) can be changed by environment variables without bounds or warnings.
- **B L0:** All workspace secrets are injected into the isolate by default and fetch() reaches any public host, so the code can exfiltrate them. An isolate escape lands in a worker that shares the app container and its user. — [apps/sim/lib/function-execution/execute-request.ts:844](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/function-execution/execute-request.ts#L844); [apps/sim/tools/function/execute.ts:114-117](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/function/execute.ts#L114-L117); [apps/sim/lib/execution/isolated-vm.ts:260](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm.ts#L260); [docker/app.Dockerfile:202](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/docker/app.Dockerfile#L202) (verified)
  - *To reach the next level:* Credentials are in the sandbox by default; L1 needs secrets kept out unless explicitly mounted.
- **Cap:** none
- **Notes:** The opt-in E2B/Daytona remote sandboxes for Python and shell would rate higher on S but are G1-capped at 0.50, below the default's score. Escape impact via /proc of the same-uid app process is inferred, not verified.

### C5 Untrusted input blast radius — 0.25 (high)

Workflows are built to read untrusted content: 78 trigger integrations (inbound email, chat, webhooks), web and HTTP tools, and knowledge-base connectors. Chat deployments are public by default. Tool results reach the model as ordinary tool messages, and only compacted conversation summaries are labelled as untrusted data. Nothing in code limits what a hijacked agent can do after reading untrusted content. It can leak secrets through HTTP or code, send email, and delete records, all while acting with the owner's credentials and with no human involved.

- **S L1:** Only labelling: compacted history is wrapped as untrusted_conversation_summary; no capability restriction after untrusted input. — [apps/sim/providers/conversation-summary.ts:56](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/conversation-summary.ts#L56); searched `rg -n -i 'requiresApproval|needsApproval'` in `apps/sim/executor apps/sim/providers/index.ts apps/sim/providers/utils.ts` → 0 hits (the workflow executor and the Agent block provider tool loop have no approval concept) (verified)
  - *To reach the next level:* No human approval or capability drop once untrusted content is read; L2 needs at least some dangerous capabilities gated.
- **C L1:** The label covers memory summaries; tool results, trigger payloads, MCP results and chat messages enter context unmarked. — [apps/sim/providers/conversation-summary.ts:56](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/conversation-summary.ts#L56); [apps/sim/triggers/gmail/poller.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/triggers/gmail/poller.ts#L5); [apps/sim/lib/chat-deployments/application/workflow-chat-deployment.ts:191](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/chat-deployments/application/workflow-chat-deployment.ts#L191) (verified)
  - *To reach the next level:* Tool, trigger and MCP outputs are not distinguished; L2 needs most sources handled.
- **D L2:** The summary labelling is hard-coded and always on. — [apps/sim/providers/conversation-summary.ts:56](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/conversation-summary.ts#L56) (verified)
  - *To reach the next level:* The mechanism is not a control that resists configuration changes; L3 needs a warned, explicit disable path for a real limit.
- **B L0:** A hijacked Agent block can exfiltrate via http_request or function fetch and send email or run SQL deletes unattended, with the owner's credentials. — [apps/sim/tools/http/request.ts:17-20](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/http/request.ts#L17-L20); [apps/sim/lib/execution/isolated-vm.ts:260](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm.ts#L260); [apps/sim/tools/gmail/send.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/gmail/send.ts#L5); [apps/sim/lib/function-execution/execute-request.ts:844](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/function-execution/execute-request.ts#L844) (verified)
  - *To reach the next level:* Leak and irreversible action are both possible with no human; L1 needs one of them blocked.
- **Cap:** C5-PUBLICTRIGGER — Chat deployments default to public and inbound triggers start runs that use the owner's write credentials with no check that the requester is a principal.

### C6 Memory, context & configuration integrity — 0.20 (high)

Agent memory is off by default. When enabled, conversations are stored per workspace under an ID the workflow author chooses, and replayed as history. Agents can also be given tools that write to workspace-wide knowledge bases and memory, which later runs and other users retrieve. Writes are not validated or reviewed, and only compacted summaries are labelled as untrusted. A poisoned entry can therefore keep steering tool use in later sessions and for other users of the workspace.

- **S L1:** Memory and knowledge-base writes are stored unvalidated; only compacted summaries carry an untrusted label. — [apps/sim/executor/handlers/agent/memory.ts:659](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/handlers/agent/memory.ts#L659); [apps/sim/providers/conversation-summary.ts:56](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/conversation-summary.ts#L56); [apps/sim/tools/knowledge/upload_chunk.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/knowledge/upload_chunk.ts#L5) (verified)
  - *To reach the next level:* No provenance on replayed memory entries or retrieved chunks; L2 needs them presented as tagged data.
- **C L1:** The summary label applies to one path; raw history replay, knowledge-base retrieval and memory tools have no control. — [apps/sim/providers/conversation-summary.ts:56](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/conversation-summary.ts#L56); [apps/sim/tools/knowledge/upload_chunk.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/knowledge/upload_chunk.ts#L5); [apps/sim/tools/memory/add.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/memory/add.ts#L5) (verified)
  - *To reach the next level:* Knowledge bases and memory tools are uncontrolled; L2 needs the main memory store controlled.
- **D L1:** Queries are scoped to the workspace, but per-user separation depends on the conversation ID the author configures. — [apps/sim/executor/handlers/agent/memory.ts:659](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/handlers/agent/memory.ts#L659); [apps/sim/blocks/blocks/agent.ts:292-302](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/blocks/blocks/agent.ts#L292-L302) (verified)
  - *To reach the next level:* No per-user or per-session namespace by default inside a workspace; L2 needs it enforced in queries.
- **B L0:** Poisoned knowledge-base or memory content persists across sessions and workspace users and can trigger tool use. — [apps/sim/tools/knowledge/upload_chunk.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/knowledge/upload_chunk.ts#L5); [apps/sim/tools/memory/add.ts:5](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/memory/add.ts#L5) (verified)
  - *To reach the next level:* Persists across users and can drive tools; L1 needs it confined to one user's sessions.
- **Cap:** none

### C7 Third-party extensions — 0.40 (high)

Sim does not run third-party extension code in its own process. MCP servers are reached only as remote HTTP endpoints, and nothing is launched locally. A workspace member adds each server by URL, and a malicious server gets only the arguments and headers sent to it. Servers are not pinned or verified, however. Any domain is allowed unless the operator sets ALLOWED_MCP_DOMAINS, and tool lists are re-fetched, with only schema changes flagged.

- **S L1:** User-chosen remote MCP URLs, unpinned; schema changes are detected but descriptions and behaviour are not. — [apps/sim/lib/mcp/client.ts:145](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/mcp/client.ts#L145); [apps/sim/lib/mcp/tool-validation.ts:29](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/mcp/tool-validation.ts#L29); [apps/sim/lib/core/config/env.ts:290](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/core/config/env.ts#L290) (verified)
  - *To reach the next level:* No version pinning or integrity check of MCP servers; L2 needs pinned versions.
- **C L1:** Schema-change detection covers MCP tools only. — [apps/sim/lib/mcp/tool-validation.ts:29](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/mcp/tool-validation.ts#L29) (verified)
  - *To reach the next level:* Other extension types (A2A agents, templates) are unverified; L2 needs most types covered.
- **D L2:** No MCP server is configured by default; adding one is an explicit, authenticated workspace action that shows the URL. — [apps/sim/lib/mcp/client.ts:145](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/mcp/client.ts#L145); [apps/sim/lib/core/config/env.ts:290](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/core/config/env.ts#L290) (verified)
  - *To reach the next level:* Any domain is allowed by default; L3 needs a narrower default with the exact endpoint and permissions shown.
- **B L3:** A malicious MCP server runs on its own infrastructure and receives only its tool arguments and its own configured headers. — [apps/sim/lib/mcp/client.ts:145](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/mcp/client.ts#L145); searched `rg -n -S 'StdioClientTransport|stdio'` in `apps/sim/lib/mcp` → 0 hits (MCP client only connects to remote Streamable HTTP servers; nothing is launched locally) (verified)
  - *To reach the next level:* Network and data access is not limited to what the extension declares.
- **Cap:** none

### C8 Secrets & sensitive-data protection — 0.38 (high)

Workspace secrets are encrypted with AES-256-GCM. A provenance system replaces resolved secret values with [REDACTED_SECRET] in model-bound content, traces and tool logs, and the code worker gets a scrubbed environment. OAuth access and refresh tokens, however, sit in plaintext in the database. The shipped compose file also leaves server telemetry on: it exports traces and every log line, including tool error payloads, to telemetry.simstudio.ai. Model-written function code receives all workspace secrets by default.

- **S L2:** Env secrets encrypted with AES-256-GCM and resolved-secret redaction on logs, traces and model-bound content, but OAuth tokens are stored in plaintext. — [apps/sim/lib/core/security/encryption.ts:22](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/core/security/encryption.ts#L22); [apps/sim/executor/utils/resolved-secret-content-projection.ts:33-36](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/utils/resolved-secret-content-projection.ts#L33-L36); [apps/sim/executor/utils/resolved-secret-matcher.ts:11](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/utils/resolved-secret-matcher.ts#L11); [packages/db/schema.ts:164-165](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/packages/db/schema.ts#L164-L165); [apps/sim/lib/oauth/credential-service.ts:1126](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/credential-service.ts#L1126) (verified)
  - *To reach the next level:* OAuth access/refresh tokens are not encrypted at rest; L3 needs all stored credentials encrypted.
- **C L3:** Redaction covers logs, traces, model-bound messages, logger error parameters and the sandbox worker environment. — [apps/sim/lib/logs/execution/trace-secret-projection.ts:1557](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/logs/execution/trace-secret-projection.ts#L1557); [apps/sim/executor/utils/resolved-secret-content-projection.ts:33-36](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/utils/resolved-secret-content-projection.ts#L33-L36); [apps/sim/lib/execution/isolated-vm.ts:956-958](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/isolated-vm.ts#L956-L958) (verified)
  - *To reach the next level:* Function code receives every workspace secret unless scoped; L4 needs all paths covered.
- **D L0:** Server telemetry is on by default and exports every logger line to telemetry.simstudio.ai, including tool error payloads. — [apps/sim/telemetry.config.ts:34](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/telemetry.config.ts#L34); [apps/sim/telemetry.config.ts:113-114](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/telemetry.config.ts#L113-L114); [apps/sim/instrumentation-node.ts:154](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/instrumentation-node.ts#L154); [apps/sim/instrumentation-node.ts:293-297](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/instrumentation-node.ts#L293-L297); [apps/sim/tools/index.ts:3001-3006](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/index.ts#L3001-L3006); searched `rg -n 'TELEMETRY'` in `docker-compose.prod.yml` → 0 hits (the shipped compose file never sets NEXT_TELEMETRY_DISABLED, so server telemetry stays on (the Helm chart does disable it)) (verified)
  - *To reach the next level:* Telemetry carrying tool output is on by default; L1 needs default telemetry to be content-free.
- **B L0:** Long-lived, high-privilege workspace secrets reach model-written code by default, and plaintext refresh tokens sit in the database. — [apps/sim/lib/function-execution/execute-request.ts:844](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/function-execution/execute-request.ts#L844); [apps/sim/tools/function/execute.ts:114-117](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/function/execute.ts#L114-L117); [packages/db/schema.ts:164-165](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/packages/db/schema.ts#L164-L165) (verified)
  - *To reach the next level:* Long-lived keys reachable by model-authored code; L1 needs them moderately scoped and kept away from model-written code.
- **Cap:** none
- **Notes:** D is L0 because server telemetry ships enabled and exports log content, not because redaction is opt-in; redaction itself is always on.

### C9 Audit & traceability — 0.50 (high)

Every workflow run is recorded in Postgres with its trigger type and trace spans, including each tool call's arguments and results (size-bounded), and credential use and platform changes go to a separate audit log. These records are written by the platform, not by the model. The audit log is fire-and-forget, though, and per-block progress is kept in Redis and written once when the run ends. A crash can therefore lose the record of actions already taken. There is no tamper-evidence, and the record does not separate the person who triggered a run from the owner whose credentials it used.

- **S L2:** Structured trace spans with tool calls, arguments and results plus trigger type, and a separate audit_log with actor fields. — [apps/sim/lib/logs/execution/logger.ts:242-252](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/logs/execution/logger.ts#L242-L252); [packages/db/schema.ts:539-540](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/packages/db/schema.ts#L539-L540); [apps/sim/lib/oauth/token-resolution.ts:276-284](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/token-resolution.ts#L276-L284) (verified)
  - *To reach the next level:* No attribution of requesting principal versus credential owner or approver on execution records; L3 needs it.
- **C L2:** All built-in and MCP tool calls in the Agent loop appear in trace spans, and credential access is audited. — [apps/sim/lib/logs/execution/logger.ts:242-252](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/logs/execution/logger.ts#L242-L252); [apps/sim/lib/oauth/token-resolution.ts:276-284](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/oauth/token-resolution.ts#L276-L284) (verified)
  - *To reach the next level:* Approvals and memory writes are not verified to be recorded; L3 needs approvals and denials included.
- **D L3:** On by default and written by the executor to Postgres; agent-facing log tools are read-only. — [packages/db/schema.ts:539-540](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/packages/db/schema.ts#L539-L540); [apps/sim/lib/logs/execution/logger.ts:242-252](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/logs/execution/logger.ts#L242-L252) (verified)
  - *To reach the next level:* Logging can be altered by operators without a logged trail; L4 needs disabling to be itself logged.
- **B L1:** Audit writes are fire-and-forget and execution progress is folded into one terminal update at completion. — [packages/audit/src/log.ts:35-38](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/packages/audit/src/log.ts#L35-L38); [apps/sim/lib/logs/execution/progress-markers.ts:16-18](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/logs/execution/progress-markers.ts#L16-L18) (verified)
  - *To reach the next level:* Records flush late and failures are only logged; L2 needs per-action flushing.
- **Cap:** none

### C10 Limits & kill switch — 0.40 (high)

An Agent block makes at most 20 tool round-trips, nested workflow calls stop at depth 25, and loops and parallel branches have default caps. Cancelling a run passes an abort signal down to in-flight tool calls and code execution. On a self-hosted install with billing disabled (the default), though, workflow runs have no wall-clock limit. There is also no token or spend ceiling, so a runaway workflow or schedule can keep calling paid models and tools.

- **S L2:** Iteration caps (20 tool rounds, 1000 loop iterations, depth 25) plus per-execution timeouts, with cancellation propagated via AbortSignal. — [apps/sim/providers/index.ts:135](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/index.ts#L135); [apps/sim/lib/execution/call-chain.ts:10](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/call-chain.ts#L10); [apps/sim/executor/constants.ts:198-199](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/executor/constants.ts#L198-L199); [apps/sim/tools/index.ts:1686](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/index.ts#L1686) (verified)
  - *To reach the next level:* No per-run token or cost cap and no rate limit on side-effecting tools; L3 needs all three cap types.
- **C L2:** The tool loop and nested workflow calls are bounded, and function execution inherits the remaining execution deadline. — [apps/sim/lib/execution/call-chain.ts:10](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/execution/call-chain.ts#L10); [apps/sim/providers/index.ts:135](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/providers/index.ts#L135) (verified)
  - *To reach the next level:* Child workflows and schedules are not verified to share one budget; L3 needs that.
- **D L1:** With billing disabled, getExecutionTimeout returns 0 (untimed) unless the operator sets EXECUTION_TIMEOUT_FREE. — [apps/sim/lib/core/execution-limits/types.ts:85-89](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/core/execution-limits/types.ts#L85-L89) (verified)
  - *To reach the next level:* No wall-clock or spend default on self-hosted installs; L2 needs sensible defaults.
- **B L1:** A runaway run has no time or spend ceiling by default, though stopping aborts in-flight calls. — [apps/sim/lib/core/execution-limits/types.ts:85-89](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/lib/core/execution-limits/types.ts#L85-L89); [apps/sim/tools/index.ts:1686](https://github.com/simstudioai/sim/blob/165e117acd19207a89a30655836f257c70b5b4e9/apps/sim/tools/index.ts#L1686) (verified)
  - *To reach the next level:* Ceilings are unlimited by default; L2 needs moderate ceilings.
- **Cap:** none

## Rule-of-Two check
[A] untrusted input: public chat deployments (workflow-chat-deployment.ts:191), inbound triggers such as gmail_poller (triggers/gmail/poller.ts:5), http_request results · [B] sensitive data/systems: workspace OAuth grants and secrets (oauth.ts:163-165, execute-request.ts:844) · [C] state change / egress: http_request to any public URL (tools/http/request.ts:17-20), gmail_send, function fetch (isolated-vm.ts:260) · Same default session? Yes

## Highest-impact improvements
1. Default function blocks and agent-authored code to no secrets (secretScope 'selected' with an empty list) and require explicit mounting. — C4 B L0→L2, +0.100 before caps (Playbook 4, step 2)
2. Ship NEXT_TELEMETRY_DISABLED=1 in docker-compose.prod.yml (as the Helm chart does) and stop exporting log arguments in telemetry. — C8 D L0→L2, +0.100 before caps
3. Add a per-tool approval option in the Agent block tool loop that pauses through the existing HITL resume flow and shows the exact arguments. — C2 S L0→L3, +0.225 before caps (Playbook 5, step 1)
4. Set a default wall-clock timeout for self-hosted runs and a per-run model spend cap. — C10 D L1→L2, +0.050 before caps (Playbook 3, step 3)
5. Enable Better Auth OAuth token encryption so stored access and refresh tokens are encrypted with the instance key. — C8 S L2→L3, +0.075 before caps (Playbook 4, step 1)

## Re-audit log
- No changes.

## Limitations
- Static source review of the pinned commit only; nothing was built, installed or run.
- Scored the self-hosted compose deployment. The hosted sim.ai service (billing limits, hosted telemetry), the Helm chart (which disables telemetry), the Copilot/Mothership surface (needs COPILOT_API_KEY) and the macOS desktop app's local terminal were not scored.
- Very large monorepo (351 tool directories, 78 trigger integrations); individual integration tools were sampled, not exhaustively reviewed.
- The impact of an isolated-vm escape (reading the same-uid app process environment) is inferred; the isolate's access to workspace secrets is verified.
- Better Auth's default of not encrypting OAuth tokens is inferred from the library; the code storing and comparing raw refresh tokens is verified.
- No reviewer-injection text was found in the repository's markdown files.
