---
title: "Create policy"
method: POST
path: "/orgs/{org_name}/governance/policies"
tags: ["Policies"]
---

# Create policy

`POST /orgs/{org_name}/governance/policies`

## Request

- Base URL: `https://hub.docker.com/v2`
- URL: `https://hub.docker.com/v2/orgs/{org_name}/governance/policies`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/docker/apis/docker-ai-governance-policy-api/docs/orgs/:org_name/governance/policies/post.ts> (a function with typed inputs; its response is checked against the schema)

Creates a new policy with an empty rule set. Rules are added separately via the rules sub-resource.

## Request body

- CreatePolicyRequest: Fields required to create a new policy. Omitting `cedar_v1` creates an `allowlist_v0` policy with an empty rule set. Supplying `cedar_v1` creates a Cedar:V1 policy; rules are embedded in the Cedar text rather than managed via the rules sub-resource.
  - `name` string, required: Policy name, unique within the organization.
  - `scope` Scope: Restricts the policy to specific teams. An empty or absent list means the policy applies org-wide.
    - `teams` string[]: Team IDs the policy applies to. Each must be a valid team in the organization.
  - `cedar_v1` CedarV1Policy: Cedar:V1 policy body. Present on `Policy` when `PolicySummary.type` is `cedar_v1`. Cedar policies encode their rules directly in `text` rather than in the rules sub-resource; the rules endpoints are not available for Cedar policies.
    - `text` string, required: One or more Cedar `permit` or `forbid` statements. Must be syntactically valid Cedar and must not carry an `@id` annotation (IDs are server-assigned).
    - `schema_url` string, required: URL of the Cedar schema this policy was authored against. The evaluator looks up the schema by this URL from its built-in registry. Use `https://schemas.docker.com/policy/cedar/v1/mcp/v0` for MCP policies.

## Response `201`

Policy created. Returns the new policy without its rule set.

- Policy: Full policy representation. Exactly one of `allowlist_v0` or `cedar_v1` is present, depending on the policy type.
  - `id` string, required
  - `name` string, required: Human-readable label, unique within the organization.
  - `org` string, required
  - `scope` Scope, required: Restricts the policy to specific teams. An empty or absent list means the policy applies org-wide.
    - `teams` string[]: Team IDs the policy applies to. Each must be a valid team in the organization.
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `allowlist_v0` AllowlistV0: Network, HTTP, or filesystem allowlist containing a list of rules. Present on Policy when `PolicySummary.type` is `allowlist_v0`; omitted when the policy has no rules yet. All rules in an allowlist share the same domain. All rules are evaluated on every request: `deny` always wins over `allow`.
    - `domain` 'network' | 'filesystem': The access-control domain shared by all rules in this allowlist. Derived from rule actions: network actions (`connect:tcp`, `connect:udp`) produce `network`; filesystem actions (`read`, `write`) produce `filesystem`. Present when `rules` is non-empty; absent when the allowlist has no rules.
    - `rules` Rule[], required
      - union: A single allow or deny rule within an allowlist policy.
        - object
          - `id` string, required
          - `name` string, required: Human-readable label for the rule.
          - `actions` string[], required: Network actions: `connect:tcp`, `connect:udp`. Filesystem actions: `read`, `write`. HTTP actions: `request:get`, `request:post`, `request:put`, `request:delete`, `request:patch`, `request:head`, `request:options`, `request:connect`, `request:trace`. All actions in a rule must belong to the same layer; mixing HTTP, network, or filesystem actions in one rule is rejected.
          - `resources` string[], required: Network domain: hostnames (for example, `example.com`), wildcard subdomains (`*.example.com` or `**.example.com`), hostnames with port (for example, `example.com:443`), or CIDRs in IPv4 or IPv6 notation (for example, `10.0.0.0/8` or `2001:db8::/32`). Filesystem domain: paths (for example, `/data`); `*` matches within one path segment, `**` matches recursively (for example, `/data/**`). Required for network and filesystem rules and forbidden for HTTP rules.
          - `http_resources` HTTPResource[]: HTTP request targets. Required for HTTP rules and forbidden for network and filesystem rules. A request matches when any target matches.
            - `host` string, required: Domain name or domain glob without a URL scheme or port. Use the separate `port` field to restrict the target to one port.
            - `port` integer: Optional destination port. Omit it to match every port.
            - `path` string, required: Absolute HTTP path glob. `*` matches one segment and `**` matches any depth, including the bare path.
          - `decision` 'allow' | 'deny', required: Outcome applied when this rule matches a request. `deny` always wins: if any rule in the policy matches with `decision: deny`, the request is denied even if other rules match with `decision: allow`.
        - object
          - `id` string, required
          - `name` string, required: Human-readable label for the rule.
          - `actions` string[], required: Network actions: `connect:tcp`, `connect:udp`. Filesystem actions: `read`, `write`. HTTP actions: `request:get`, `request:post`, `request:put`, `request:delete`, `request:patch`, `request:head`, `request:options`, `request:connect`, `request:trace`. All actions in a rule must belong to the same layer; mixing HTTP, network, or filesystem actions in one rule is rejected.
          - `resources` string[]: Network domain: hostnames (for example, `example.com`), wildcard subdomains (`*.example.com` or `**.example.com`), hostnames with port (for example, `example.com:443`), or CIDRs in IPv4 or IPv6 notation (for example, `10.0.0.0/8` or `2001:db8::/32`). Filesystem domain: paths (for example, `/data`); `*` matches within one path segment, `**` matches recursively (for example, `/data/**`). Required for network and filesystem rules and forbidden for HTTP rules.
          - `http_resources` HTTPResource[], required: HTTP request targets. Required for HTTP rules and forbidden for network and filesystem rules. A request matches when any target matches.
            - `host` string, required: Domain name or domain glob without a URL scheme or port. Use the separate `port` field to restrict the target to one port.
            - `port` integer: Optional destination port. Omit it to match every port.
            - `path` string, required: Absolute HTTP path glob. `*` matches one segment and `**` matches any depth, including the bare path.
          - `decision` 'allow' | 'deny', required: Outcome applied when this rule matches a request. `deny` always wins: if any rule in the policy matches with `decision: deny`, the request is denied even if other rules match with `decision: allow`.
  - `cedar_v1` CedarV1Policy: Cedar:V1 policy body. Present on `Policy` when `PolicySummary.type` is `cedar_v1`. Cedar policies encode their rules directly in `text` rather than in the rules sub-resource; the rules endpoints are not available for Cedar policies.
    - `text` string, required: One or more Cedar `permit` or `forbid` statements. Must be syntactically valid Cedar and must not carry an `@id` annotation (IDs are server-assigned).
    - `schema_url` string, required: URL of the Cedar schema this policy was authored against. The evaluator looks up the schema by this URL from its built-in registry. Use `https://schemas.docker.com/policy/cedar/v1/mcp/v0` for MCP policies.

## Other responses

- `400`: Bad request
- `401`: Missing or invalid credentials
- `403`: Caller lacks the required permission for this org, the org is not entitled to use governance (`permission_denied`), or a creation limit has been reached (`limit_exceeded`): the org already has the maximum number of policies, or the policy already has the maximum number of rules.
- `404`: Not found
- `409`: Conflict
- `500`: Internal server error

## Changes

- **2026-10-02** `4f9f7d5cadd5`: 2 breaking, 9 warning, 1 info
  - the response property `allowlist_v0/rules/items/resources` became optional for the status `201`
  - added `subschema #1, subschema #2` to the `allowlist_v0/rules/items/` response property `oneOf` list for the response status `201`
  - added the new `request:connect` enum value to the `allowlist_v0/rules/items/actions/items/` response property for the response status `201`
  - added the new `request:delete` enum value to the `allowlist_v0/rules/items/actions/items/` response property for the response status `201`
  - …8 more
- **2026-09-22** `85e78016fe38`: 2 info
  - added the new optional request property `cedar_v1`
  - added the optional property `cedar_v1` to the response with the `201` status
- **2026-06-10** `c133c0782991`: 6 warning
  - added the new `limit_exceeded` enum value to the `error/code` response property for the response status `400`
  - added the new `limit_exceeded` enum value to the `error/code` response property for the response status `401`
  - added the new `limit_exceeded` enum value to the `error/code` response property for the response status `403`
  - added the new `limit_exceeded` enum value to the `error/code` response property for the response status `404`
  - …2 more
- **2026-06-04** `67e1167ee1cf`: 2 warning
  - removed the request property `scope/profiles`
  - removed the optional property `scope/profiles` from the response with the `201` status
- …earlier changes not shown

[Operation history](https://skmtc.dev/docker/apis/docker-ai-governance-policy-api/changes/orgs/:org_name/governance/policies/post.md)

---

[API](https://skmtc.dev/docker/apis/docker-ai-governance-policy-api.md) - [All operations](https://skmtc.dev/docker/apis/docker-ai-governance-policy-api/llms.txt) - [OpenAPI document](https://skmtc.dev/docker/apis/docker-ai-governance-policy-api/revisions/4f9f7d5cadd5?raw)
