Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

secure-deployment changedmanaged-agents/secure-deployment

Nearest release: v2.1.299, published under an hour after this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+860added
Lines−0removed
From line — no hunk to open at
First seen 13 Oct 2026 this site's first read of the page
Recorded edits7to this page, all time

## Choose where the agent runs ## Limit the network ## Keep credentials in vaults ## Restrict web search and web fetch ## Approve risky actions ## Give the agent the smallest tool set ## Keep untrusted input away from powerful tools ## Set limits and a way to stop ## Next steps

The whole hunk

860 lines, new page
/
lines

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: Secure your Managed Agents deployment
url: https://platform.claude.com/docs/en/managed-agents/secure-deployment
description: The settings that limit what your agents can reach and do, most important first.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

This guide lists the settings that limit what an agent on Claude Managed Agents can reach and do, most important first. Each section links to the page that covers the setting in full.

| Section                                                                                                                                                                                                | Setting or decision                                                           | Recommended                                                                                                                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Choose where the agent runs](https://platform.claude.com/docs/en/managed-agents/secure-deployment#choose-where-the-agent-runs)                                                                        | Cloud or self-hosted sandbox                                                  | Cloud, unless files and processes must stay on your infrastructure                                                                                                                                                             |
| [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network)                                                                                            | Environment `networking.type`                                                 | `limited`, with only the hosts the agent needs                                                                                                                                                                                 |
| [Keep credentials in vaults](https://platform.claude.com/docs/en/managed-agents/secure-deployment#keep-credentials-in-vaults)                                                                          | `injection_location` and `networking` on each environment variable credential | Request headers only, and `limited` networking with only the hosts the key is for                                                                                                                                              |
| [Restrict web search and web fetch](https://platform.claude.com/docs/en/managed-agents/secure-deployment#restrict-web-search-and-web-fetch)                                                            | `allowed_domains` on each web tool                                            | An allowlist on each tool. On `web_fetch`, list only the sites the agent needs. On `web_search`, list the sites you want results from                                                                                          |
| [Approve risky actions](https://platform.claude.com/docs/en/managed-agents/secure-deployment#approve-risky-actions)                                                                                    | `permission_policy` on each tool                                              | `auto` on `bash`, `write`, `edit`, `web_fetch`, and MCP tools that only read data. `always_ask` instead on a tool if you cannot undo its changes outside the sandbox, or if relayed end-user text alone should not make it run |
| [Give the agent the smallest tool set](https://platform.claude.com/docs/en/managed-agents/secure-deployment#give-the-agent-the-smallest-tool-set)                                                      | `default_config.enabled` on the agent toolset                                 | `false`, then enable the tools the agent needs                                                                                                                                                                                 |
| [Keep untrusted input away from powerful tools](https://platform.claude.com/docs/en/managed-agents/secure-deployment#keep-untrusted-input-away-from-powerful-tools)                                    | Which tools and credentials an agent holds when it reads untrusted input      | No agent that reads untrusted input has a tool on `always_allow` that writes files, runs commands, or changes records                                                                                                          |
| [Set limits and a way to stop](https://platform.claude.com/docs/en/managed-agents/secure-deployment#set-limits-and-a-way-to-stop)                                                                      | `budget` on each session and deployment                                       | A cap sized to what you expect a run to cost                                                                                                                                                                                   |
| [Optionally have an offline reviewer read every transcript](https://platform.claude.com/docs/en/managed-agents/secure-deployment-monitoring#optionally-have-an-offline-reviewer-read-every-transcript) | An offline review job you run that reads each session's events                | Optional. A review of each session that went idle or terminated, on a schedule                                                                                                                                                 |
| [Monitor sessions and review retention](https://platform.claude.com/docs/en/managed-agents/secure-deployment-monitoring#monitor-sessions-and-review-retention)                                         | Webhooks and session deletion                                                 | An alert when a session goes idle, reaches its budget, or terminates, and a check of why it went idle. Store the events you want to keep in your own logs, and delete sessions you no longer need                              |

[Security risks and sandbox boundaries](https://platform.claude.com/docs/en/managed-agents/secure-deployment-risks) explains why these settings matter and what they do not protect against. To review and monitor sessions, see [Review and monitor agent sessions](https://platform.claude.com/docs/en/managed-agents/secure-deployment-monitoring).

## Choose where the agent runs

Choose a cloud environment unless you need files and processes to stay on infrastructure you control. Session history and tool inputs and outputs go to Anthropic either way.

If you use a [self-hosted sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes), keep these four points in mind:

* **Network:** [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network) applies to cloud environments. For a self-hosted sandbox, set the equivalent limits on its traffic in your own firewall. Your firewall does not limit the MCP servers an agent declares, so review them, and any that your application sets for a session.
* **Web tools:** The web tools run on Anthropic's servers, so your firewall does not limit them. Limit them with their domain lists. See [Restrict web search and web fetch](https://platform.claude.com/docs/en/managed-agents/secure-deployment#restrict-web-search-and-web-fetch).
* **Credentials:** Environment variable credentials are not yet supported with self-hosted sandboxes.
* **Isolation and hardening:** You are responsible for isolating sessions from each other, hardening the sandbox image, and storing the environment service key. See the [Security model](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-security).

Neither option changes the compliance coverage of Managed Agents or how long it keeps session history. See [Monitor sessions and review retention](https://platform.claude.com/docs/en/managed-agents/secure-deployment-monitoring#monitor-sessions-and-review-retention).

## Limit the network

Set `networking.type` to `limited` and list only the hosts the agent needs in `allowed_hosts`. An environment create request that omits `networking` might get `unrestricted`, so set `networking` in every create request. See [Risks of unrestricted networking](https://platform.claude.com/docs/en/managed-agents/environments#risks-of-unrestricted-networking).

Files, memory stores, and GitHub repositories that you attach stay available to the agent regardless of `allowed_hosts`.

The examples on this page use a support agent. It reads a customer's ticket, looks up the order, reads your help center, and drafts a reply. Your application runs the order lookup, which needs no host, so this environment allows one host, the help center, for `web_fetch`:

<CodeGroup defaultLanguage="CLI">
  ```bash cURL
  curl -fsS https://api.anthropic.com/v1/environments \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d '{
      "name": "support-agent",
      "config": {
        "type": "cloud",
        "networking": {
          "type": "limited",
          "allowed_hosts": ["help.example.com"]
        }
      }
    }'
  ```

  <CodeGroupItem>
    ```bash CLI
    ant apply environment.yaml
    ```

    <File filename="environment.yaml">
      ```yaml
      # yaml-language-server: $schema=https://platform.claude.com/schemas/ant/beta/environment.json
      name: support-agent
      config:
        type: cloud
        networking:
          type: limited
          allowed_hosts:
            - help.example.com
      ```
    </File>
  </CodeGroupItem>

  ```python Python
  environment = client.beta.environments.create(
      name="support-agent",
      config={
          "type": "cloud",
          "networking": {
              "type": "limited",
              "allowed_hosts": ["help.example.com"],
          },
      },
  )
  ```

  ```typescript TypeScript
  const environment = await client.beta.environments.create({
    name: "support-agent",
    config: {
      type: "cloud",
      networking: {
        type: "limited",
        allowed_hosts: ["help.example.com"]
      }
    }
  });
  ```

  ```csharp C#
  using Anthropic.Models.Beta.Environments;

  var environment = await client.Beta.Environments.Create(new()
  {
      Name = "support-agent",
      Config = new BetaCloudConfigParams
      {
          Networking = new BetaLimitedNetworkParams
          {
              AllowedHosts = ["help.example.com"],
          },
      },
  });
  ```

  ```go Go
  environment, err := client.Beta.Environments.New(ctx, anthropic.BetaEnvironmentNewParams{
  	Name: "support-agent",
  	Config: anthropic.BetaEnvironmentNewParamsConfigUnion{
  		OfCloud: &anthropic.BetaCloudConfigParams{
  			Networking: anthropic.BetaCloudConfigParamsNetworkingUnion{
  				OfLimited: &anthropic.BetaLimitedNetworkParams{
  					AllowedHosts: []string{"help.example.com"},
  				},
  			},
  		},
  	},
  })
  if err != nil {
  	panic(err)
  }
  _ = environment
  ```

  ```java Java
  import com.anthropic.models.beta.environments.*;
  import java.util.List;

  var environment = client.beta().environments().create(EnvironmentCreateParams.builder()
      .name("support-agent")
      .config(BetaCloudConfigParams.builder()
          .networking(BetaLimitedNetworkParams.builder()
              .allowedHosts(List.of("help.example.com"))
              .build())
          .build())
      .build());
  ```

  ```php PHP
  $environment = $client->beta->environments->create(
      name: 'support-agent',
      config: [
          'type' => 'cloud',
          'networking' => [
              'type' => 'limited',
              'allowed_hosts' => ['help.example.com'],
          ],
      ],
  );
  ```

  ```ruby Ruby
  environment = client.beta.environments.create(
    name: "support-agent",
    config: {
      type: "cloud",
      networking: {
        type: "limited",
        allowed_hosts: ["help.example.com"]
      }
    }
  )
  ```
</CodeGroup>

A `limited` environment has three networking settings:

| Setting                  | What it opens to code in the sandbox                                                                                                                                                                                                                                                           | Recommended                                                                                                                                                                                                |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowed_hosts`          | The hosts you list, for any request                                                                                                                                                                                                                                                            | Only the hosts the agent needs, including the host of each MCP server you operate or trust                                                                                                                 |
| `allow_package_managers` | The [package manager hosts](https://platform.claude.com/docs/en/managed-agents/environments#package-manager-hosts). They include every repository and path on `github.com`, `gitlab.com`, and `bitbucket.org`, where anyone can publish content and where code in the sandbox can upload files | `false`, unless the environment's `packages` setting lists packages, which requires `true`. If the agent installs packages while it runs, list only the registry hosts it needs in `allowed_hosts` instead |
| `allow_mcp_servers`      | No host. Managed Agents connects to MCP servers from Anthropic's servers                                                                                                                                                                                                                       | `false`, with the host of each MCP server you operate or trust listed in `allowed_hosts`                                                                                                                   |

The `allow_package_managers` and `allow_mcp_servers` settings add no hosts for web search and web fetch.

Leave `allow_mcp_servers` off, which is the default, and list the host of each MCP server you operate or trust in `allowed_hosts`. Each host you list is also open to code in the sandbox. With `allow_mcp_servers` off, a check at session creation rejects the request if an MCP server's host is not listed. See [Provide authentication at session creation](https://platform.claude.com/docs/en/managed-agents/mcp-connector#provide-authentication-at-session-creation). The same check runs when a session update changes `mcp_servers`.

<Warning>
  Network access is granted for each host, not for each operation. The sandbox can send any request to an allowed host, including uploads such as `git push` and package publishing. It can also use any credential the command supplies, even one that someone hid in text the agent reads.
</Warning>

When you choose hosts for `allowed_hosts`, follow these two rules:

* List only hosts you operate or trust.
* Avoid `*.` wildcards and shared-hosting domains where anyone can publish content.

If the agent keeps `bash`, set the `bash` tool's [permission policy](https://platform.claude.com/docs/en/managed-agents/permission-policies) as [Approve risky actions](https://platform.claude.com/docs/en/managed-agents/secure-deployment#approve-risky-actions) describes.

<Note>
  After you tighten an environment, start new sessions and stop the ones that were already running. A session that is already running can keep the old limits until it ends. See [Set limits and a way to stop](https://platform.claude.com/docs/en/managed-agents/secure-deployment#set-limits-and-a-way-to-stop).
</Note>

See [Cloud environment setup](https://platform.claude.com/docs/en/managed-agents/environments#networking) for every networking setting.

## Keep credentials in vaults

Store every secret in a vault. For each environment variable credential, set the injection location to request headers only and list only the hosts the secret is for. Code in the sandbox sees a placeholder instead of the secret. Managed Agents swaps in the real secret only in outgoing HTTPS requests to the hosts the credential allows. So the secret stays out of direct reach of the model, unless a service sends it back, such as an endpoint that echoes request headers. If the credential's `networking` is `unrestricted`, Managed Agents swaps in the real secret in requests to any host the environment lets the sandbox reach. To use a vault, pass its ID in `vault_ids` when you create the session or deployment.

| Setting                                                   | Set it to                                                                                                                        | Why                                                                                                                                                                                                                              | What it does not do                                                                                                                                         |
| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `injection_location`                                      | `{"header": true, "body": false}`, after you check that the service reads the key from a header                                  | Request bodies are often built from content the agent reads, so a key in a body is more exposed. Name both fields: a create request that omits the object enables both locations, and an update changes only the fields you send | Code can still use the key on every host the credential allows. A service that expects the key in the body receives the placeholder and rejects the request |
| `networking` on the credential                            | `limited`, with the exact hosts the key is for                                                                                   | Responses reach the sandbox unredacted, so avoid wildcards, shared-hosting domains, and hosts that echo request headers                                                                                                          | It does not open the host. The environment must also allow it                                                                                               |
| The key's permissions, at the service that issued the key | Only the permissions the agent needs                                                                                             | The agent can do anything the key allows                                                                                                                                                                                         | Not applicable                                                                                                                                              |
| A mounted repository's GitHub token                       | A [fine-grained token](https://platform.claude.com/docs/en/managed-agents/github#token-permissions) with the minimum permissions | Code in the sandbox can fetch from and push to the mounted repository with it for the whole session. Grant write access only if the agent must push                                                                              | Not applicable                                                                                                                                              |

The support agent needs no vault credential, because your application holds the API key for your order API. If your agent does hold a vault credential, see [Add a credential](https://platform.claude.com/docs/en/managed-agents/vaults#add-a-credential) for the request in every language.

Keep keys out of system prompts, agent definitions, and messages. Do not give the agent a Claude API key. Even when a Claude API key is in a vault, code in the sandbox can use it to call the Claude API directly. It can do anything that key allows, such as starting or deleting sessions, or using web search and web fetch. The agent's tool settings, approvals, and budget do not apply to those calls. In a `limited` environment, code can make these calls only if `allowed_hosts` lets the sandbox reach `api.anthropic.com`.

Fetch tokens yourself and store them in the vault, because a token that code in the sandbox fetches with a stored secret comes back unredacted.

Keep vaults for workloads with different trust levels in separate [workspaces](https://platform.claude.com/docs/en/manage-claude/workspaces), because any API key with access to a workspace can reference its vaults. Use API keys scoped to one workspace.

See [Authenticate with vaults](https://platform.claude.com/docs/en/managed-agents/vaults) for MCP credentials and rotation.

## Restrict web search and web fetch

Set `allowed_domains` on `web_fetch` to the sites the agent needs. Any URL the agent fetches can carry data to the site it points to, so this list is a security control. On `web_search`, set `allowed_domains` to the sites you want results from, so that results come only from sites you trust to be accurate. The list does not stop the search query from reaching the search provider. Search results include text from pages, so the list also limits which sites' text reaches the agent. Set `allowed_domains` on both tools for every type of environment.

A `blocked_domains` list blocks the hosts you list and their subdomains, and no other host. The same content can still reach the agent from web archives, caches, mirrors, or related domains you did not list. Do not rely on `blocked_domains` for security. Use `allowed_domains` and name the hosts you trust.

In a `limited` environment, the `allowed_hosts` list from [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network) also limits the web tools. An `unrestricted` environment or a self-hosted sandbox does not limit the web tools.

| In a `limited` environment                                                   | Result                                                                                                                                                                                                                                                       |
| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| An `allowed_domains` entry on an enabled web tool is outside `allowed_hosts` | Creating a session fails with a 400 error, and so does a session update that adds such an entry. A session that a deployment starts, on its schedule or by a manual run, is created anyway. The tool then returns nothing from hosts outside `allowed_hosts` |
| A web tool has no list of its own                                            | The tool returns pages and results only from hosts in `allowed_hosts`. Set `allowed_domains` on the tool as well                                                                                                                                             |
| `allowed_hosts` has no entries                                               | Neither web tool returns a page or a search result                                                                                                                                                                                                           |
| You add a host to `allowed_hosts` for a web tool                             | The host is also open to code in the sandbox                                                                                                                                                                                                                 |

The two lists match hosts differently:

| List                          | Entry           | Matches                           | Does not match    |
| ----------------------------- | --------------- | --------------------------------- | ----------------- |
| `allowed_hosts` (environment) | `example.com`   | `example.com`                     | `www.example.com` |
| `allowed_hosts` (environment) | `*.example.com` | Every subdomain                   | `example.com`     |
| `allowed_domains` (web tool)  | `example.com`   | `example.com` and every subdomain | Other domains     |

If the agent needs a site and all of its subdomains, list both `example.com` and `*.example.com` in `allowed_hosts`, and otherwise list exact hosts. If a tool lists `example.com` and `allowed_hosts` lists only `*.example.com`, the session is created. The check at session creation counts `example.com` as within `*.example.com`, but the tool returns nothing from `example.com` itself. See [Set domain lists on an agent](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#set-domain-lists-on-an-agent) for how the two lists match.

The `web_fetch` tool also opens only URLs that have already appeared in the session:

| Where the URL appears                                                                         | `web_fetch` can open it                           |
| --------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| The text of a user message, including end-user text that you relay                            | Yes                                               |
| The description of a `user.define_outcome` event                                              | Yes                                               |
| The address of a web search result                                                            | Yes                                               |
| The text of a page that `web_fetch` returned earlier (not a PDF), where the full URL is shown | Yes                                               |
| The text of a custom tool's result, when Claude called the tool directly                      | Yes, unless the result is marked `is_error: true` |
| The system prompt                                                                             | No                                                |
| The agent's configuration, including `allowed_domains` entries                                | No                                                |
| Claude's own output                                                                           | No                                                |
| Output of `bash` and the other sandbox tools                                                  | No                                                |
| An MCP tool result                                                                            | No                                                |
| A file attached to a user message                                                             | No                                                |

In a multiagent session, `web_fetch` opens a URL from another agent only if it reached that agent through a source marked Yes. A custom tool's result from a direct call counts as a source marked Yes. This holds even if Claude wrote its text, for example when the tool repeats its input. A URL can count even when it is written without `https://`, such as `example.com/docs`. The `web_fetch` tool cannot always open a link that shows words instead of its URL, such as "Contact support." If the agent must fetch a URL that has not appeared in the session, send it in a user message.

This rule reduces the chance that injected text builds a URL that carries private data. End-user text, search results, fetched pages, and custom tool results can still add URLs, so keep `allowed_domains` set. The Messages API applies a similar rule with a different list of sources. See [URL validation](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool#url-validation).

A domain list on `web_fetch` does not limit the `bash` tool. [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network) as well. See [Domain list rules](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#domain-list-rules).

## Approve risky actions

Set `auto` on `bash`, `write`, `edit`, and `web_fetch`, and on MCP tools that only read data. Use `always_ask` instead on a tool if you cannot undo its changes outside the sandbox. Also use it on a tool that should not run just because end-user text you relay asks for it. A [permission policy](https://platform.claude.com/docs/en/managed-agents/permission-policies) determines whether a tool call runs, waits for your approval, or is evaluated by the server.

| Tool                          | Recommended policy                                                                                                                           | Why                                                                                                  |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `read`, `glob`, `grep`        | `always_allow`                                                                                                                               | They read files in the sandbox and change nothing                                                    |
| `bash`, `write`, `edit`       | `auto`. Use `always_ask` on a tool if you cannot undo its changes outside the sandbox. Use `always_ask` on `bash` if you relay end-user text | The agent toolset default is `always_allow`, which runs every call without approval                  |
| `web_fetch`                   | `auto`                                                                                                                                       | A URL the agent fetches can carry data to the site it points to                                      |
| `web_search`                  | `always_ask` if the agent handles data you would not want sent in a search query. Otherwise `always_allow`                                   | `allowed_domains` limits which sites results come from, not what the query contains                  |
| MCP tools that only read data | `auto`, set for each tool in the toolset's `configs`                                                                                         | The toolset default stays `always_ask`, so a tool the MCP server adds later still waits for approval |
| MCP tools that change data    | `always_ask`                                                                                                                                 | This is the MCP toolset default. Keep it                                                             |
| Custom tools                  | Your code decides whether each call runs                                                                                                     | Permission policies do not apply                                                                     |

Cut at 300 lines. The page has the rest.

Feedback