CONTAINERS-POLICY.JSON(5) (NAME) containers-policy.json - (DESCRIPTION) ( ) (image) . $XDG_CONFIG_HOME/containers/policy.json ( $XDG_CONFIG_HOME $HOME/.config/containers/policy.json) /etc/containers/policy.json /usr/share/containers/policy.json. . CONTAINERS_POLICY_JSON . (FORMAT) policy.json JSON . JSON : . (policy requirements) ( pull ) . : o (scope) (transport). transport / (push/pull) ( docker: atomic:) scope . (namespaces) . o . o (global). . JSON (top-level) : { "default": [/* : */] "transports": { transport_name: { "": [/* : $transport_name */], scope_1: [/* : $scope_1 $transport_name */], scope_2: [/**/] /**/ }, transport_name_2: {/**/} /**/ } } default ( transports ) . (SUPPORTED TRANSPORTS AND THEIR SCOPES) containers-transports(5) . atomic: atomic: Atomic Registry . hostname[:port][/namespace[/imagestream [:tag]]] (tag) // (image stream) (wildcard) *. . *.example.com example*.*.com . : hostname port ( docker pull ) API OpenShift. containers-storage: [storage-specifier]image-scope . [storage-specifier] [graph-driver-name@graph-root] [overlay@/var/lib/containers/storage]. image-scope : - Docker (fully expanded) (tag) (digest). docker.io/library/busybox:latest ( busybox:latest) - / ( ) @image-id ( ) ( ) . : - [graph-driver-name@graph-root] - [graph-root] Podman Buildah (hard-coded) "push" policy.json . dir: dir: . ( ). : - (symlink) . . - "/" "" . docker: docker: "Docker Registry HTTP API V2" . Docker . docker.io/library/busybox:latest ( busybox:latest). ( ) ( ) *. ( ) . *.example.com example*.*.com . docker-archive: "" . docker-daemon: algo:digest ( ) "" . . docker.io/library/busybox:latest ( busybox:latest). ( ) ( ) *. ( ) . *.example.com example*.*.com . oci: oci: "Open Container Image Layout Specification" . ( OCI OCI ). (annotation) (reference) . : - . . - "/" "" . oci-archive: OCI ( ). reference . : - . . - "/" "" . sif: Singularity ( ). : - . . - "/" "" . tarball: tarball: (import) . "" . (POLICY REQUIREMENTS) . JSON . . (= ) . : insecureAcceptAnything : {"type":"insecureAcceptAnything"} ( ). . . reject : {"type":"reject"} . signedBy " (simple signing)" . { "type": "signedBy", "keyType": "GPGKeys", /* */ "keyPath": "/path/to/local/keyring/file", "keyPaths": ["/path/to/local/keyring/file1","/path/to/local/keyring/file2"], "keyData": "base64-encoded-keyring-data", "signedIdentity": identity_requirement } keyPath keyPaths keyData (keyring) GPG . . signedIdentity JSON . : o . ( repository:tag ) . {"type":"matchExact"} o (tag) ( ). ( .) {"type":"matchRepoDigestOrExact"} o . :latest . {"type":"matchRepository"} o . (local mirroring) . { "type": "exactReference", "dockerReference": docker_reference_value } o . matchRepository exactReference . { "type": "exactRepository", "dockerRepository": docker_repository_value } o (Prefix remapping): " (signed prefix)" ( ) matchRepoDigestOrExact ( ). prefix signedPrefix host[:port] ( host[:port] ) ( tag/digest ) . docker.io/library/busybox ( busybox) docker.io/library ( ) docker.io/library/busybox==busybox. prefix signedBy . { "type": "remapIdentity", "prefix": prefix, "signedPrefix": prefix, } signedIdentity matchRepoDigestOrExact . : matchExact matchRepoDigestOrExact matchRepository . dir: oci: exactReference exactRepository . sigstoreSigned sigstore . { "type": "sigstoreSigned", "keyPath": "/path/to/local/public/key/file", "keyPaths": ["/path/to/first/public/key/one", "/path/to/first/public/key/two"], "keyData": "base64-encoded-public-key-data", "keyDatas": ["base64-encoded-public-key-one-data", "base64-encoded-public-key-two-data"] "fulcio": { "caPath": "/path/to/local/CA/file", "caData": "base64-encoded-CA-data", "oidcIssuer": "https://expected.OIDC.issuer/", "subjectEmail", "expected-signing-user@example.com", }, "pki": { "caRootsPath": "/path/to/local/CARoots/file", "caRootsData": "base64-encoded-CARoots-data", "caIntermediatesPath": "/path/to/local/CAIntermediates/file", "caIntermediatesData": "base64-encoded-CAIntermediates-data", "subjectHostname": "expected-signing-hostname.example.com", "subjectEmail": "expected-signing-user@example.com" }, "rekorPublicKeyPath": "/path/to/local/public/key/file", "rekorPublicKeyPaths": ["/path/to/local/public/key/one","/path/to/local/public/key/two"], "rekorPublicKeyData": "base64-encoded-public-key-data", "rekorPublicKeyDatas": ["base64-encoded-public-key-one-data","base64-encoded-public-key-two-data"], "signedIdentity": identity_requirement } keyPath keyPaths keyData keyDatas fulcio pki . keyPath keyData sigstore . . keyPaths keyDatas sigstore . . fulcio Fulcio . caPath caData Fulcio . oidcIssuer subjectEmail Fulcio . pki X.509 Fulcio . caRootsPath caRootsData (CA) . caIntermediatesPath caIntermediatesData CA . subjectEmail subjectHostname . rekorPublicKeyPath rekorPublicKeyPaths rekorPublicKeyData rekorPublicKeyDatas fulcio . Rekor Rekor " (signed entry timestamp)" ( ) Rekor . signedIdentity signedBy . cosign matchRepository exactRepository ( ). use-sigstore-attachments containers-registries.d(5) . (EXAMPLES) default reject . ( /**/ JSON .) { "default": [{"type": "reject"}], /* */ "transports": { "docker": { /* . openshift/hello-openshift openshift/origin . */ "docker.io/openshift": [{"type": "insecureAcceptAnything"}], /* "" busybox. /library/ . */ "docker.io/library/busybox": [{"type": "insecureAcceptAnything"}], /* */ "*.temporary-project.example.com": [{"type": "insecureAcceptAnything"}], /* sigstore */ "hostname:5000/myns/sigstore-signed-with-full-references": [ { "type": "sigstoreSigned", "keyPath": "/path/to/sigstore-pubkey.pub" } ], /* sigstore Fulcio+Rekor. : https://github.com/sigstore/sigstore/tree/main/pkg/tuf/repository/targets . */ "hostname:5000/myns/sigstore-signed-fulcio-rekor": [ { "type": "sigstoreSigned", "fulcio": { "caPath": "/path/to/fulcio_v1.crt.pem", "oidcIssuer": "https://github.com/login/oauth", "subjectEmail": "test-user@example.com" }, "rekorPublicKeyPath": "/path/to/rekor.pub", } ], /* Sigstore . */ "hostname:5000/myns/sigstore-signed-byopki": [ { "type": "sigstoreSigned", "pki": { "caRootsPath": "/path/to/pki_root_crts.pem", "caIntermediatesPath": "/path/to/pki_intermediate_crts.pem", "subjectHostname": "test-user.example.com" "subjectEmail": "test-user@example.com" } } ], /* sigstore /usr/bin/cosign */ "hostname:5000/myns/sigstore-signed-allows-malicious-tag-substitution": [ { "type": "sigstoreSigned", "keyPath": "/path/to/sigstore-pubkey.pub", "signedIdentity": {"type": "matchRepository"} } ], /* sigstore Fulcio+Rekor /usr/bin/cosign . : https://github.com/sigstore/sigstore/tree/main/pkg/tuf/repository/targets . */ "hostname:5000/myns/sigstore-signed-fulcio-rekor- allows-malicious-tag-substitution": [ { "type": "sigstoreSigned", "fulcio": { "caPath": "/path/to/fulcio_v1.crt.pem", "oidcIssuer": "https://github.com/login/oauth", "subjectEmail": "test-user@example.com" }, "rekorPublicKeyPath": "/path/to/rekor.pub", "signedIdentity": { "type": "matchRepository" } } ] /* :docker */ }, "dir": { "": [{"type": "insecureAcceptAnything"}] /* */ }, "atomic": { /* : */ "hostname:5000/myns/official": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/path/to/official-pubkey.gpg" } ], /* IT */ "hostname:5000/vendor/product": [ { /* . */ "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/path/to/vendor-pubkey.gpg", "signedIdentity": { "type": "exactRepository", "dockerRepository": "vendor-hostname/product/repository" } }, { /* __ . */ "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/path/to/reviewer-pubkey.gpg" } ], /* */ "private-mirror:5000/vendor-mirror": [ { /* . private-mirror:5000/vendor-mirror/productA/image1:latest vendor.example/productA/image1:latest . */ "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/path/to/vendor-pubkey.gpg", "signedIdentity": { "type": "remapIdentity", "prefix": "private-mirror:5000/vendor-mirror", "signedPrefix": "vendor.example.com" } } ] } } } { "default": [{"type": "insecureAcceptAnything"}] } (SEE ALSO) atomic(1), containers-transports(5), containers-registries.d(5) (HISTORY) containers- policy.json(5) Valentin Rothberg vrothberg@suse.com Miloslav Trmac mitr@redhat.com Parch Linux CONTAINERS-POLICY.JSON(5)