# Defense-in-Depth Score: AutoGen

**Repo:** https://github.com/microsoft/autogen · **Commit:** `027ecf0a379bcc1d09956d46d12d44a3ad9cee14` (autogen-agentchat 0.7.5 (no tag at commit)) · **Reviewed:** 2026-10-04
**What it is:** Microsoft's Python and .NET framework for building multi-agent LLM applications (AgentChat, Core, Extensions), now in maintenance mode.
**Category:** Agent Frameworks
**Scored configuration:** Python AgentChat/Core/Ext public constructors with default arguments (AssistantAgent, group-chat teams, CodeExecutorAgent with create_default_code_executor, Magentic-One preset).
**Agent surface (default):** code execution yes · filesystem write yes · network egress yes · external credentials yes · persistent memory opt-in · untrusted input yes · third party extensions opt-in · sub agents yes · external communication opt-in

## Score: 2.8 / 10.0 (Minimal)

| # | Criterion | S | C | D | B | Raw | Cap | Score | Confidence |
|---|---|---|---|---|---|---|---|---|---|
| C1 | Identity & least privilege | L0 | L0 | L0 | L1 | 0.05 | — | **0.05** | High |
| C2 | Approval gates | L2 | L1 | L0 | L1 | 0.28 | G1 | **0.28** (alt) | High |
| C3 | Tool & action scoping | L2 | L2 | L2 | L1 | 0.45 | — | **0.45** | High |
| C4 | Code-execution isolation | L4 | L1 | L0 | L2 | 0.47 | G1 | **0.47** (alt) | High |
| C5 | Untrusted input blast radius | L0 | L0 | L0 | L0 | 0.00 | C5-WORSTCASE | **0.00** | High |
| C6 | Memory, context & configuration integrity | L1 | L1 | L1 | L1 | 0.25 | — | **0.25** | High |
| C7 | Third-party extensions | L1 | L1 | L2 | L1 | 0.30 | — | **0.30** | High |
| C8 | Secrets & sensitive-data protection | L1 | L1 | L2 | L1 | 0.30 | — | **0.30** | High |
| C9 | Audit & traceability | L2 | L2 | L0 | L1 | 0.35 | G1 | **0.35** | High |
| C10 | Limits & kill switch | L2 | L2 | L0 | L0 | 0.30 | G1 | **0.30** | High |


AutoGen gives developers building blocks but almost no safety defaults: tool calls run as soon as the model requests them, code-execution approval is an opt-in callback, and teams have no turn or cost limit unless one is configured. Code runs in a stock Docker container with full network and a read-write workspace, falling back to the host with the full environment when Docker is missing. In the flagship Magentic-One team, a malicious web page can steer unapproved code execution and data exfiltration with no human in the loop.

## Critical gaps
- Code execution, the most powerful action, runs with no approval gate by default: approval_func defaults to None and PythonCodeExecutionTool has no hook. (ASI02, ASI09; C2) — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:441](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L441); [python/packages/autogen-ext/src/autogen_ext/tools/code_execution/_code_execution.py:83](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/code_execution/_code_execution.py#L83)
- A hijacked Magentic-One team can read local files (FileSurfer at cwd, WebSurfer file://), exfiltrate over the open web and run unapproved code, all unattended. (ASI01, LLM01; C5) — [python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py:655](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py#L655); [python/packages/autogen-ext/src/autogen_ext/teams/magentic_one.py:210-217](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/teams/magentic_one.py#L210-L217); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:681](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L681)

## Criterion details

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

AutoGen has no identity or authorization layer of its own: every tool, code executor and MCP server runs with whatever authority the host Python process has, and nothing checks a request against the person who asked for it. The host-process code executor copies the full process environment, including model API keys, into every script it runs. The Docker executor does not pass the environment, which keeps host credentials out of the default sandbox, but nothing scopes the credentials developers hand to tools. The optional distributed gRPC runtime listens on an unauthenticated, unencrypted port.

- **S L0:** Tools and executors run with the host process's ambient authority; the framework has no notion of an agent identity or scoped credential. — [python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py:397](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py#L397); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:1600](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L1600) (verified)
  - *To reach the next level:* No dedicated or role-scoped identity for agents or tools.
- **C L0:** No authorization check exists on any tool path; the local executor hands the full os.environ to model-written code. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:1600](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L1600); [python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py:397](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py#L397); [python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host.py:24](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host.py#L24) (verified)
  - *To reach the next level:* No authorization check on even the main tool path.
- **D L0:** Default constructors give agents the full privilege of the launching process; narrowing it is left entirely to the developer. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:729](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L729); [python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py:397](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py#L397) (verified)
  - *To reach the next level:* No narrower default role or credential scope.
- **B L1:** Nothing in the framework bounds what tool credentials can do, but the Docker executor (preferred default) does not mount home directories or pass the environment, so host credential files stay out of model-run code unless Docker is missing. — [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:538-546](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L538-L546); [python/packages/autogen-ext/src/autogen_ext/code_executors/__init__.py:64-80](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/__init__.py#L64-L80) (verified)
  - *To reach the next level:* No restriction keeping a hijacked agent to one system or to non-destructive writes.
- **Cap:** none

### C2 Approval gates — 0.28 (high)

Ordinary tool calls made by AssistantAgent, including MCP tools and the Python code-execution tool, run as soon as the model asks for them; there is no approval hook on that path. CodeExecutorAgent offers an optional approval callback that sees the exact code and can reject it, and it warns when none is set, but it is off by default and covers only that one agent. The Magentic-One team runs code without approval unless the developer supplies the callback, and the docs show using another LLM as the approver.

- **default configuration** (default; raw 0.05, cap C2-POWERBYPASS → 0.05)
  - **S L0:** The default tool path has no approval step at all. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:1600](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L1600); searched `rg -n 'requires_approval|needs_approval|confirm'` in `python/packages/autogen-core/src/autogen_core/tools python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py` → 0 hits (No approval flag or confirmation hook on the generic tool path.) (verified)
    - *To reach the next level:* No per-call approval on the tool path.
  - **C L0:** Code execution through PythonCodeExecutionTool and through CodeExecutorAgent without a callback both run ungated. — [python/packages/autogen-ext/src/autogen_ext/tools/code_execution/_code_execution.py:83](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/code_execution/_code_execution.py#L83); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:691](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L691) (verified)
    - *To reach the next level:* The most powerful path (code execution) is exempt.
  - **D L0:** approval_func defaults to None; only a UserWarning is emitted. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:441](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L441) (verified)
    - *To reach the next level:* Approval is opt-in.
  - **B L1:** Model-written code can delete or overwrite workspace files and make network calls with no checkpoint or undo; the Docker container is discarded after use but the mounted workspace is not. — [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:538-546](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L538-L546) (verified)
    - *To reach the next level:* No checkpoint or rollback for workspace state.
- **opt-in CodeExecutorAgent approval_func** (alt; raw 0.28, cap G1 → 0.28) ← counted
  - **S L2:** When set, the callback receives the exact code blocks, a denial is returned as a first-class result, and the approved code_blocks object is what executes, but the framework has no risk tiers and leaves every decision (including an LLM approver, as the docs show) to developer code. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:699](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L699); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:711-715](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L711-L715); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:718](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L718) (verified)
    - *To reach the next level:* No built-in risk tiers deciding which calls need a human.
  - **C L1:** Only CodeExecutorAgent consults the callback; AssistantAgent tools, MCP tools and PythonCodeExecutionTool bypass it. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:691](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L691); [python/packages/autogen-ext/src/autogen_ext/tools/code_execution/_code_execution.py:83](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/code_execution/_code_execution.py#L83); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:1600](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L1600) (verified)
    - *To reach the next level:* Tool calls, MCP tools and the code-execution tool do not traverse the gate.
  - **D L0:** The callback is opt-in and cannot be serialized, so agents loaded from config never have it. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:441](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L441); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:779](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L779) (verified)
    - *To reach the next level:* Approval is opt-in.
  - **B L1:** Same as default: no checkpoint or rollback of workspace state. — [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:538-546](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L538-L546) (verified)
    - *To reach the next level:* No checkpoint or rollback for workspace state.
- **Cap:** G1 — Opt-in mechanism: off in the scored default configuration.

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

Every function tool validates its arguments against a typed Pydantic schema before running, which catches malformed calls but is not an allowlist. A few bundled tools add real scoping (the file surfer confines paths with realpath containment), while others are wide open: the web surfer visits any URL including file:// and internal addresses, the HTTP tool formats model input straight into the path, and the code-execution tool takes arbitrary code. MCP tool arguments are forwarded without local validation. AssistantAgent starts with no tools, but the official Magentic-One preset enables web, file and code execution together.

- **S L2:** Pydantic schema validation on every BaseTool, with realpath containment in the file surfer, but the web surfer accepts file:// and any host and the code tool takes raw code. — [python/packages/autogen-core/src/autogen_core/tools/_base.py:198](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/tools/_base.py#L198); [python/packages/autogen-ext/src/autogen_ext/agents/file_surfer/_markdown_file_browser.py:79-83](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/agents/file_surfer/_markdown_file_browser.py#L79-L83); [python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py:655](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py#L655); [python/packages/autogen-ext/src/autogen_ext/tools/http/_http_tool.py:216](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/http/_http_tool.py#L216) (verified)
  - *To reach the next level:* No URL/host allowlist or internal-address blocking; general tools are not replaced by narrow ones.
- **C L2:** All BaseTool subclasses go through model_validate, but MCP tools forward arguments to the server without a local validation layer. — [python/packages/autogen-core/src/autogen_core/tools/_base.py:198](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/tools/_base.py#L198); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:1600](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L1600) (verified)
  - *To reach the next level:* Extension (MCP) tools are not wrapped by the shared validation layer.
- **D L2:** AssistantAgent defaults to no tools, but the flagship Magentic-One preset enables web browsing, local file reading and code execution together. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:729](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L729); [python/packages/autogen-ext/src/autogen_ext/teams/magentic_one.py:210-217](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/teams/magentic_one.py#L210-L217) (verified)
  - *To reach the next level:* Official presets ship write/exec/network tools enabled; default lowered one level per the framework rule.
- **B L1:** A misused tool can execute arbitrary code with full network access or browse arbitrary URLs and local files. — [python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py:655](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py#L655); [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:538-546](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L538-L546) (verified)
  - *To reach the next level:* No quantity bounds or narrow scoping on the general-purpose tools.
- **Cap:** none

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

Model-written code runs either on the host (LocalCommandLineCodeExecutor, which copies the full environment, API keys included) or in a stock Docker container that runs as root with default capabilities, full network and the workspace mounted read-write. The helper used by Magentic-One prefers Docker but quietly falls back to the host executor, with only a Python warning, when Docker is missing. An experimental Azure Container Apps executor offers a stronger remote sandbox but must be chosen explicitly. MCP stdio servers always run on the host.

- **default configuration** (default; raw 0.42 → 0.42)
  - **S L2:** The preferred default is a stock python:3-slim container with no user, capability, seccomp or read-only settings. — [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:160](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L160); [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:538-546](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L538-L546) (verified)
    - *To reach the next level:* No non-root user, dropped capabilities, seccomp or network denial.
  - **C L1:** Code executors are containerized but MCP stdio servers launched by the framework run on the host. — [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:538-546](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L538-L546); [python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py:23](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py#L23) (verified)
    - *To reach the next level:* MCP stdio servers and other spawned processes are not sandboxed.
  - **D L2:** create_default_code_executor falls back to host execution with only a UserWarning when Docker is unavailable or fails to start. — [python/packages/autogen-ext/src/autogen_ext/code_executors/__init__.py:64-80](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/__init__.py#L64-L80); [python/packages/autogen-ext/src/autogen_ext/teams/magentic_one.py:209](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/teams/magentic_one.py#L209) (verified)
    - *To reach the next level:* Silent fallback to host execution instead of failing closed.
  - **B L2:** Inside the container the workspace is mounted read-write with unrestricted network; the environment is not passed in and auto_remove destroys the container. — [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:538-546](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L538-L546) (verified)
    - *To reach the next level:* Network egress is not off or allowlisted and no CPU/memory/PID limits are set.
- **opt-in ACADynamicSessionsCodeExecutor (Azure remote sandbox)** (alt; raw 0.47, cap G1 → 0.47) ← counted
  - **S L4:** Code is sent to a remote Azure Container Apps dynamic session rather than run locally. — [python/packages/autogen-ext/src/autogen_ext/code_executors/azure/_azure_container_code_executor.py:60](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/azure/_azure_container_code_executor.py#L60); [python/packages/autogen-ext/src/autogen_ext/code_executors/azure/_azure_container_code_executor.py:146](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/azure/_azure_container_code_executor.py#L146) (verified)
  - **C L1:** Covers the code-execution path only; MCP stdio servers still run on the host. — [python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py:23](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py#L23) (verified)
    - *To reach the next level:* MCP stdio servers and other spawned processes are not sandboxed.
  - **D L0:** Must be constructed explicitly with an Azure endpoint and credential; it is marked experimental. — [python/packages/autogen-ext/src/autogen_ext/code_executors/azure/_azure_container_code_executor.py:47-48](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/azure/_azure_container_code_executor.py#L47-L48) (verified)
    - *To reach the next level:* The remote sandbox is opt-in.
  - **B L2:** No host filesystem is reachable; sessions persist per session id rather than per call and egress is governed by the Azure pool, not AutoGen. — [python/packages/autogen-ext/src/autogen_ext/code_executors/azure/_azure_container_code_executor.py:146](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/azure/_azure_container_code_executor.py#L146) (verified)
    - *To reach the next level:* Sessions are not ephemeral per call and AutoGen does not restrict egress.
- **Cap:** G1 — Opt-in mechanism: off in the scored default configuration.

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

Nothing in AutoGen limits what a hijacked agent can do after reading untrusted content. Tool results, web pages and other agents' messages enter the conversation with the same standing as the user's instructions, and CodeExecutorAgent by default executes code blocks from any participant's message. In the documented Magentic-One team, a web page the browser agent reads can steer the coder into writing code that runs without approval and with full network access, and the browser itself can open file:// URLs and send data to any site. Leaking data and taking destructive action can both happen with no human involved.

- **S L0:** No taint tracking, provenance or capability restriction once untrusted content is read. — searched `rg -n -i 'untrusted|prompt.injection|taint'` in `python/packages/autogen-agentchat/src/autogen_agentchat python/packages/autogen-core/src/autogen_core` → 0 hits (No provenance or taint handling for tool results or other agents' messages.); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:681](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L681) (verified)
  - *To reach the next level:* No human approval tied to untrusted content entering the session.
- **C L0:** Untrusted sources are not distinguished; code is extracted from any message source by default. — [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:681](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L681); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:1600](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L1600) (verified)
  - *To reach the next level:* Untrusted sources are not distinguished from principal input.
- **D L0:** No control exists to be on by default. — searched `rg -n -i 'untrusted|prompt.injection|taint'` in `python/packages/autogen-agentchat/src/autogen_agentchat python/packages/autogen-core/src/autogen_core` → 0 hits (No provenance or taint handling for tool results or other agents' messages.) (verified)
  - *To reach the next level:* No control is on by default.
- **B L0:** Web content, local file access (file:// and FileSurfer at cwd), unrestricted egress and unapproved code execution coexist in the Magentic-One preset. — [python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py:655](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py#L655); [python/packages/autogen-ext/src/autogen_ext/agents/file_surfer/_file_surfer.py:79](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/agents/file_surfer/_file_surfer.py#L79); [python/packages/autogen-ext/src/autogen_ext/teams/magentic_one.py:210-217](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/teams/magentic_one.py#L210-L217); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:441](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L441) (verified)
  - *To reach the next level:* Exfiltration and irreversible actions are not gated by a human.
- **Cap:** C5-WORSTCASE — B is L0: a hijacked default Magentic-One team can both exfiltrate data and run destructive code unattended.

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

Memory is opt-in and the framework never writes to it on the model's behalf, but anything a developer stores is re-injected as a system message with no provenance marking, so poisoned memory carries system-level weight in every later run. Persistent stores such as ChromaDB default to one shared collection with no per-user namespace. AutoGen does not auto-load instruction or settings files from the working directory, and component configs are only loaded when the developer calls load_component.

- **S L1:** Memory contents are added to the model context as a SystemMessage with no validation or provenance. — [python/packages/autogen-core/src/autogen_core/memory/_list_memory.py:127](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/memory/_list_memory.py#L127) (verified)
  - *To reach the next level:* Memory entries are not presented as data with provenance.
- **C L1:** No memory store applies validation or provenance; the same injection pattern is used by the memory implementations. — [python/packages/autogen-core/src/autogen_core/memory/_list_memory.py:127](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/memory/_list_memory.py#L127); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:744](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L744) (verified)
  - *To reach the next level:* Not even the main memory store controls what is re-injected.
- **D L1:** ListMemory is per-instance, but the ChromaDB store defaults to a single shared collection; per-user separation is left to developer filters. — [python/packages/autogen-ext/src/autogen_ext/memory/chromadb/_chroma_configs.py:111](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/memory/chromadb/_chroma_configs.py#L111) (verified)
  - *To reach the next level:* No per-user or per-session namespace enforced by default in persistent stores.
- **B L1:** Persistent memory survives across sessions and, as system-level context, can steer later tool use. — [python/packages/autogen-core/src/autogen_core/memory/_list_memory.py:127](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/memory/_list_memory.py#L127); [python/packages/autogen-ext/src/autogen_ext/memory/chromadb/_chroma_configs.py:111](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/memory/chromadb/_chroma_configs.py#L111) (verified)
  - *To reach the next level:* Poisoned memory is not limited to text output or gated actions.
- **Cap:** none

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

Developers add MCP servers explicitly in code, which avoids silent installs, but AutoGen launches whatever command it is given with no pinning, integrity check or detection of changed tool definitions. Component configs can only name provider classes from AutoGen's own namespaces, a useful allowlist, but it can be widened by an environment variable and its enforcement does not cover every path, and a FunctionTool config runs arbitrary embedded Python via exec. The Docker executor pulls the unpinned python:3-slim image. MCP stdio servers run on the host as the same user; in-process adapters such as LangChain tools share the agent's process.

- **S L1:** MCP servers are user-chosen and unpinned; tool lists are re-fetched on each call with no change detection. — [python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py:23](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py#L23); [python/packages/autogen-ext/src/autogen_ext/tools/mcp/_workbench.py:274](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/mcp/_workbench.py#L274); searched `rg -n -i 'sha256|checksum|digest|verify_signature'` in `python/packages/autogen-ext/src/autogen_ext/tools/mcp` → 0 hits (No integrity or change detection for MCP servers or tool definitions.); [python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:160](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py#L160) (verified)
  - *To reach the next level:* No version pinning or integrity verification of extensions.
- **C L1:** Only component-config providers are restricted, by a namespace allowlist with an env override whose enforcement does not cover every path; MCP servers are not verified. — [python/packages/autogen-core/src/autogen_core/_component_config.py:256-270](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_component_config.py#L256-L270); [python/packages/autogen-core/src/autogen_core/_component_config.py:75](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_component_config.py#L75) (verified)
  - *To reach the next level:* MCP servers and downloaded images are not covered by any verification.
- **D L2:** No extension is enabled by default; adding an MCP server or loading a FunctionTool config is an explicit developer action, with a warning for config-embedded code. — [python/packages/autogen-core/src/autogen_core/tools/_function_tool.py:147](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/tools/_function_tool.py#L147); [python/packages/autogen-core/src/autogen_core/tools/_function_tool.py:171](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/tools/_function_tool.py#L171) (verified)
  - *To reach the next level:* Adding an extension does not show the exact package and permissions it will use.
- **B L1:** MCP stdio servers run as separate processes under the same user on the host; FunctionTool configs and LangChain adapters run in-process. — [python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py:23](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py#L23); [python/packages/autogen-core/src/autogen_core/tools/_function_tool.py:171](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/tools/_function_tool.py#L171) (verified)
  - *To reach the next level:* Extensions are not separated with a scrubbed environment and scoped credentials.
- **Cap:** none

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

Model API keys come from environment variables and are typed as SecretStr in config models, which keeps them out of reprs and serialized configs. There is no redaction anywhere else: when event logging is enabled, every LLM call is logged with the full prompt and response, and the host-process code executor gives model-written code a copy of the full environment. AutoGen sends no telemetry of its own; tracing is OpenTelemetry and is a no-op unless the developer configures a provider.

- **S L1:** API keys are SecretStr in config models but there are no log filters or redaction helpers. — [python/packages/autogen-ext/src/autogen_ext/models/openai/config/__init__.py:115](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/openai/config/__init__.py#L115); searched `rg -n -i 'redact|mask_secret|scrub'` in `python/packages/autogen-agentchat/src/autogen_agentchat python/packages/autogen-core/src/autogen_core python/packages/autogen-ext/src/autogen_ext` → 0 hits (No redaction helper anywhere in the three Python packages.) (verified)
  - *To reach the next level:* No log filters or redaction on main logging paths.
- **C L1:** Masking covers only config serialization; logs, traces and subprocess environments are unprotected. — [python/packages/autogen-ext/src/autogen_ext/models/openai/config/__init__.py:115](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/openai/config/__init__.py#L115); [python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py:716-721](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py#L716-L721); [python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py:397](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py#L397) (verified)
  - *To reach the next level:* Logs and transcripts are not protected.
- **D L2:** No built-in telemetry; OpenTelemetry falls back to a NoOp provider and event loggers have no handler unless configured, but enabling them logs full payloads unredacted. — [python/packages/autogen-core/src/autogen_core/_telemetry/_tracing.py:36](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_telemetry/_tracing.py#L36); [python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py:716-721](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py#L716-L721) (verified)
  - *To reach the next level:* Redaction is not always on, because none exists.
- **B L1:** Long-lived model provider keys are reachable by in-process tools and by every script the host executor runs. — [python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py:397](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py#L397) (verified)
  - *To reach the next level:* Keys are not scoped or short-lived.
- **Cap:** none

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

Each run returns a structured stream of tool-call request and execution events attributed to the agent that made them, and function tools log a ToolCallEvent with arguments and result. None of this is persisted unless the developer attaches a logging handler or an OpenTelemetry provider; by default the record exists only in memory. MCP calls produce trace spans but not event-log entries, approvals are not logged as distinct events, and nothing records the requesting human.

- **S L2:** ToolCallEvent records tool name, arguments and result; message events carry the source agent name. — [python/packages/autogen-core/src/autogen_core/tools/_base.py:201-206](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/tools/_base.py#L201-L206); [python/packages/autogen-ext/src/autogen_ext/tools/mcp/_workbench.py:335](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/mcp/_workbench.py#L335) (verified)
  - *To reach the next level:* No requesting-principal or approver attribution.
- **C L2:** Built-in function tools log events; MCP calls emit only trace spans and approvals or denials are not separate records. — [python/packages/autogen-core/src/autogen_core/tools/_base.py:201-206](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/tools/_base.py#L201-L206); [python/packages/autogen-ext/src/autogen_ext/tools/mcp/_workbench.py:335](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/mcp/_workbench.py#L335); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:711-715](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py#L711-L715) (verified)
  - *To reach the next level:* Extension calls and approvals/denials are not recorded consistently.
- **D L0:** The event logger has no handler and tracing uses a NoOp provider unless configured, so nothing persists by default. — [python/packages/autogen-core/src/autogen_core/_telemetry/_tracing.py:36](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_telemetry/_tracing.py#L36); [python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py:90](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py#L90) (verified)
  - *To reach the next level:* Persistent logging is opt-in.
- **B L1:** Logging goes through Python logging after the tool runs; failures are silent and actions proceed. — [python/packages/autogen-core/src/autogen_core/tools/_base.py:201-206](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/tools/_base.py#L201-L206) (verified)
  - *To reach the next level:* Records are not flushed durably per action with errors surfaced.
- **Cap:** G1 — Persistent audit logging requires the developer to configure a logging handler or OpenTelemetry provider.

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

A single AssistantAgent stops after one round of tool calls by default and code executors time out after 60 seconds, killing the process. Multi-agent teams, however, default to no turn limit and no termination condition, so a round-robin or selector team runs until something external stops it. Turn, token and wall-clock limits exist as opt-in termination conditions checked between messages; nested teams and agent-as-tool start fresh budgets, and there are no rate limits on side-effecting tools.

- **S L2:** Turn caps, TokenUsageTermination, TimeoutTermination and per-execution timeouts with process termination are enforced in code when configured. — [python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_base_group_chat_manager.py:214-215](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_base_group_chat_manager.py#L214-L215); [python/packages/autogen-agentchat/src/autogen_agentchat/conditions/_terminations.py:358](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/conditions/_terminations.py#L358); [python/packages/autogen-agentchat/src/autogen_agentchat/conditions/_terminations.py:235](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/conditions/_terminations.py#L235); [python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py:447](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py#L447); searched `rg -n -i 'rate_limit|ratelimit|RateLimiter'` in `python/packages/autogen-agentchat/src/autogen_agentchat python/packages/autogen-core/src/autogen_core` → 0 hits (No rate limiting on tool calls.) (verified)
  - *To reach the next level:* No rate limits on side-effecting tools.
- **C L2:** Limits apply to the top-level team loop and executor timeouts; nested teams and tools wrapping agents have their own budgets. — [python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_base_group_chat_manager.py:214-215](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_base_group_chat_manager.py#L214-L215); [python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py:149](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py#L149) (verified)
  - *To reach the next level:* Sub-agents and nested teams do not count against the parent budget.
- **D L0:** Group chats default to max_turns=None and termination_condition=None (Magentic-One is the exception at 20 turns). — [python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_base_group_chat.py:73-74](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_base_group_chat.py#L73-L74); [python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_round_robin_group_chat.py:248-249](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_round_robin_group_chat.py#L248-L249); [python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:739](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L739) (verified)
  - *To reach the next level:* Teams are unlimited by default.
- **B L0:** A default team with no termination condition can loop and spend indefinitely. — [python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_round_robin_group_chat.py:248-249](https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_round_robin_group_chat.py#L248-L249) (verified)
  - *To reach the next level:* No default ceiling on team runtime or spend.
- **Cap:** G1 — Team turn, token and time limits are opt-in termination conditions; the default team is unlimited.

## Rule-of-Two check
[A] untrusted input: WebSurfer visit_url accepts any URL (_multimodal_web_surfer.py:655); tool results and other agents' messages enter context unmarked · [B] sensitive data/systems: FileSurfer base_path=os.getcwd() (_file_surfer.py:79); LocalCommandLineCodeExecutor env=os.environ.copy() (local/__init__.py:397) · [C] state change / egress: CodeExecutorAgent executes code from any source with approval_func=None (_code_executor_agent.py:441,681); Docker executor has default network (_docker_code_executor.py:538-546) · Same default session? Yes

## Highest-impact improvements
1. Give group-chat teams a default turn cap and timeout (as MagenticOneGroupChat does) instead of max_turns=None. — C10 D L0→L2, +0.100 before caps (Playbook 3 step 3)
2. Make create_default_code_executor fail closed when Docker is unavailable instead of falling back to the host executor. — C4 D L2→L3, +0.050 before caps (Playbook 3 step 1)
3. Harden the Docker executor defaults: non-root user, dropped capabilities, no-new-privileges, network disabled unless requested, and resource limits. — C4 S L2→L3, +0.075 before caps (Playbook 3 step 1)
4. Add an approval hook to the AssistantAgent workbench path so every tool call, including MCP and code-execution tools, can be gated, and enable a console approver by default. — C2 S L0→L3, +0.225 before caps (Playbook 5)
5. Default CodeExecutorAgent.sources to the agent's paired coder rather than any participant, and drop file:// from the WebSurfer allowlist. — C5 S L0→L2, +0.150 before caps (Playbook 1)

## Re-audit log
- No changes.

## Limitations
- Static source review of the pinned commit only; nothing was executed, installed, or probed.
- Scope is the Python packages autogen-core, autogen-agentchat and autogen-ext; the .NET implementation, AutoGen Studio, agbench and magentic-one-cli were not scored.
- MCP stdio servers' environment handling depends on the mcp library's default (an allowlisted env when env is None); this was not verified in the library source.
- .github/copilot-instructions.md contains build instructions for coding agents; it is contributor guidance, not reviewer steering, and was treated as data and not followed.
- The project is in maintenance mode; the README directs new users to Microsoft Agent Framework, which was not reviewed.
