mirror of
https://github.com/docker/docs.git
synced 2026-10-28 07:15:09 +03:00
<!--Delete sections as needed --> ## Description Vendored changes to AI Governance OpenAPI spec, which adds L7 HTTP rules. Once the associated PR merges, sync again. https://deploy-preview-26240--docsdocker.netlify.app/reference/api/ai-governance/latest/ ## Related issues or tickets https://github.com/docker/governor-services/pull/836 ## Reviews <!-- Notes for reviewers here --> <!-- List applicable reviews (optionally @tag reviewers) --> - [ ] Technical review - [ ] Editorial review - [ ] Product review Signed-off-by: Craig Osterhout <craig.osterhout@docker.com>
1156 lines
40 KiB
YAML
1156 lines
40 KiB
YAML
openapi: 3.2.0
|
|
jsonSchemaDialect: https://spec.openapis.org/oas/3.1/dialect/base
|
|
|
|
info:
|
|
title: Docker AI Governance Policy API
|
|
version: "1"
|
|
description: |
|
|
HTTP+JSON API for managing Docker governance policies and rules.
|
|
|
|
**Resource model.** An organization owns one or more policies. Each policy
|
|
contains a list of rules grouped into a single domain: either `network` or
|
|
`filesystem`. A policy's domain is derived from its rule actions; mixing
|
|
domains within a single policy is not permitted.
|
|
|
|
**Lifecycle.** Create a policy with CreatePolicy, then add rules with
|
|
CreateRule. Rules can be updated in place with UpdateRule or removed with
|
|
DeleteRule. Deleting all rules does not delete the policy itself.
|
|
|
|
**Rule evaluation.** All rules in a policy are tested against every request.
|
|
`deny` always wins: if any rule matches with `decision: deny`, the request
|
|
is denied regardless of any `allow` rules.
|
|
|
|
**Enforcement.** Organization policies take precedence over local sandbox
|
|
policies and cannot be overridden by individual users.
|
|
|
|
**Propagation.** Policy changes take up to five minutes to reach developer
|
|
machines after being written.
|
|
|
|
See the [AI Governance documentation](https://docs.docker.com/ai/sandboxes/governance/)
|
|
for product documentation.
|
|
contact:
|
|
name: Docker
|
|
url: https://www.docker.com/products/ai-governance/
|
|
|
|
tags:
|
|
- name: policies
|
|
summary: Policies
|
|
kind: nav
|
|
description: Policy lifecycle management
|
|
- name: rules
|
|
summary: Rules
|
|
kind: nav
|
|
description: Rule management within an allowlist policy
|
|
|
|
servers:
|
|
- url: https://hub.docker.com/v2
|
|
|
|
security:
|
|
- bearerAuth: []
|
|
|
|
paths:
|
|
/orgs/{org_name}/governance/policies:
|
|
parameters:
|
|
- $ref: "#/components/parameters/OrgName"
|
|
get:
|
|
operationId: listPolicies
|
|
tags: [policies]
|
|
summary: List policies
|
|
description: >
|
|
Returns a shallow summary of the organization's policies, one page at a time.
|
|
The rule set is not included; use GetPolicy to fetch the full object.
|
|
|
|
|
|
Results are paginated with an opaque cursor. Pass `page_size` to bound
|
|
the page; if more policies remain, the response includes a non-null
|
|
`next_page_token` to pass as `page_token` on the next request. Iterate
|
|
until `next_page_token` is `null`. Treat the token as opaque; do not
|
|
parse or construct it.
|
|
parameters:
|
|
- name: page_size
|
|
in: query
|
|
required: false
|
|
description: >
|
|
Maximum number of policies to return. Defaults to 100 if omitted or
|
|
zero. The server caps values above 100 at 100.
|
|
schema:
|
|
type: integer
|
|
minimum: 0
|
|
default: 100
|
|
- name: page_token
|
|
in: query
|
|
required: false
|
|
description: >
|
|
Opaque cursor from a previous response's `next_page_token`. Omit to
|
|
fetch the first page.
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Object wrapping an array of policy summaries under `data` and a `next_page_token`, which is null on the last page. Rule sets are not included; use GetPolicy to fetch a full policy.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data, next_page_token]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/PolicySummary"
|
|
next_page_token:
|
|
type: [string, "null"]
|
|
description: >
|
|
The opaque cursor for the next page, or `null` on the last page.
|
|
example: AQpteyJQSyI6Im15LW9yZyIsIlNLIjoicG9saWN5I3BvbF8ifQ
|
|
examples:
|
|
default:
|
|
value:
|
|
data:
|
|
- id: pol_06evsmp24r1pg71cm8500546pkbn
|
|
name: "Security Research — hardened"
|
|
org: my-org
|
|
scope:
|
|
teams: [d290f1ee-6c54-4b01-90e6-d701748f0851]
|
|
created_at: "2026-04-22T00:00:00Z"
|
|
updated_at: "2026-04-22T00:00:00Z"
|
|
type: allowlist_v0
|
|
next_page_token: AQpteyJQSyI6Im15LW9yZyIsIlNLIjoicG9saWN5I3BvbF8ifQ
|
|
"400":
|
|
$ref: "#/components/responses/InvalidArgument"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthenticated"
|
|
"403":
|
|
$ref: "#/components/responses/PermissionDenied"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
post:
|
|
operationId: createPolicy
|
|
tags: [policies]
|
|
summary: Create policy
|
|
description: >
|
|
Creates a new policy with an empty rule set. Rules are added separately
|
|
via the rules sub-resource.
|
|
requestBody:
|
|
description: Policy name and optional scope.
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreatePolicyRequest"
|
|
examples:
|
|
default:
|
|
value:
|
|
name: "Security Research — hardened"
|
|
scope:
|
|
teams: [d290f1ee-6c54-4b01-90e6-d701748f0851]
|
|
responses:
|
|
"201":
|
|
description: Policy created. Returns the new policy without its rule set.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Policy"
|
|
examples:
|
|
default:
|
|
value:
|
|
id: pol_06evsmp24r1pg71cm8500546pkbn
|
|
name: "Security Research — hardened"
|
|
org: my-org
|
|
scope:
|
|
teams: [d290f1ee-6c54-4b01-90e6-d701748f0851]
|
|
created_at: "2026-04-22T00:00:00Z"
|
|
updated_at: "2026-04-22T00:00:00Z"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidArgument"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthenticated"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/orgs/{org_name}/governance/policies/{policy_id}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/OrgName"
|
|
- $ref: "#/components/parameters/PolicyID"
|
|
get:
|
|
operationId: getPolicy
|
|
tags: [policies]
|
|
summary: Get policy
|
|
description: Returns the full policy including its `allowlist_v0` rule set.
|
|
responses:
|
|
"200":
|
|
description: Full policy including its `allowlist_v0` rule set.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Policy"
|
|
examples:
|
|
default:
|
|
value:
|
|
id: pol_06evsmp24r1pg71cm8500546pkbn
|
|
name: "Security Research — hardened"
|
|
org: my-org
|
|
scope:
|
|
teams: [d290f1ee-6c54-4b01-90e6-d701748f0851]
|
|
created_at: "2026-04-22T00:00:00Z"
|
|
updated_at: "2026-04-22T00:00:00Z"
|
|
allowlist_v0:
|
|
domain: network
|
|
rules:
|
|
- id: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org, cve.mitre.org]
|
|
decision: allow
|
|
"401":
|
|
$ref: "#/components/responses/Unauthenticated"
|
|
"403":
|
|
$ref: "#/components/responses/PermissionDenied"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
patch:
|
|
operationId: updatePolicy
|
|
tags: [policies]
|
|
summary: Update policy
|
|
description: |
|
|
Partially updates a policy's metadata. Only fields present in the
|
|
request body are updated; absent fields are left unchanged. The `scope`
|
|
object is patched per sub-field: sending `teams` replaces that list,
|
|
while an omitted sub-field is left untouched and an empty list clears
|
|
it (org-wide).
|
|
|
|
The rule set is not modified here. Use the rule endpoints for that.
|
|
At least one field must be present. Returns the policy in both its old
|
|
and new states. Changes may take up to five minutes to reach developer
|
|
machines.
|
|
requestBody:
|
|
description: Fields to update. Absent fields are left unchanged.
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdatePolicyRequest"
|
|
examples:
|
|
rename:
|
|
summary: Rename the policy
|
|
value:
|
|
name: Security Research
|
|
scope:
|
|
summary: Restrict to a team
|
|
value:
|
|
scope:
|
|
teams: [d290f1ee-6c54-4b01-90e6-d701748f0851]
|
|
responses:
|
|
"200":
|
|
description: Policy updated, returns old and new states.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdatePolicyResponse"
|
|
examples:
|
|
default:
|
|
value:
|
|
old:
|
|
id: pol_06evsmp24r1pg71cm8500546pkbn
|
|
name: "Security Research — hardened"
|
|
org: my-org
|
|
scope:
|
|
teams: [d290f1ee-6c54-4b01-90e6-d701748f0851]
|
|
created_at: "2026-04-22T00:00:00Z"
|
|
updated_at: "2026-04-22T00:00:00Z"
|
|
allowlist_v0:
|
|
domain: network
|
|
rules:
|
|
- id: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org, cve.mitre.org]
|
|
decision: allow
|
|
new:
|
|
id: pol_06evsmp24r1pg71cm8500546pkbn
|
|
name: Security Research
|
|
org: my-org
|
|
scope:
|
|
teams: [d290f1ee-6c54-4b01-90e6-d701748f0851]
|
|
created_at: "2026-04-22T00:00:00Z"
|
|
updated_at: "2026-04-22T10:00:00Z"
|
|
allowlist_v0:
|
|
domain: network
|
|
rules:
|
|
- id: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org, cve.mitre.org]
|
|
decision: allow
|
|
"400":
|
|
$ref: "#/components/responses/InvalidArgument"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthenticated"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
delete:
|
|
operationId: deletePolicy
|
|
tags: [policies]
|
|
summary: Delete policy
|
|
description: |
|
|
Permanently deletes the policy and its rule set. Returns the deleted
|
|
policy as a courtesy; its `updated_at` is unchanged by the deletion.
|
|
Changes may take up to five minutes to reach developer machines.
|
|
responses:
|
|
"200":
|
|
description: Policy deleted, returns the deleted policy.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DeletePolicyResponse"
|
|
examples:
|
|
default:
|
|
value:
|
|
deleted:
|
|
id: pol_06evsmp24r1pg71cm8500546pkbn
|
|
name: "Security Research — hardened"
|
|
org: my-org
|
|
scope:
|
|
teams: [d290f1ee-6c54-4b01-90e6-d701748f0851]
|
|
created_at: "2026-04-22T00:00:00Z"
|
|
updated_at: "2026-04-22T00:00:00Z"
|
|
allowlist_v0:
|
|
domain: network
|
|
rules:
|
|
- id: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org, cve.mitre.org]
|
|
decision: allow
|
|
"401":
|
|
$ref: "#/components/responses/Unauthenticated"
|
|
"403":
|
|
$ref: "#/components/responses/PermissionDenied"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/orgs/{org_name}/governance/policies/{policy_id}/rules:
|
|
parameters:
|
|
- $ref: "#/components/parameters/OrgName"
|
|
- $ref: "#/components/parameters/PolicyID"
|
|
post:
|
|
operationId: createRule
|
|
tags: [rules]
|
|
summary: Create rule
|
|
description: |
|
|
Adds a rule to the policy's rule set. All rules in a policy must share
|
|
the same domain (`network`, which includes HTTP, or `filesystem`);
|
|
mixing domains is rejected. A single rule cannot mix L4 network and L7
|
|
HTTP actions.
|
|
|
|
**Network** actions: `connect:tcp`, `connect:udp`. Resources are
|
|
hostnames (for example, `example.com`), wildcard subdomains (`*.example.com`
|
|
for one level, `**.example.com` for any depth), hostnames with an optional
|
|
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** actions: `read`, `write`. Resources are paths (for example,
|
|
`/data`). Use `*` to match within a single path segment and `**` to match
|
|
recursively across segments (for example, `/data/**`).
|
|
|
|
**HTTP** actions identify request methods, such as `request:get` and
|
|
`request:post`. Use `http_resources` to identify the host, optional port,
|
|
and absolute path glob. HTTP rules must not supply `resources`.
|
|
|
|
Changes may take up to five minutes to reach developer machines.
|
|
requestBody:
|
|
description: Rule definition including actions, matching resources, and decision.
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateRuleRequest"
|
|
examples:
|
|
network:
|
|
summary: Network rule
|
|
value:
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org, cve.mitre.org]
|
|
decision: allow
|
|
filesystem:
|
|
summary: Filesystem rule
|
|
value:
|
|
name: allow data directory
|
|
actions: [read, write]
|
|
resources: [/data]
|
|
decision: allow
|
|
http:
|
|
summary: HTTP rule
|
|
value:
|
|
name: read GitHub repositories
|
|
actions: [request:get, request:head]
|
|
http_resources:
|
|
- host: api.github.com
|
|
port: 443
|
|
path: /repos/docker/**
|
|
decision: allow
|
|
responses:
|
|
"201":
|
|
description: Rule created and added to the policy's rule set.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Rule"
|
|
examples:
|
|
network:
|
|
summary: Network rule
|
|
value:
|
|
id: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org, cve.mitre.org]
|
|
decision: allow
|
|
filesystem:
|
|
summary: Filesystem rule
|
|
value:
|
|
id: rule_07fwtnr0kn2qetl1b9olfbyz8kob
|
|
name: allow data directory
|
|
actions: [read, write]
|
|
resources: [/data]
|
|
decision: allow
|
|
http:
|
|
summary: HTTP rule
|
|
value:
|
|
id: rule_08gxuos1lo3rfum2c0pmgcz09lpc
|
|
name: read GitHub repositories
|
|
actions: [request:get, request:head]
|
|
http_resources:
|
|
- host: api.github.com
|
|
port: 443
|
|
path: /repos/docker/**
|
|
decision: allow
|
|
"400":
|
|
$ref: "#/components/responses/InvalidArgument"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthenticated"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/orgs/{org_name}/governance/policies/{policy_id}/rules/{rule_id}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/OrgName"
|
|
- $ref: "#/components/parameters/PolicyID"
|
|
- $ref: "#/components/parameters/RuleID"
|
|
patch:
|
|
operationId: updateRule
|
|
tags: [rules]
|
|
summary: Update rule
|
|
description: |
|
|
Partially updates a rule. Only fields present in the request body are
|
|
updated; absent fields are left unchanged. Returns the rule in both its
|
|
old and new states.
|
|
|
|
Changing `actions` across domains (for example, from network actions to
|
|
filesystem actions) is rejected while other rules remain in the policy.
|
|
When changing a rule between L4 network and L7 HTTP, supply the matching
|
|
`resources` or `http_resources` in the same request. Changes may take up
|
|
to five minutes to reach developer machines.
|
|
requestBody:
|
|
description: Fields to update. Absent fields are left unchanged.
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdateRuleRequest"
|
|
examples:
|
|
default:
|
|
value:
|
|
resources: ["research.mitre.org"]
|
|
responses:
|
|
"200":
|
|
description: Rule updated, returns old and new states.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdateRuleResponse"
|
|
examples:
|
|
default:
|
|
value:
|
|
old:
|
|
id: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org, cve.mitre.org]
|
|
decision: allow
|
|
new:
|
|
id: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org]
|
|
decision: allow
|
|
"400":
|
|
$ref: "#/components/responses/InvalidArgument"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthenticated"
|
|
"403":
|
|
$ref: "#/components/responses/PermissionDenied"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
delete:
|
|
operationId: deleteRule
|
|
tags: [rules]
|
|
summary: Delete rule
|
|
description: |
|
|
Deletes a rule from the policy. Returns the deleted rule. Changes may
|
|
take up to five minutes to reach developer machines.
|
|
responses:
|
|
"200":
|
|
description: Rule deleted, returns the deleted rule.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DeleteRuleResponse"
|
|
examples:
|
|
default:
|
|
value:
|
|
deleted:
|
|
id: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name: allow research mirrors
|
|
actions: [connect:tcp, connect:udp]
|
|
resources: [research.mitre.org, cve.mitre.org]
|
|
decision: allow
|
|
"401":
|
|
$ref: "#/components/responses/Unauthenticated"
|
|
"403":
|
|
$ref: "#/components/responses/PermissionDenied"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: |
|
|
Short-lived JWT obtained by exchanging Docker Hub credentials at
|
|
`POST https://hub.docker.com/v2/auth/token`. Pass the JWT in the
|
|
`Authorization: Bearer <token>` header. Tokens expire after a short
|
|
period; request a fresh one when you receive a `401`.
|
|
|
|
The `password` field of the token request accepts any of the following
|
|
credential types:
|
|
|
|
| Type | Format | Notes |
|
|
|------|--------|-------|
|
|
| Password | Plain text | Your Docker Hub account password. |
|
|
| Personal Access Token (PAT) | `dckr_pat_*` | Recommended over passwords. Create one under Account Settings → Security. |
|
|
| Organization Access Token (OAT) | `dckr_oat_*` | Scoped to an organization. Create one under Organization Settings → Access Tokens. |
|
|
|
|
PAT and OAT strings can't be used directly as a bearer token. They must
|
|
be exchanged at the token endpoint first.
|
|
|
|
See [Docker Hub authentication](https://docs.docker.com/reference/api/hub/latest/operations/AuthCreateAccessToken/)
|
|
for full details.
|
|
|
|
parameters:
|
|
OrgName:
|
|
name: org_name
|
|
in: path
|
|
required: true
|
|
description: Docker Hub organization name.
|
|
schema:
|
|
type: string
|
|
examples:
|
|
default:
|
|
value: my-org
|
|
|
|
PolicyID:
|
|
name: policy_id
|
|
in: path
|
|
required: true
|
|
description: Unique policy identifier.
|
|
schema:
|
|
type: string
|
|
examples:
|
|
default:
|
|
value: pol_06evsmp24r1pg71cm8500546pkbn
|
|
|
|
RuleID:
|
|
name: rule_id
|
|
in: path
|
|
required: true
|
|
description: Unique rule identifier within the policy.
|
|
schema:
|
|
type: string
|
|
examples:
|
|
default:
|
|
value: rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
|
|
schemas:
|
|
PolicySummary:
|
|
type: object
|
|
description: Shallow policy representation returned by ListPolicies. Excludes the rule set.
|
|
required: [id, name, org, scope, created_at, updated_at, type]
|
|
properties:
|
|
id:
|
|
type: string
|
|
examples:
|
|
- pol_06evsmp24r1pg71cm8500546pkbn
|
|
name:
|
|
type: string
|
|
description: Human-readable label, unique within the organization.
|
|
examples:
|
|
- "Security Research — hardened"
|
|
org:
|
|
type: string
|
|
examples:
|
|
- my-org
|
|
scope:
|
|
$ref: "#/components/schemas/Scope"
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
examples:
|
|
- "2026-04-22T00:00:00Z"
|
|
updated_at:
|
|
type: string
|
|
format: date-time
|
|
examples:
|
|
- "2026-04-22T00:00:00Z"
|
|
type:
|
|
type: string
|
|
description: >
|
|
Identifies the policy type. `allowlist_v0` for network, HTTP, and
|
|
filesystem allowlist policies; `cedar_v1` for Cedar language policies.
|
|
enum: [allowlist_v0, cedar_v1]
|
|
examples:
|
|
- allowlist_v0
|
|
|
|
Policy:
|
|
type: object
|
|
description: >
|
|
Full policy representation. Exactly one of `allowlist_v0` or `cedar_v1`
|
|
is present, depending on the policy type.
|
|
required: [id, name, org, scope, created_at, updated_at]
|
|
properties:
|
|
id:
|
|
type: string
|
|
examples:
|
|
- pol_06evsmp24r1pg71cm8500546pkbn
|
|
name:
|
|
type: string
|
|
description: Human-readable label, unique within the organization.
|
|
examples:
|
|
- "Security Research — hardened"
|
|
org:
|
|
type: string
|
|
examples:
|
|
- my-org
|
|
scope:
|
|
$ref: "#/components/schemas/Scope"
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
examples:
|
|
- "2026-04-22T00:00:00Z"
|
|
updated_at:
|
|
type: string
|
|
format: date-time
|
|
examples:
|
|
- "2026-04-22T00:00:00Z"
|
|
allowlist_v0:
|
|
$ref: "#/components/schemas/AllowlistV0"
|
|
cedar_v1:
|
|
$ref: "#/components/schemas/CedarV1Policy"
|
|
|
|
Scope:
|
|
type: object
|
|
description: Restricts the policy to specific teams. An empty or absent list means the policy applies org-wide.
|
|
properties:
|
|
teams:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Team IDs the policy applies to. Each must be a valid team in the organization.
|
|
examples:
|
|
- ["d290f1ee-6c54-4b01-90e6-d701748f0851"]
|
|
|
|
AllowlistV0:
|
|
type: object
|
|
description: |
|
|
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`.
|
|
required: [rules]
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: >
|
|
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.
|
|
enum: [network, filesystem]
|
|
examples:
|
|
- network
|
|
rules:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Rule"
|
|
|
|
CedarV1Policy:
|
|
type: object
|
|
description: >
|
|
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.
|
|
required: [text, schema_url]
|
|
properties:
|
|
text:
|
|
type: string
|
|
description: >
|
|
One or more Cedar `permit` or `forbid` statements. Must be
|
|
syntactically valid Cedar and must not carry an `@id` annotation
|
|
(IDs are server-assigned).
|
|
examples:
|
|
- 'permit(principal, action == MCP::Action::"call_tool", resource is MCP::Tool);'
|
|
schema_url:
|
|
type: string
|
|
description: >
|
|
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.
|
|
examples:
|
|
- "https://schemas.docker.com/policy/cedar/v1/mcp/v0"
|
|
|
|
Rule:
|
|
type: object
|
|
description: A single allow or deny rule within an allowlist policy.
|
|
required: [id, name, actions, decision]
|
|
oneOf:
|
|
- type: object
|
|
required: [resources]
|
|
- type: object
|
|
required: [http_resources]
|
|
properties:
|
|
id:
|
|
type: string
|
|
examples:
|
|
- rule_06evsm9qjm1pdsk0a8nkfaxy7jna
|
|
name:
|
|
type: string
|
|
description: Human-readable label for the rule.
|
|
examples:
|
|
- allow research mirrors
|
|
actions:
|
|
$ref: "#/components/schemas/RuleActions"
|
|
resources:
|
|
$ref: "#/components/schemas/RuleResources"
|
|
http_resources:
|
|
$ref: "#/components/schemas/HTTPResources"
|
|
decision:
|
|
$ref: "#/components/schemas/RuleDecision"
|
|
|
|
CreatePolicyRequest:
|
|
type: object
|
|
description: >
|
|
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.
|
|
required: [name]
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Policy name, unique within the organization.
|
|
examples:
|
|
- "Security Research — hardened"
|
|
scope:
|
|
$ref: "#/components/schemas/Scope"
|
|
cedar_v1:
|
|
$ref: "#/components/schemas/CedarV1Policy"
|
|
|
|
CreateRuleRequest:
|
|
type: object
|
|
description: Fields required to create a new rule within a policy's rule set.
|
|
required: [name, actions, decision]
|
|
oneOf:
|
|
- type: object
|
|
required: [resources]
|
|
- type: object
|
|
required: [http_resources]
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Human-readable label for the rule.
|
|
examples:
|
|
- allow research mirrors
|
|
actions:
|
|
$ref: "#/components/schemas/RuleActions"
|
|
resources:
|
|
$ref: "#/components/schemas/RuleResources"
|
|
http_resources:
|
|
$ref: "#/components/schemas/HTTPResources"
|
|
decision:
|
|
$ref: "#/components/schemas/RuleDecision"
|
|
|
|
UpdateRuleRequest:
|
|
type: object
|
|
description: Partial update. Only fields present in the body are updated; absent fields are left unchanged.
|
|
not:
|
|
type: object
|
|
required: [resources, http_resources]
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Human-readable label for the rule.
|
|
examples:
|
|
- allow research mirrors
|
|
actions:
|
|
$ref: "#/components/schemas/RuleActions"
|
|
resources:
|
|
$ref: "#/components/schemas/RuleResources"
|
|
http_resources:
|
|
$ref: "#/components/schemas/HTTPResources"
|
|
decision:
|
|
$ref: "#/components/schemas/RuleDecision"
|
|
|
|
UpdateRuleResponse:
|
|
type: object
|
|
description: The rule state before and after the update.
|
|
required: [old, new]
|
|
properties:
|
|
old:
|
|
$ref: "#/components/schemas/Rule"
|
|
new:
|
|
$ref: "#/components/schemas/Rule"
|
|
|
|
DeleteRuleResponse:
|
|
type: object
|
|
description: The deleted rule.
|
|
required: [deleted]
|
|
properties:
|
|
deleted:
|
|
$ref: "#/components/schemas/Rule"
|
|
|
|
UpdatePolicyRequest:
|
|
type: object
|
|
description: >
|
|
Partial update of a policy. Only fields present in the body are updated;
|
|
absent fields are left unchanged. At least one field must be present.
|
|
For `cedar_v1` policies, supply `cedar_v1` to replace the policy text;
|
|
`name` and `scope` may be combined freely.
|
|
properties:
|
|
name:
|
|
type: string
|
|
minLength: 1
|
|
description: Policy name, unique within the organization.
|
|
examples:
|
|
- Security Research
|
|
scope:
|
|
$ref: "#/components/schemas/ScopePatch"
|
|
cedar_v1:
|
|
$ref: "#/components/schemas/CedarV1Policy"
|
|
|
|
ScopePatch:
|
|
type: object
|
|
description: >
|
|
Per-sub-field patch of a policy's scope. An omitted sub-field is left
|
|
unchanged; a present list replaces that dimension, and an empty list
|
|
clears it (making the policy org-wide for that dimension).
|
|
properties:
|
|
teams:
|
|
type: array
|
|
items:
|
|
type: string
|
|
examples:
|
|
- ["d290f1ee-6c54-4b01-90e6-d701748f0851"]
|
|
|
|
UpdatePolicyResponse:
|
|
type: object
|
|
description: The full policy before and after the update.
|
|
required: [old, new]
|
|
properties:
|
|
old:
|
|
$ref: "#/components/schemas/Policy"
|
|
new:
|
|
$ref: "#/components/schemas/Policy"
|
|
|
|
DeletePolicyResponse:
|
|
type: object
|
|
description: The full deleted policy.
|
|
required: [deleted]
|
|
properties:
|
|
deleted:
|
|
$ref: "#/components/schemas/Policy"
|
|
|
|
RuleActions:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum:
|
|
- connect:tcp
|
|
- connect:udp
|
|
- read
|
|
- write
|
|
- request:get
|
|
- request:post
|
|
- request:put
|
|
- request:delete
|
|
- request:patch
|
|
- request:head
|
|
- request:options
|
|
- request:connect
|
|
- request:trace
|
|
minItems: 1
|
|
description: >
|
|
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.
|
|
examples:
|
|
- ["connect:tcp", "connect:udp"]
|
|
|
|
RuleResources:
|
|
type: array
|
|
items:
|
|
type: string
|
|
minItems: 1
|
|
description: >
|
|
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.
|
|
examples:
|
|
- ["research.mitre.org", "cve.mitre.org"]
|
|
|
|
HTTPResources:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
$ref: "#/components/schemas/HTTPResource"
|
|
description: >
|
|
HTTP request targets. Required for HTTP rules and forbidden for network
|
|
and filesystem rules. A request matches when any target matches.
|
|
|
|
HTTPResource:
|
|
type: object
|
|
required: [host, path]
|
|
properties:
|
|
host:
|
|
type: string
|
|
minLength: 1
|
|
description: >
|
|
Domain name or domain glob without a URL scheme or port. Use the
|
|
separate `port` field to restrict the target to one port.
|
|
examples:
|
|
- api.github.com
|
|
- "*.example.com"
|
|
port:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 65535
|
|
description: Optional destination port. Omit it to match every port.
|
|
examples:
|
|
- 443
|
|
path:
|
|
type: string
|
|
pattern: ^/
|
|
description: >
|
|
Absolute HTTP path glob. `*` matches one segment and `**` matches
|
|
any depth, including the bare path.
|
|
examples:
|
|
- /repos/docker/**
|
|
|
|
RuleDecision:
|
|
type: string
|
|
enum: [allow, deny]
|
|
description: >
|
|
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`.
|
|
examples:
|
|
- allow
|
|
|
|
Error:
|
|
type: object
|
|
description: Error envelope returned on all non-2xx responses.
|
|
required: [error]
|
|
properties:
|
|
error:
|
|
type: object
|
|
description: Error detail.
|
|
required: [code, message]
|
|
examples:
|
|
- code: not_found
|
|
message: policy not found
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: >
|
|
Machine-readable error code. `not_found`: the requested resource
|
|
does not exist, the org does not exist, or the caller is not a
|
|
member of the organization (the organization's existence is not revealed to callers
|
|
who cannot access it). `conflict`: a resource with the same name
|
|
already exists. `invalid_argument`: the request body is malformed
|
|
or fails validation. `unauthenticated`: missing or invalid
|
|
credentials. `permission_denied`: the org is not entitled to use
|
|
governance. `limit_exceeded`: the org has reached its maximum
|
|
number of policies, or the policy has reached its maximum number
|
|
of rules. `unimplemented`: the endpoint or feature is not yet
|
|
available. `internal`: unexpected server error.
|
|
enum:
|
|
- not_found
|
|
- conflict
|
|
- invalid_argument
|
|
- unauthenticated
|
|
- permission_denied
|
|
- limit_exceeded
|
|
- unimplemented
|
|
- internal
|
|
message:
|
|
type: string
|
|
|
|
responses:
|
|
NotFound:
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
examples:
|
|
default:
|
|
value:
|
|
error:
|
|
code: not_found
|
|
message: policy not found
|
|
|
|
Conflict:
|
|
description: Conflict
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
examples:
|
|
default:
|
|
value:
|
|
error:
|
|
code: conflict
|
|
message: policy name already in use
|
|
|
|
InvalidArgument:
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
examples:
|
|
default:
|
|
value:
|
|
error:
|
|
code: invalid_argument
|
|
message: "name is required"
|
|
|
|
Unauthenticated:
|
|
description: Missing or invalid credentials
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
examples:
|
|
default:
|
|
value:
|
|
error:
|
|
code: unauthenticated
|
|
message: unauthenticated
|
|
|
|
PermissionDenied:
|
|
description: >
|
|
Caller lacks the required permission for this org, or the org is not
|
|
entitled to use governance.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
examples:
|
|
default:
|
|
value:
|
|
error:
|
|
code: permission_denied
|
|
message: permission denied
|
|
|
|
Forbidden:
|
|
description: >
|
|
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.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
examples:
|
|
permission_denied:
|
|
value:
|
|
error:
|
|
code: permission_denied
|
|
message: permission denied
|
|
limit_exceeded:
|
|
value:
|
|
error:
|
|
code: limit_exceeded
|
|
message: organization has reached the maximum of 100 policies
|
|
|
|
InternalError:
|
|
description: Internal server error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
examples:
|
|
default:
|
|
value:
|
|
error:
|
|
code: internal
|
|
message: internal error
|