ab079c
% CONTAINERS-POLICY.JSON(5) policy.json Man Page
ab079c
% Miloslav Trmač
ab079c
% September 2016
ab079c
ab079c
# NAME
ab079c
containers-policy.json - syntax for the signature verification policy file
ab079c
ab079c
## DESCRIPTION
ab079c
ab079c
Signature verification policy files are used to specify policy, e.g. trusted keys,
ab079c
applicable when deciding whether to accept an image, or individual signatures of that image, as valid.
ab079c
ab079c
The default policy is stored (unless overridden at compile-time) at `/etc/containers/policy.json`;
ab079c
applications performing verification may allow using a different policy instead.
ab079c
ab079c
## FORMAT
ab079c
ab079c
The signature verification policy file, usually called `policy.json`,
ab079c
uses a JSON format.  Unlike some other JSON files, its parsing is fairly strict:
ab079c
unrecognized, duplicated or otherwise invalid fields cause the entire file,
ab079c
and usually the entire operation, to be rejected.
ab079c
ab079c
The purpose of the policy file is to define a set of *policy requirements* for a container image,
ab079c
usually depending on its location (where it is being pulled from) or otherwise defined identity.
ab079c
ab079c
Policy requirements can be defined for:
ab079c
ab079c
- An individual *scope* in a *transport*.
ab079c
  The *transport* values are the same as the transport prefixes when pushing/pulling images (e.g. `docker:`, `atomic:`),
ab079c
  and *scope* values are defined by each transport; see below for more details.
ab079c
ab079c
  Usually, a scope can be defined to match a single image, and various prefixes of
ab079c
  such a most specific scope define namespaces of matching images.
ab079c
- A default policy for a single transport, expressed using an empty string as a scope
ab079c
- A global default policy.
ab079c
ab079c
If multiple policy requirements match a given image, only the requirements from the most specific match apply,
ab079c
the more general policy requirements definitions are ignored.
ab079c
ab079c
This is expressed in JSON using the top-level syntax
ab079c
```js
ab079c
{
ab079c
    "default": [/* policy requirements: global default */]
ab079c
    "transports": {
ab079c
        transport_name: {
ab079c
            "": [/* policy requirements: default for transport $transport_name */],
ab079c
            scope_1: [/* policy requirements: default for $scope_1 in $transport_name */],
ab079c
            scope_2: [/*…*/]
ab079c
            /*…*/
ab079c
        },
ab079c
        transport_name_2: {/*…*/}
ab079c
        /*…*/
ab079c
    }
ab079c
}
ab079c
```
ab079c
ab079c
The global `default` set of policy requirements is mandatory; all of the other fields
ab079c
(`transports` itself, any specific transport, the transport-specific default, etc.) are optional.
ab079c
ab079c
ab079c
## Supported transports and their scopes
ab079c
ab079c
### `atomic:`
ab079c
ab079c
The `atomic:` transport refers to images in an Atomic Registry.
ab079c
ab079c
Supported scopes use the form _hostname_[`:`_port_][`/`_namespace_[`/`_imagestream_ [`:`_tag_]]],
ab079c
i.e. either specifying a complete name of a tagged image, or prefix denoting
ab079c
a host/namespace/image stream.
ab079c
ab079c
*Note:* The _hostname_ and _port_ refer to the Docker registry host and port (the one used
ab079c
e.g. for `docker pull`), _not_ to the OpenShift API host and port.
ab079c
ab079c
### `dir:`
ab079c
ab079c
The `dir:` transport refers to images stored in local directories.
ab079c
ab079c
Supported scopes are paths of directories (either containing a single image or
ab079c
subdirectories possibly containing images).
ab079c
ab079c
*Note:* The paths must be absolute and contain no symlinks. Paths violating these requirements may be silently ignored.
ab079c
ab079c
The top-level scope `"/"` is forbidden; use the transport default scope `""`,
ab079c
for consistency with other transports.
ab079c
ab079c
### `docker:`
ab079c
ab079c
The `docker:` transport refers to images in a registry implementing the "Docker Registry HTTP API V2".
ab079c
ab079c
Scopes matching individual images are named Docker references *in the fully expanded form*, either
ab079c
using a tag or digest. For example, `docker.io/library/busybox:latest` (*not* `busybox:latest`).
ab079c
ab079c
More general scopes are prefixes of individual-image scopes, and specify a repository (by omitting the tag or digest),
ab079c
a repository namespace, or a registry host (by only specifying the host name).
ab079c
ab079c
### `oci:`
ab079c
ab079c
The `oci:` transport refers to images in directories compliant with "Open Container Image Layout Specification".
ab079c
ab079c
Supported scopes use the form _directory_`:`_tag_, and _directory_ referring to
ab079c
a directory containing one or more tags, or any of the parent directories.
ab079c
ab079c
*Note:* See `dir:` above for semantics and restrictions on the directory paths, they apply to `oci:` equivalently.
ab079c
ab079c
### `tarball:`
ab079c
ab079c
The `tarball:` transport refers to tarred up container root filesystems.
ab079c
ab079c
Scopes are ignored.
ab079c
ab079c
## Policy Requirements
ab079c
ab079c
Using the mechanisms above, a set of policy requirements is looked up.  The policy requirements
ab079c
are represented as a JSON array of individual requirement objects.  For an image to be accepted,
ab079c
*all* of the requirements must be satisfied simulatenously.
ab079c
ab079c
The policy requirements can also be used to decide whether an individual signature is accepted (= is signed by a recognized key of a known author);
ab079c
in that case some requirements may apply only to some signatures, but each signature must be accepted by *at least one* requirement object.
ab079c
ab079c
The following requirement objects are supported:
ab079c
ab079c
### `insecureAcceptAnything`
ab079c
ab079c
A simple requirement with the following syntax
ab079c
ab079c
```json
ab079c
{"type":"insecureAcceptAnything"}
ab079c
```
ab079c
ab079c
This requirement accepts any image (but note that other requirements in the array still apply).
ab079c
ab079c
When deciding to accept an individual signature, this requirement does not have any effect; it does *not* cause the signature to be accepted, though.
ab079c
ab079c
This is useful primarily for policy scopes where no signature verification is required;
ab079c
because the array of policy requirements must not be empty, this requirement is used
ab079c
to represent the lack of requirements explicitly.
ab079c
ab079c
### `reject`
ab079c
ab079c
A simple requirement with the following syntax:
ab079c
ab079c
```json
ab079c
{"type":"reject"}
ab079c
```
ab079c
ab079c
This requirement rejects every image, and every signature.
ab079c
ab079c
### `signedBy`
ab079c
ab079c
This requirement requires an image to be signed with an expected identity, or accepts a signature if it is using an expected identity and key.
ab079c
ab079c
```js
ab079c
{
ab079c
    "type":    "signedBy",
ab079c
    "keyType": "GPGKeys", /* The only currently supported value */
ab079c
    "keyPath": "/path/to/local/keyring/file",
ab079c
    "keyData": "base64-encoded-keyring-data",
ab079c
    "signedIdentity": identity_requirement
ab079c
}
ab079c
```
ab079c
ab079c
ab079c
Exactly one of `keyPath` and `keyData` must be present, containing a GPG keyring of one or more public keys.  Only signatures made by these keys are accepted.
ab079c
ab079c
The `signedIdentity` field, a JSON object, specifies what image identity the signature claims about the image.
ab079c
One of the following alternatives are supported:
ab079c
ab079c
- The identity in the signature must exactly match the image identity.  Note that with this, referencing an image by digest (with a signature claiming a _repository_`:`_tag_ identity) will fail.
ab079c
ab079c
  ```json
ab079c
  {"type":"matchExact"}
ab079c
  ```
ab079c
- If the image identity carries a tag, the identity in the signature must exactly match;
ab079c
  if the image identity uses a digest reference, the identity in the signature must be in the same repository as the image identity (using any tag).
ab079c
ab079c
  (Note that with images identified using digest references, the digest from the reference is validated even before signature verification starts.)
ab079c
ab079c
  ```json
ab079c
  {"type":"matchRepoDigestOrExact"}
ab079c
  ```
ab079c
- The identity in the signature must be in the same repository as the image identity.  This is useful e.g. to pull an image using the `:latest` tag when the image is signed with a tag specifing an exact image version.
ab079c
ab079c
  ```json
ab079c
  {"type":"matchRepository"}
ab079c
  ```
ab079c
- The identity in the signature must exactly match a specified identity.
ab079c
  This is useful e.g. when locally mirroring images signed using their public identity.
ab079c
ab079c
  ```js
ab079c
  {
ab079c
      "type": "exactReference",
ab079c
      "dockerReference": docker_reference_value
ab079c
  }
ab079c
  ```
ab079c
- The identity in the signature must be in the same repository as a specified identity.
ab079c
  This combines the properties of `matchRepository` and `exactReference`.
ab079c
ab079c
  ```js
ab079c
  {
ab079c
      "type": "exactRepository",
ab079c
      "dockerRepository": docker_repository_value
ab079c
  }
ab079c
  ```
ab079c
ab079c
If the `signedIdentity` field is missing, it is treated as `matchRepoDigestOrExact`.
ab079c
ab079c
*Note*: `matchExact`, `matchRepoDigestOrExact` and `matchRepository` can be only used if a Docker-like image identity is
ab079c
provided by the transport.  In particular, the `dir:` and `oci:` transports can be only
ab079c
used with `exactReference` or `exactRepository`.
ab079c
ab079c
ab079c
ab079c
## Examples
ab079c
ab079c
It is *strongly* recommended to set the `default` policy to `reject`, and then
ab079c
selectively allow individual transports and scopes as desired.
ab079c
ab079c
### A reasonably locked-down system
ab079c
ab079c
(Note that the `/*`…`*/` comments are not valid in JSON, and must not be used in real policies.)
ab079c
ab079c
```js
ab079c
{
ab079c
    "default": [{"type": "reject"}], /* Reject anything not explicitly allowed */
ab079c
    "transports": {
ab079c
        "docker": {
ab079c
            /* Allow installing images from a specific repository namespace, without cryptographic verification.
ab079c
               This namespace includes images like openshift/hello-openshift and openshift/origin. */
ab079c
            "docker.io/openshift": [{"type": "insecureAcceptAnything"}],
ab079c
            /* Similarly, allow installing the “official” busybox images.  Note how the fully expanded
ab079c
               form, with the explicit /library/, must be used. */
ab079c
            "docker.io/library/busybox": [{"type": "insecureAcceptAnything"}]
ab079c
            /* Other docker: images use the global default policy and are rejected */
ab079c
        },
ab079c
        "dir": {
ab079c
            "": [{"type": "insecureAcceptAnything"}] /* Allow any images originating in local directories */
ab079c
        },
ab079c
        "atomic": {
ab079c
            /* The common case: using a known key for a repository or set of repositories */
ab079c
            "hostname:5000/myns/official": [
ab079c
                {
ab079c
                    "type": "signedBy",
ab079c
                    "keyType": "GPGKeys",
ab079c
                    "keyPath": "/path/to/official-pubkey.gpg"
ab079c
                }
ab079c
            ],
ab079c
            /* A more complex example, for a repository which contains a mirror of a third-party product,
ab079c
               which must be signed-off by local IT */
ab079c
            "hostname:5000/vendor/product": [
ab079c
                { /* Require the image to be signed by the original vendor, using the vendor's repository location. */
ab079c
                    "type": "signedBy",
ab079c
                    "keyType": "GPGKeys",
ab079c
                    "keyPath": "/path/to/vendor-pubkey.gpg",
ab079c
                    "signedIdentity": {
ab079c
                        "type": "exactRepository",
ab079c
                        "dockerRepository": "vendor-hostname/product/repository"
ab079c
                    }
ab079c
                },
ab079c
                { /* Require the image to _also_ be signed by a local reviewer. */
ab079c
                    "type": "signedBy",
ab079c
                    "keyType": "GPGKeys",
ab079c
                    "keyPath": "/path/to/reviewer-pubkey.gpg"
ab079c
                }
ab079c
            ]
ab079c
        }
ab079c
    }
ab079c
}
ab079c
```
ab079c
ab079c
### Completely disable security, allow all images, do not trust any signatures
ab079c
ab079c
```json
ab079c
{
ab079c
    "default": [{"type": "insecureAcceptAnything"}]
ab079c
}
ab079c
```
ab079c
## SEE ALSO
ab079c
  atomic(1)
ab079c
ab079c
## HISTORY
ab079c
August 2018, Rename to containers-policy.json(5) by Valentin Rothberg <vrothberg@suse.com>
ab079c
ab079c
September 2016, Originally compiled by Miloslav Trmač <mitr@redhat.com>