# Policy concepts


The governance described here applies to local sandboxes. Cloud sandboxes
use separate network policy configuration. See
[Cloud network policy](/ai/sandboxes/governance/cloud/network-policy/) for cloud controls.

## Resource model

Docker sandbox governance is built around two resource types: **policies** and
**rules**.

A **policy** is a named collection of rules that controls sandbox access.
Policies exist at two levels:

- **Local**: configured per machine using the `sbx policy` CLI. Applies to
  sandboxes on that machine only.
- **Organization**: configured in Docker Home. Network and filesystem policies
  can also be managed via the
  [Governance API](/reference/api/ai-governance/). Applies to sandboxes across
  the organization. An organization can have several policies, each applying
  either org-wide or to specific teams. See [Policy scope](#policy-scope).

When organization governance is active, only organization allow rules can grant
access. Local and kit-defined deny rules still apply on top. See
[Precedence](#precedence).

A **rule** is the unit of access control within a policy. Each rule has:

- **Name**: a human-readable label
- **Actions**: the type of access the rule controls
- **Resources**: the targets the rule matches against
- **Decision**: `allow` or `deny`

Rules are grouped by domain. Network and filesystem rules in a policy must
share the same domain, either `network` or `filesystem`. MCP policies use Cedar
statements written in the `MCP` namespace instead of the network and filesystem
rule format.

An organization network policy can also require approval, which turns every
allow in that policy into a request the developer must confirm before access is
granted. Approval is set on the policy rather than on individual rules, so it
applies to all of the policy's allow rules at once. Without organization
governance, a request with no matching allow or deny rule also asks for
approval. See
[Approval-required access](/ai/sandboxes/governance/concepts/access-controls/network/#approval-required-access).

Network approval is separate from the MCP `@requireApproval` annotation. An MCP
approval confirms a single call within the session and creates no rule, while
an approved network destination stays allowed until you remove the rule. See
[MCP access policies](/ai/sandboxes/governance/concepts/access-controls/mcp/).

### Limits

Organization policies have the following limits, which help ensure fair usage
and resource availability across organizations:

| Limit                     | Value                                               |
|---------------------------|-----------------------------------------------------|
| Policies per organization | 100                                                 |
| Rules per policy          | 250                                                 |
| Policy size               | 400 KB total, shared across all of a policy's rules |

Typical policies use only a small fraction of the policy size limit. Domain
and file path values have no separate length limit beyond valid format.

If these limits don't fit your organization's needs,
[contact Docker Sales](https://www.docker.com/products/ai-governance/#contact-sales)
to discuss options.

## Policy scope

Each organization policy applies either across the whole organization or only
to specific teams:

- Org-wide: with no teams assigned, the policy applies to every member of the
  organization.
- Team-scoped: with one or more teams assigned, the policy applies only to
  members of those teams.

Teams are the same [teams](/accounts/organization/manage/manage-a-team/)
you manage for your organization; Docker matches a policy's teams against each
user's team membership. Because an organization can mix org-wide and team-scoped
policies, a single user is often subject to several at once. The policies that
apply to a given user are their _effective policies_: every org-wide policy,
plus every team-scoped policy for a team they belong to. See
[Rule evaluation](#rule-evaluation) for how a user's effective policies combine.

## Rule syntax

### Network rules

Network rules use `connect:tcp` for TCP and `connect:udp` for UDP. Resources are
hostnames, CIDR ranges, or ports. UDP requires
[experimental outbound UDP](/ai/sandboxes/governance/concepts/access-controls/local/#allow-outbound-udp).
ICMP is blocked.

**Hostname patterns**

| Pattern               | Example           | Matches                                                      |
| --------------------- | ----------------- | ------------------------------------------------------------- |
| Exact hostname        | `example.com`     | `example.com` on any port, not subdomains                     |
| Single-level wildcard | `*.example.com`   | One subdomain level, any port: `api.example.com`              |
| Multi-level wildcard  | `**.example.com`  | Any depth, any port: `api.example.com`, `v2.api.example.com`  |
| Hostname with port    | `example.com:443` | `example.com` on port 443 only                                |

`example.com` and `*.example.com` don't cover each other. Specify both if you
need to match the root domain and its subdomains.

**CIDR ranges**

Both IPv4 and IPv6 notation are supported: `10.0.0.0/8`, `192.168.1.0/24`,
`2001:db8::/32`.

#### HTTP method and path

A network rule matches a destination host on its own. An HTTP rule is a network
rule that also names an HTTP method and URL path, so a policy can allow reads
from an API without allowing writes to it.

An HTTP rule names one or more methods, a destination, and path patterns. What
each part accepts depends on where you configure the rule:

| Part        | Organization policy                        | Local policy                      |
| ----------- | ------------------------------------------ | --------------------------------- |
| Method      | One or more listed methods                 | `ANY`, or one or more methods     |
| Destination | A host or IP address                       | A host                            |
| Path        | One or more absolute path patterns         | One absolute path pattern         |

A destination can include a port, and a path pattern looks like `/api/**`.

A local rule doesn't accept an IP address or a CIDR range. Use a plain network
rule for those destinations. To cover a second path in a local policy, add a
second rule.

Every rule applies to at least one method. On the CLI, `--method ANY` covers
every HTTP method. In the composer, a rule with no methods selected covers
every method the composer lists. For the methods you can select individually, see
[Add a network rule](/ai/sandboxes/governance/concepts/access-controls/organization/#add-a-network-rule) for an
organization policy and
[HTTP method and path rules](/ai/sandboxes/governance/concepts/access-controls/local/#http-method-and-path-rules)
for a local one.

Path patterns follow the same wildcard rules as filesystem paths, where `*`
matches within one path segment and `**` matches any depth. A pattern without a
wildcard matches that path exactly, so `/repos` matches `/repos` and nothing
below it. Every pattern must start with `/` and can't contain a query string, a
fragment, or a `..` segment. A local rule's path must also be canonical, so it
can't contain percent-encoding, control characters, repeated or trailing
slashes, or a `.` segment. For the full list, see
[HTTP method and path rules](/ai/sandboxes/governance/concepts/access-controls/local/#http-method-and-path-rules).

HTTP requests are evaluated against both layers. A network rule sets the
baseline for a host, and HTTP rules adjust individual methods and paths within
it:

| Rules that cover the host   | Result for an HTTP request                                              |
| --------------------------- | ----------------------------------------------------------------------- |
| Network allow only          | Allowed at any method and path                                          |
| HTTP allow only             | Allowed only where a rule matches the method and path. Anything else is denied |
| Network allow and HTTP deny | The denied methods and paths are blocked. The rest stay allowed          |
| Network deny                | Blocked. An HTTP allow can't reopen a denied host                        |

A network deny is therefore a floor that HTTP rules can't raise, while a
network allow is a ceiling that HTTP rules can carve into.

When a rule requires a method and path decision, the sandbox HTTP proxy
evaluates each request separately instead of deciding once per connection.

Those requests have to go through the proxy. A connection it can't inspect,
such as one it handles transparently, is blocked rather than evaluated.
Traffic that isn't HTTP, such as SSH, carries no method or path, so HTTP rules
never match it. Control those destinations with network rules.

For local and organization policy configuration, see
[Network access policies](/ai/sandboxes/governance/concepts/access-controls/network/).

### Filesystem rules

Filesystem rules use the actions `read` and `write`. Resources are host paths
that sandboxes can mount as workspaces.

A workspace mounted with write access must be allowed by both a `read` and a
`write` rule; a read-only workspace needs only `read`. When default deny blocks
a mount, the denial reason names whether read or write access was missing.

`~` expands to the user's home directory on every platform, including Windows,
where it resolves to `%USERPROFILE%`. A single `~/**` rule therefore matches
each user's home tree on macOS, Linux, and Windows. The policy engine expands
only `~`: it does not expand environment variables, so a pattern such as
`%USERPROFILE%\**` or `$HOME/**` matches nothing.

For a path outside the home directory, write it in the format the user's
operating system uses. A rule matches only the format it's written in, so a
location that several platforms share needs a rule for each:

| Operating system | Example path                               |
| ---------------- | ------------------------------------------ |
| macOS, Linux     | `/data/project/**`                         |
| Windows          | `C:\data\project\**`                       |
| WSL              | `\\wsl.localhost\<distro>\data\project\**` |

On Windows, `*:` matches any drive letter, so `*:\data\**` matches the path on
any drive.

Wildcards behave the same way in every path format:

| Pattern            | Example    | Matches                                                    |
| ------------------ | ---------- | ---------------------------------------------------------- |
| Exact path         | `/data`    | `/data` only                                               |
| Segment wildcard   | `/data/*`  | `/data/project`, one path segment only, not subdirectories |
| Recursive wildcard | `/data/**` | `/data/project`, `/data/project/src`, any depth            |

Use `**` to match a directory tree recursively. A single `*` matches within one
path segment and won't cross a path separator. For example, `~/**` matches all
paths under the home directory, while `~/*` matches only its direct children.

For organization policy configuration and enforcement details, see
[Filesystem access policies](/ai/sandboxes/governance/concepts/access-controls/filesystem/).

### MCP policies

MCP policies control Model Context Protocol activity made available to a
sandbox through Docker's [MCP gateway](/ai/sandboxes/governance/mcp-gateway/). They are
organization policies written in Cedar using the `MCP` namespace, rather than
the network and filesystem rule format.

MCP policy applies when a developer registers a server and when an agent uses
the MCP gateway. Registration rules control future `sbx mcp add` operations.
Use-time rules control tool calls, gateway meta-tools, resource reads, and
prompt retrieval from servers that are already registered or loaded.

Governed MCP activity is default deny: a request is blocked unless a matching
`permit` allows it. A matching `forbid` overrides any `permit`, including a
permit that requires approval. Policy scope supplies the principal, so use
organization or team scope instead of matching users, teams, tenants, or roles
in Cedar.

For representative policies, see [MCP access policies](/ai/sandboxes/governance/concepts/access-controls/mcp/).
For exact action, resource, context, and approval behavior, see the
[MCP policy reference](/ai/sandboxes/governance/concepts/reference/mcp-policy/).

## Rule evaluation

When organization governance is active, the rules from all of a user's
[effective policies](#policy-scope) are combined and evaluated together against
each request, following two principles:

- Deny wins: if any rule matches with `decision: deny`, the request is denied,
  regardless of any matching allow rules.
- Default deny: anything an allow rule doesn't match is blocked. Outbound
  network traffic is blocked unless a network rule allows the destination, and a
  host path can't be mounted unless a filesystem rule allows it. MCP activity is
  blocked unless an MCP `permit` allows it.

Because every effective policy feeds the same evaluation, allows are additive (a
request is allowed if any effective policy allows it) and denies are absolute (a
request is blocked if any effective policy denies it). A deny rule in an
org-wide policy therefore applies to everyone and can't be overridden by a
team-scoped policy, which makes org-wide deny rules useful as guardrails.

Local and kit-defined allow rules take no part in this evaluation. Deny rules
from those sources do still apply. See [Precedence](#precedence).

A request that an approval-required policy allows produces a third outcome.
Rather than being allowed outright, it's held back until the developer confirms
the destination, and the confirmation governs later requests to it. This holds
even when another policy allows the same request without requiring approval. A
matching deny still wins, so a denied destination is blocked without asking.
See [Approval-required access](/ai/sandboxes/governance/concepts/access-controls/network/#approval-required-access).

## Precedence

What applies depends on whether your organization has governance enabled:

- No organization governance: local rules and any kit-defined network rules
  determine what sandboxes can access.
- Organization governance active: organization policy determines what access can
  be granted. Only organization allow rules grant access, so local and
  kit-defined allow rules are inactive and can't expand what the organization
  permits. Deny rules apply from every source, so a local or kit-defined deny
  can still restrict access further.

For kit-defined rules, see
[Network policies](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/capabilities/com.docker.sandbox/network-policy@1.md)
in the kit specification.

Precedence is decided by a rule's decision rather than its source:

| Rule                | Evaluated under organization governance |
| ------------------- | --------------------------------------- |
| Organization allow  | Yes                                     |
| Organization deny   | Yes                                     |
| Local allow         | No                                      |
| Local deny          | Yes                                     |
| Kit-defined allow   | No                                      |
| Kit-defined deny    | Yes                                     |

Local and kit-defined rules cover network access only, so a deny that layers on
top of organization policy is always a network deny. `sbx policy ls` hides
inactive rules by default. See
[Monitoring](/ai/sandboxes/governance/concepts/monitor-and-enforce/monitoring/#showing-inactive-rules) for how
to list them.

A local deny takes precedence over an organization approval requirement as
well, so the request is blocked and no approval is requested. Rules that a
developer gains by approving a request are the one exception to local allow
rules being inactive, because they record an answer to the organization's own
approval requirement rather than granting new access. See
[Approval-required access](/ai/sandboxes/governance/concepts/access-controls/network/#approval-required-access).

When organization governance is active, a user's organization policies are
evaluated together, as described in [Rule evaluation](#rule-evaluation).

