diff --git a/config/v1alpha1/0000_10_config-operator_01_imagepolicy.crd.yaml b/config/v1alpha1/0000_10_config-operator_01_imagepolicy.crd.yaml index 728c55a6ba1..7d67447f70e 100644 --- a/config/v1alpha1/0000_10_config-operator_01_imagepolicy.crd.yaml +++ b/config/v1alpha1/0000_10_config-operator_01_imagepolicy.crd.yaml @@ -37,63 +37,82 @@ spec: description: spec holds user settable values for configuration type: object required: - - images - policy + - scopes properties: - images: - description: 'images defines the list of images assigned to a policy. Each item refers to an image or repository in a registry implementing the "Docker Registry HTTP API V2". "images" uses one of the following scopes: - complete image name, either using a tag or digest - prefixes of individual-image scopes - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. For more information about the format, see the document about the docker transport field: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker' - type: array - items: - description: ImageScope is the item of the images list. - type: string - pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?/)?[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?)(?::([\w][\w.-]{0,127}))?(?:@([A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}))?$ - x-kubernetes-list-type: set policy: - description: policy defines the verification policy for the images in the images list + description: policy defines the verification policy for the items in the scopes list type: object properties: - fulcioCAData: - description: fulcioCAData contains inline base64 data for the fulcio CA certificate. - type: string - keyData: - description: keyData contains inline base64 data of the public key. keyData can be empty if the image got signed keyless. Requires oidcIssuer, subjectEmail, and fulcioCAData to be empty if keyData is set. - type: string - oidcIssuer: - description: 'oidcIssuer contains the expected OIDC issuer. Example: "https://expected.OIDC.issuer/" Required if fulcioCAData is set. subjectEmail must be set and keyData must be empty if oidcIssuer is set' - type: string - rekorKeyData: - description: rekorKeyData contains inline base64 data of the rekor public key. Required if fulcioCAData is set. - type: string - signedIdentity: - description: signedIdentity specifies what image identity the signature. claims about the image. + fulcioSubject: + description: fulcioSubject specifies OIDC issuer and the email of the fulcio authentication configuration. Required if rootOfTrust.fulcioCAData is set. type: object properties: - dockerRepository: - description: dockerReference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to "exactReference". + oidcIssuer: + description: 'oidcIssuer contains the expected OIDC issuer. Example: "https://expected.OIDC.issuer/" Required if rootOfTrust.fulcioCAData is set.' + type: string + signedEmail: + description: 'signedEmail holds the email address the the certificate is issued for. Example: "expected-signing-user@example.com" Required if rootOfTrust.fulcioCAData is set.' + type: string + rootOfTrust: + description: rootOfTrust specifies the public key, the Fulcio certificate and the Rekor public key. Requires only one of keyData or fulcioCAData must be set. + type: object + properties: + fulcioCAData: + description: fulcioCAData contains inline base64 data for the fulcio CA certificate. Requires only one of keyData and fulcioCAData must be set. + type: string + keyData: + description: keyData contains inline base64 data of the public key. keyData can be empty if the image got signed keyless. Requires only one of keyData and fulcioCAData must be set. type: string - identityMatchPolicy: - description: identityMatchPolicy set the type of matching to be used. Valid values are "MatchRepository", "ExactRepository". When omitted, the default value is "MatchRepoDigestOrExact". If set identityMatchPolicy to ExactRepository, then the dockerRepository must be specified. If set identityMatchPolicy to remapIdentity, then the prefix, and signedPrefix must be specified. "MatchRepository" means that the identity in the signature must be in the same repository as the image identity. "ExactRepository" means that the identity in the signature must be in the same repository as a specific identity specified by "dockerRepository". "remapIdentity" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the "prefix" with the specified “signed prefix” if the the image identity matches the specified prefix. + rekorKeyData: + description: rekorKeyData contains inline base64 data of the Rekor public key. Required if fulcioCAData is set. + type: string + x-kubernetes-validations: + - rule: 'has(self.fulcioCAData) ? has(self.rekorKeyData) : true' + message: rekorKeyData must be set if fulcioCAData is set + - rule: has(self.keyData) != has(self.fulcioCAData) + message: only one of keyData and fulcioCAData must be set + signedIdentity: + description: signedIdentity specifies what image identity the signature claims about the image. + type: object + properties: + matchPolicy: + description: matchPolicy sets the type of matching to be used. Valid values are "MatchRepoDigestOrExact", "MatchRepository", "ExactRepository", "RemapIdentity". When omitted, the default value is "MatchRepoDigestOrExact". If set matchPolicy to ExactRepository, then the repository must be specified. If set matchPolicy to remapIdentity, then the remapPrefix, and remapSignedPrefix must be specified. "MatchRepoDigestOrExact" means that the identity in the signature must be in the same repository as the image identity if the image identity is referenced by a digest. Otherwise, the identity in the signature must be the same as the image identity. "MatchRepository" means that the identity in the signature must be in the same repository as the image identity. "ExactRepository" means that the identity in the signature must be in the same repository as a specific identity specified by "dockerRepository". "remapIdentity" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the "remapPrefix" with the specified “remapSignedPrefix” if the the image identity matches the specified remapPrefix. type: string enum: + - MatchRepoDigestOrExact - MatchRepository - ExactRepository - RemapIdentity - prefix: - description: prefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to "remapIdentity". + remapPrefix: + description: remapPrefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to "remapIdentity". type: string - signedPrefix: - description: signedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to "remapIdentity". + remapSignedPrefix: + description: remapSignedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to "remapIdentity". + type: string + repository: + description: reference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to "exactReference". type: string x-kubernetes-validations: - - rule: 'has(self.identityMatchPolicy) && self.identityMatchPolicy == ''ExactRepository'' ? self.dockerRepository != '''' : true' - message: must set dockerRepository if identityMatchPolicy is ExactRepository - - rule: 'has(self.identityMatchPolicy) && self.identityMatchPolicy == ''RemapIdentity'' ? self.prefix != '''' && self.signedPrefix != '''' : true' - message: must set prefix and signedPrefix if identityMatchPolicy is RemapIdentity - subjectEmail: - description: 'subjectEmail holds the email address of the subject. Example: "expected-signing-user@example.com" Required if fulcioCAData is set. oidcIssuer must be set and keyData must be empty if subjectEmail is set.' - type: string + - rule: 'has(self.matchPolicy) && self.matchPolicy == ''ExactRepository'' ? has(self.repository) : true' + message: must set repository if matchPolicy is ExactRepository + - rule: 'has(self.matchPolicy) && self.matchPolicy == ''RemapIdentity'' ? has(self.remapPrefix) && has(self.remapSignedPrefix) : true' + message: must set remapPrefix and remapSignedPrefix if matchPolicy is RemapIdentity x-kubernetes-validations: - - rule: (has(self.keyData) && self.keyData != '' && !has(self.oidcIssuer) && !has(self.subjectEmail) && !has(self.fulcioCAData) && !has(self.rekorKeyData)) || (!has(self.keyData) && has(self.oidcIssuer) && self.oidcIssuer != '' && has(self.subjectEmail) && self.subjectEmail != '' && has(self.fulcioCAData) && self.fulcioCAData != '' && has(self.rekorKeyData) && self.rekorKeyData != '') + - rule: '(has(self.rootOfTrust) && has(self.rootOfTrust.fulcioCAData)) ? has(self.fulcioSubject) : true' + message: fulcioSubject must be set if fulcioCAData is set + - rule: 'has(self.fulcioSubject) ? has(self.fulcioSubject.oidcIssuer) && has(self.fulcioSubject.signedEmail): true' + message: oidcIssuer and signedEmail must be set if fulcioSubject is set + - rule: 'has(self.signedIdentity) ? has(self.signedIdentity.matchPolicy): true' + message: matchPolicy must be set if signedIdentity is set + scopes: + description: 'scopes defines the list of image identities assigned to a policy. Each item refers to an image or repository in a registry implementing the "Docker Registry HTTP API V2". "scopes" uses one of the following: - complete image name, either using a tag or digest - prefixes of individual-image scopes - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. For more information about the format, see the document about the docker transport field: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker' + type: array + items: + description: ImageScope is the item of the scopes list. + type: string + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(((?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+(?::[0-9]+)?)|(:[0-9]+))(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+:([\w][\w.-]{0,127}))?(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+@([A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}))?$ + x-kubernetes-list-type: set status: description: status contains the observed state of the resource. type: object @@ -145,3 +164,7 @@ spec: policyJSON: description: policyJSON contains the whole policy applied to the namespace which got written to disk. This includes cluster-wide policies from the `openshift-config` namespace as well. type: string + served: true + storage: true + subresources: + status: {} diff --git a/config/v1alpha1/techpreview.imagepolicy.testsuite.yaml b/config/v1alpha1/techpreview.imagepolicy.testsuite.yaml index 8e26d6910f7..4d768c22301 100644 --- a/config/v1alpha1/techpreview.imagepolicy.testsuite.yaml +++ b/config/v1alpha1/techpreview.imagepolicy.testsuite.yaml @@ -3,20 +3,128 @@ name: "[TechPreviewNoUpgrade] ImagePolicy" crd: 0000_10_config-operator_01_imagepolicy.crd.yaml tests: onCreate: - - name: Should be able to create a minimal ImagePolicy + - name: Should be able to create a minimal ImagePolicy with kayData rootOfTrust initial: | apiVersion: config.openshift.io/v1alpha1 kind: ImagePolicy spec: - images: + scopes: - hostname:5000/myns/sigstore-signed-with-full-references policy: - keyData: Zm9vIGJhcg== + rootOfTrust: + keyData: Zm9vIGJhcg== expected: | apiVersion: config.openshift.io/v1alpha1 kind: ImagePolicy spec: - images: + scopes: - hostname:5000/myns/sigstore-signed-with-full-references policy: - keyData: Zm9vIGJhcg== + rootOfTrust: + keyData: Zm9vIGJhcg== + - name: Should be able to create a minimal ImagePolicy with fulcio and rekor rootOfTrust + initial: | + apiVersion: config.openshift.io/v1alpha1 + kind: ImagePolicy + spec: + scopes: + - hostname:5000/myns/sigstore-signed-with-full-references + policy: + rootOfTrust: + fulcioCAData: Zm9vIGJhcg== + rekorKeyData: Zm9vIGJhcg== + fulcioSubject: + oidcIssuer: https://oidc.localhost + signedEmail: test-user@example.com + expected: | + apiVersion: config.openshift.io/v1alpha1 + kind: ImagePolicy + spec: + scopes: + - hostname:5000/myns/sigstore-signed-with-full-references + policy: + rootOfTrust: + fulcioCAData: Zm9vIGJhcg== + rekorKeyData: Zm9vIGJhcg== + fulcioSubject: + oidcIssuer: https://oidc.localhost + signedEmail: test-user@example.com + - name: Should not allow both keyData and fulcioCAData + initial: | + apiVersion: config.openshift.io/v1alpha1 + kind: ImagePolicy + spec: + scopes: + - hostname:5000/myns/sigstore-signed-with-full-references + policy: + rootOfTrust: + keyData: Zm9vIGJhcg== + fulcioCAData: Zm9vIGJhcg== + rekorKeyData: Zm9vIGJhcg== + fulcioSubject: + oidcIssuer: https://oidc.localhost + signedEmail: test-user@example.com + expectedError: "spec.policy.rootOfTrust: Invalid value: \"object\": only one of keyData and fulcioCAData must be set" + - name: Should not allow both keyData and fulcioCAData not set + initial: | + apiVersion: config.openshift.io/v1alpha1 + kind: ImagePolicy + spec: + scopes: + - hostname:5000/myns/sigstore-signed-with-full-references + policy: + rootOfTrust: + rekorKeyData: Zm9vIGJhcg== + expectedError: "spec.policy.rootOfTrust: Invalid value: \"object\": only one of keyData and fulcioCAData must be set" + - name: Should not allow fulcioCAData rootOfTrust set but not set rekorKeyData + initial: | + apiVersion: config.openshift.io/v1alpha1 + kind: ImagePolicy + spec: + scopes: + - hostname:5000/myns/sigstore-signed-with-full-references + policy: + rootOfTrust: + fulcioCAData: Zm9vIGJhcg== + fulcioSubject: + oidcIssuer: https://oidc.localhost + signedEmail: test-user@example.com + expectedError: "spec.policy.rootOfTrust: Invalid value: \"object\": rekorKeyData must be set if fulcioCAData is set" + - name: Should not allow fulcioCAData rootOfTrust set but not set fulcioSubject + initial: | + apiVersion: config.openshift.io/v1alpha1 + kind: ImagePolicy + spec: + scopes: + - hostname:5000/myns/sigstore-signed-with-full-references + policy: + rootOfTrust: + fulcioCAData: Zm9vIGJhcg== + rekorKeyData: Zm9vIGJhcg== + expectedError: "spec.policy: Invalid value: \"object\": fulcioSubject must be set if fulcioCAData is set" + - name: Should not allow ExactRepository signedIdentity but not set repository + initial: | + apiVersion: config.openshift.io/v1alpha1 + kind: ImagePolicy + spec: + scopes: + - hostname:5000/myns/sigstore-signed-with-full-references + policy: + rootOfTrust: + keyData: Zm9vIGJhcg== + signedIdentity: + matchPolicy: ExactRepository + expectedError: "spec.policy.signedIdentity: Invalid value: \"object\": must set repository if matchPolicy is ExactRepository" + - name: Should not allow RemapIdentity signedIdentity set but not set remapPrefix and remapSignedPrefix + initial: | + apiVersion: config.openshift.io/v1alpha1 + kind: ImagePolicy + spec: + scopes: + - hostname:5000/myns/sigstore-signed-with-full-references + policy: + rootOfTrust: + keyData: Zm9vIGJhcg== + signedIdentity: + matchPolicy: RemapIdentity + expectedError: "Invalid value: \"object\": must set remapPrefix and remapSignedPrefix if matchPolicy is RemapIdentity" \ No newline at end of file diff --git a/config/v1alpha1/types_image_policy.go b/config/v1alpha1/types_image_policy.go index dea57620c7b..84f558cb87e 100644 --- a/config/v1alpha1/types_image_policy.go +++ b/config/v1alpha1/types_image_policy.go @@ -28,8 +28,8 @@ type ImagePolicy struct { // ImagePolicySpec is the specification of the ImagePolicy CRD. type ImagePolicySpec struct { - // images defines the list of images assigned to a policy. Each item refers to an image or repository in a registry implementing the "Docker Registry HTTP API V2". - // "images" uses one of the following scopes: + // scopes defines the list of image identities assigned to a policy. Each item refers to an image or repository in a registry implementing the "Docker Registry HTTP API V2". + // "scopes" uses one of the following: // - complete image name, either using a tag or digest // - prefixes of individual-image scopes // - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. @@ -39,87 +39,112 @@ type ImagePolicySpec struct { // +kubebuilder:validation:Required // +required // +listType=set - Images []ImageScope `json:"images"` - // policy defines the verification policy for the images in the images list + Scopes []ImageScope `json:"scopes"` + // policy defines the verification policy for the items in the scopes list // +kubebuilder:validation:Required // +required Policy Policy `json:"policy"` } -// ImageScope is the item of the images list. -// +kubebuilder:validation:Pattern=`^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?/)?[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?)(?::([\w][\w.-]{0,127}))?(?:@([A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}))?$` +// ImageScope is the item of the scopes list. +// +kubebuilder:validation:Pattern=`^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(((?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+(?::[0-9]+)?)|(:[0-9]+))(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+:([\w][\w.-]{0,127}))?(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+@([A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}))?$` type ImageScope string -// Policy defines the verification policy for the images in the images list. -// +kubebuilder:validation:XValidation:rule="(has(self.keyData) && self.keyData != '' && !has(self.oidcIssuer) && !has(self.subjectEmail) && !has(self.fulcioCAData) && !has(self.rekorKeyData)) || (!has(self.keyData) && has(self.oidcIssuer) && self.oidcIssuer != '' && has(self.subjectEmail) && self.subjectEmail != '' && has(self.fulcioCAData) && self.fulcioCAData != '' && has(self.rekorKeyData) && self.rekorKeyData != '')" +// Policy defines the verification policy for the items in the scopes list. +// +kubebuilder:validation:XValidation:rule="(has(self.rootOfTrust) && has(self.rootOfTrust.fulcioCAData)) ? has(self.fulcioSubject) : true",message="fulcioSubject must be set if fulcioCAData is set" +// +kubebuilder:validation:XValidation:rule="has(self.fulcioSubject) ? has(self.fulcioSubject.oidcIssuer) && has(self.fulcioSubject.signedEmail): true",message="oidcIssuer and signedEmail must be set if fulcioSubject is set" +// +kubebuilder:validation:XValidation:rule="has(self.signedIdentity) ? has(self.signedIdentity.matchPolicy): true",message="matchPolicy must be set if signedIdentity is set" type Policy struct { - // oidcIssuer contains the expected OIDC issuer. - // Example: "https://expected.OIDC.issuer/" - // Required if fulcioCAData is set. - // subjectEmail must be set and keyData must be empty if oidcIssuer is set + // rootOfTrust specifies the public key, the Fulcio certificate and the Rekor public key. + // Requires only one of keyData or fulcioCAData must be set. + // +required + RootOfTrust PolicyRootOfTrust `json:"rootOfTrust"` + + // fulcioSubject specifies OIDC issuer and the email of the fulcio authentication configuration. + // Required if rootOfTrust.fulcioCAData is set. // +optional - OIDCIssuer string `json:"oidcIssuer,omitempty"` + FulcioSubject PolicyFulcioSubject `json:"fulcioSubject,omitempty"` - // subjectEmail holds the email address of the subject. - // Example: "expected-signing-user@example.com" - // Required if fulcioCAData is set. - // oidcIssuer must be set and keyData must be empty if subjectEmail is set. + // signedIdentity specifies what image identity the signature claims about the image. // +optional - SubjectEmail string `json:"subjectEmail,omitempty"` + SignedIdentity PolicyIdentity `json:"signedIdentity,omitempty"` +} +// PolicyRootOfTrust defines the public key, the Fulcio certificate and the Rekor public key. +// +kubebuilder:validation:XValidation:rule="has(self.fulcioCAData) ? has(self.rekorKeyData) : true",message="rekorKeyData must be set if fulcioCAData is set" +// +kubebuilder:validation:XValidation:rule="has(self.keyData) != has(self.fulcioCAData)",message="only one of keyData and fulcioCAData must be set" +type PolicyRootOfTrust struct { // keyData contains inline base64 data of the public key. // keyData can be empty if the image got signed keyless. - // Requires oidcIssuer, subjectEmail, and fulcioCAData to be empty if keyData is set. + // Requires only one of keyData and fulcioCAData must be set. // +optional KeyData string `json:"keyData,omitempty"` // fulcioCAData contains inline base64 data for the fulcio CA certificate. + // Requires only one of keyData and fulcioCAData must be set. // +optional FulcioCAData string `json:"fulcioCAData,omitempty"` - // rekorKeyData contains inline base64 data of the rekor public key. + // rekorKeyData contains inline base64 data of the Rekor public key. // Required if fulcioCAData is set. // +optional RekorKeyData string `json:"rekorKeyData,omitempty"` +} - // signedIdentity specifies what image identity the signature. - // claims about the image. - // +optional - SignedIdentity Identity `json:"signedIdentity,omitempty"` +// PolicyFulcioSubject defines the OIDC issuer and the email of the fulcio authentication configuration. +type PolicyFulcioSubject struct { + // oidcIssuer contains the expected OIDC issuer. + // Example: "https://expected.OIDC.issuer/" + // Required if rootOfTrust.fulcioCAData is set. + // +required + OIDCIssuer string `json:"oidcIssuer,omitempty"` + + // signedEmail holds the email address the the certificate is issued for. + // Example: "expected-signing-user@example.com" + // Required if rootOfTrust.fulcioCAData is set. + // +required + SignedEmail string `json:"signedEmail,omitempty"` } -// +kubebuilder:validation:XValidation:rule="has(self.identityMatchPolicy) && self.identityMatchPolicy == 'ExactRepository' ? self.dockerRepository != '' : true",message="must set dockerRepository if identityMatchPolicy is ExactRepository" -// +kubebuilder:validation:XValidation:rule="has(self.identityMatchPolicy) && self.identityMatchPolicy == 'RemapIdentity' ? self.prefix != '' && self.signedPrefix != '' : true",message="must set prefix and signedPrefix if identityMatchPolicy is RemapIdentity" -type Identity struct { - // identityMatchPolicy set the type of matching to be used. - // Valid values are "MatchRepository", "ExactRepository". When omitted, the default value is "MatchRepoDigestOrExact". - // If set identityMatchPolicy to ExactRepository, then the dockerRepository must be specified. - // If set identityMatchPolicy to remapIdentity, then the prefix, and signedPrefix must be specified. +// PolicyIdentity defines image identity the signature claims about the image. +// +kubebuilder:validation:XValidation:rule="has(self.matchPolicy) && self.matchPolicy == 'ExactRepository' ? has(self.repository) : true",message="must set repository if matchPolicy is ExactRepository" +// +kubebuilder:validation:XValidation:rule="has(self.matchPolicy) && self.matchPolicy == 'RemapIdentity' ? has(self.remapPrefix) && has(self.remapSignedPrefix) : true",message="must set remapPrefix and remapSignedPrefix if matchPolicy is RemapIdentity" +type PolicyIdentity struct { + // matchPolicy sets the type of matching to be used. + // Valid values are "MatchRepoDigestOrExact", "MatchRepository", "ExactRepository", "RemapIdentity". When omitted, the default value is "MatchRepoDigestOrExact". + // If set matchPolicy to ExactRepository, then the repository must be specified. + // If set matchPolicy to remapIdentity, then the remapPrefix, and remapSignedPrefix must be specified. + // "MatchRepoDigestOrExact" means that the identity in the signature must be in the same repository as the image identity if the image identity is referenced by a digest. Otherwise, the identity in the signature must be the same as the image identity. // "MatchRepository" means that the identity in the signature must be in the same repository as the image identity. // "ExactRepository" means that the identity in the signature must be in the same repository as a specific identity specified by "dockerRepository". - // "remapIdentity" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the "prefix" with the specified “signed prefix” if the the image identity matches the specified prefix. - // +kubebuilder:validation:Enum=MatchRepository;ExactRepository;RemapIdentity + // "remapIdentity" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the "remapPrefix" with the specified “remapSignedPrefix” if the the image identity matches the specified remapPrefix. + // +kubebuilder:validation:Enum=MatchRepoDigestOrExact;MatchRepository;ExactRepository;RemapIdentity // +optional - IdentityMatchPolicy IdentityMatchPolicy `json:"identityMatchPolicy,omitempty"` - // dockerReference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to "exactReference". + MatchPolicy IdentityMatchPolicy `json:"matchPolicy,omitempty"` + // reference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to "exactReference". // +optional - DockerRepository string `json:"dockerRepository,omitempty"` - // prefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to "remapIdentity". + Repository string `json:"repository,omitempty"` + // remapPrefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to "remapIdentity". // +optional - Prefix string `json:"prefix,omitempty"` - // signedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to "remapIdentity". + RemapPrefix string `json:"remapPrefix,omitempty"` + // remapSignedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to "remapIdentity". // +optional - SignedPrefix string `json:"signedPrefix,omitempty"` + RemapSignedPrefix string `json:"remapSignedPrefix,omitempty"` } -// IdentityMatchPolicy defines the type of matching to be used. +// IdentityMatchPolicy defines the type of matching for setting "matchPolicy". +// Valid values are "MatchRepoDigestOrExact", "MatchRepository", "ExactRepository", "RemapIdentity". When omitted, the default value is "MatchRepoDigestOrExact". type IdentityMatchPolicy string const ( - IdentityMatchPolicyMatchRepoDigestOrExact = "MatchRepoDigestOrExact" - IdentityMatchPolicyMatchRepository = "MatchRepository" - IdentityMatchPolicyExactRepository = "ExactRepository" - IdentityMatchPolicyRemapIdentity = "RemapIdentity" + // "MatchRepoDigestOrExact" means that the identity in the signature must be in the same repository as the image identity if the image identity is referenced by a digest. Otherwise, the identity in the signature must be the same as the image identity. + IdentityMatchPolicyMatchRepoDigestOrExact IdentityMatchPolicy = "MatchRepoDigestOrExact" + // "MatchRepository" means that the identity in the signature must be in the same repository as the image identity. + IdentityMatchPolicyMatchRepository IdentityMatchPolicy = "MatchRepository" + // "ExactRepository" means that the identity in the signature must be in the same repository as a specific identity specified by "dockerRepository". + IdentityMatchPolicyExactRepository IdentityMatchPolicy = "ExactRepository" + // "remapIdentity" means that the signature must be in the same as the remapped image identity. + IdentityMatchPolicyRemapIdentity IdentityMatchPolicy = "RemapIdentity" ) // +k8s:deepcopy-gen=true @@ -154,10 +179,10 @@ const ( // ImagePolicyPending designates a failure application of a ImagePolicy CR. ImagePolicyPending ImagePolicyStatusConditionReason = "Pending" - // ImagePolicyUpdating designates applying a ImagePolicy CR to the machine config. + // ImagePolicyUpdating designates applying an ImagePolicy CR to the machine config. ImagePolicyUpdating ImagePolicyStatusConditionReason = "Updating" - // ImagePolicyAvailable designates a successful application of a ImagePolicy CR to the machine config. + // ImagePolicyAvailable designates a successful application of an ImagePolicy CR to the machine config. ImagePolicyAvailable ImagePolicyStatusConditionReason = "Available" ) diff --git a/config/v1alpha1/zz_generated.deepcopy.go b/config/v1alpha1/zz_generated.deepcopy.go index ab0cc173621..fe44648dad4 100644 --- a/config/v1alpha1/zz_generated.deepcopy.go +++ b/config/v1alpha1/zz_generated.deepcopy.go @@ -31,22 +31,6 @@ func (in *GatherConfig) DeepCopy() *GatherConfig { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Identity) DeepCopyInto(out *Identity) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Identity. -func (in *Identity) DeepCopy() *Identity { - if in == nil { - return nil - } - out := new(Identity) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImagePolicy) DeepCopyInto(out *ImagePolicy) { *out = *in @@ -111,8 +95,8 @@ func (in *ImagePolicyList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImagePolicySpec) DeepCopyInto(out *ImagePolicySpec) { *out = *in - if in.Images != nil { - in, out := &in.Images, &out.Images + if in.Scopes != nil { + in, out := &in.Scopes, &out.Scopes *out = make([]ImageScope, len(*in)) copy(*out, *in) } @@ -250,6 +234,8 @@ func (in *InsightsDataGatherStatus) DeepCopy() *InsightsDataGatherStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Policy) DeepCopyInto(out *Policy) { *out = *in + out.RootOfTrust = in.RootOfTrust + out.FulcioSubject = in.FulcioSubject out.SignedIdentity = in.SignedIdentity return } @@ -263,3 +249,51 @@ func (in *Policy) DeepCopy() *Policy { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyFulcioSubject) DeepCopyInto(out *PolicyFulcioSubject) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyFulcioSubject. +func (in *PolicyFulcioSubject) DeepCopy() *PolicyFulcioSubject { + if in == nil { + return nil + } + out := new(PolicyFulcioSubject) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyIdentity) DeepCopyInto(out *PolicyIdentity) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyIdentity. +func (in *PolicyIdentity) DeepCopy() *PolicyIdentity { + if in == nil { + return nil + } + out := new(PolicyIdentity) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyRootOfTrust) DeepCopyInto(out *PolicyRootOfTrust) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyRootOfTrust. +func (in *PolicyRootOfTrust) DeepCopy() *PolicyRootOfTrust { + if in == nil { + return nil + } + out := new(PolicyRootOfTrust) + in.DeepCopyInto(out) + return out +} diff --git a/config/v1alpha1/zz_generated.swagger_doc_generated.go b/config/v1alpha1/zz_generated.swagger_doc_generated.go index 67fabec2780..f8be70fa9c2 100644 --- a/config/v1alpha1/zz_generated.swagger_doc_generated.go +++ b/config/v1alpha1/zz_generated.swagger_doc_generated.go @@ -11,17 +11,6 @@ package v1alpha1 // Those methods can be generated by using hack/update-swagger-docs.sh // AUTO-GENERATED FUNCTIONS START HERE -var map_Identity = map[string]string{ - "identityMatchPolicy": "identityMatchPolicy set the type of matching to be used. Valid values are \"MatchRepository\", \"ExactRepository\". When omitted, the default value is \"MatchRepoDigestOrExact\". If set identityMatchPolicy to ExactRepository, then the dockerRepository must be specified. If set identityMatchPolicy to remapIdentity, then the prefix, and signedPrefix must be specified. \"MatchRepository\" means that the identity in the signature must be in the same repository as the image identity. \"ExactRepository\" means that the identity in the signature must be in the same repository as a specific identity specified by \"dockerRepository\". \"remapIdentity\" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the \"prefix\" with the specified “signed prefix” if the the image identity matches the specified prefix.", - "dockerRepository": "dockerReference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to \"exactReference\".", - "prefix": "prefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to \"remapIdentity\".", - "signedPrefix": "signedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to \"remapIdentity\".", -} - -func (Identity) SwaggerDoc() map[string]string { - return map_Identity -} - var map_ImagePolicy = map[string]string{ "": "ImagePolicy holds namespace-wide configuration configuration for image signature verification\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", @@ -44,8 +33,8 @@ func (ImagePolicyList) SwaggerDoc() map[string]string { var map_ImagePolicySpec = map[string]string{ "": "ImagePolicySpec is the specification of the ImagePolicy CRD.", - "images": "images defines the list of images assigned to a policy. Each item refers to an image or repository in a registry implementing the \"Docker Registry HTTP API V2\". \"images\" uses one of the following scopes: - complete image name, either using a tag or digest - prefixes of individual-image scopes - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. For more information about the format, see the document about the docker transport field: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker", - "policy": "policy defines the verification policy for the images in the images list", + "scopes": "scopes defines the list of image identities assigned to a policy. Each item refers to an image or repository in a registry implementing the \"Docker Registry HTTP API V2\". \"scopes\" uses one of the following: - complete image name, either using a tag or digest - prefixes of individual-image scopes - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. For more information about the format, see the document about the docker transport field: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker", + "policy": "policy defines the verification policy for the items in the scopes list", } func (ImagePolicySpec) SwaggerDoc() map[string]string { @@ -62,19 +51,49 @@ func (ImagePolicyStatus) SwaggerDoc() map[string]string { } var map_Policy = map[string]string{ - "": "Policy defines the verification policy for the images in the images list.", - "oidcIssuer": "oidcIssuer contains the expected OIDC issuer. Example: \"https://expected.OIDC.issuer/\" Required if fulcioCAData is set. subjectEmail must be set and keyData must be empty if oidcIssuer is set", - "subjectEmail": "subjectEmail holds the email address of the subject. Example: \"expected-signing-user@example.com\" Required if fulcioCAData is set. oidcIssuer must be set and keyData must be empty if subjectEmail is set.", - "keyData": "keyData contains inline base64 data of the public key. keyData can be empty if the image got signed keyless. Requires oidcIssuer, subjectEmail, and fulcioCAData to be empty if keyData is set.", - "fulcioCAData": "fulcioCAData contains inline base64 data for the fulcio CA certificate.", - "rekorKeyData": "rekorKeyData contains inline base64 data of the rekor public key. Required if fulcioCAData is set.", - "signedIdentity": "signedIdentity specifies what image identity the signature. claims about the image.", + "": "Policy defines the verification policy for the items in the scopes list.", + "rootOfTrust": "rootOfTrust specifies the public key, the Fulcio certificate and the Rekor public key. Requires only one of keyData or fulcioCAData must be set.", + "fulcioSubject": "fulcioSubject specifies OIDC issuer and the email of the fulcio authentication configuration. Required if rootOfTrust.fulcioCAData is set.", + "signedIdentity": "signedIdentity specifies what image identity the signature claims about the image.", } func (Policy) SwaggerDoc() map[string]string { return map_Policy } +var map_PolicyFulcioSubject = map[string]string{ + "": "PolicyFulcioSubject defines the OIDC issuer and the email of the fulcio authentication configuration.", + "oidcIssuer": "oidcIssuer contains the expected OIDC issuer. Example: \"https://expected.OIDC.issuer/\" Required if rootOfTrust.fulcioCAData is set.", + "signedEmail": "signedEmail holds the email address the the certificate is issued for. Example: \"expected-signing-user@example.com\" Required if rootOfTrust.fulcioCAData is set.", +} + +func (PolicyFulcioSubject) SwaggerDoc() map[string]string { + return map_PolicyFulcioSubject +} + +var map_PolicyIdentity = map[string]string{ + "": "PolicyIdentity defines image identity the signature claims about the image.", + "matchPolicy": "matchPolicy sets the type of matching to be used. Valid values are \"MatchRepoDigestOrExact\", \"MatchRepository\", \"ExactRepository\", \"RemapIdentity\". When omitted, the default value is \"MatchRepoDigestOrExact\". If set matchPolicy to ExactRepository, then the repository must be specified. If set matchPolicy to remapIdentity, then the remapPrefix, and remapSignedPrefix must be specified. \"MatchRepoDigestOrExact\" means that the identity in the signature must be in the same repository as the image identity if the image identity is referenced by a digest. Otherwise, the identity in the signature must be the same as the image identity. \"MatchRepository\" means that the identity in the signature must be in the same repository as the image identity. \"ExactRepository\" means that the identity in the signature must be in the same repository as a specific identity specified by \"dockerRepository\". \"remapIdentity\" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the \"remapPrefix\" with the specified “remapSignedPrefix” if the the image identity matches the specified remapPrefix.", + "repository": "reference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to \"exactReference\".", + "remapPrefix": "remapPrefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to \"remapIdentity\".", + "remapSignedPrefix": "remapSignedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to \"remapIdentity\".", +} + +func (PolicyIdentity) SwaggerDoc() map[string]string { + return map_PolicyIdentity +} + +var map_PolicyRootOfTrust = map[string]string{ + "": "PolicyRootOfTrust defines the public key, the Fulcio certificate and the Rekor public key.", + "keyData": "keyData contains inline base64 data of the public key. keyData can be empty if the image got signed keyless. Requires only one of keyData and fulcioCAData must be set.", + "fulcioCAData": "fulcioCAData contains inline base64 data for the fulcio CA certificate. Requires only one of keyData and fulcioCAData must be set.", + "rekorKeyData": "rekorKeyData contains inline base64 data of the Rekor public key. Required if fulcioCAData is set.", +} + +func (PolicyRootOfTrust) SwaggerDoc() map[string]string { + return map_PolicyRootOfTrust +} + var map_GatherConfig = map[string]string{ "": "gatherConfig provides data gathering configuration options.", "dataPolicy": "dataPolicy allows user to enable additional global obfuscation of the IP addresses and base domain in the Insights archive data. Valid values are \"None\" and \"ObfuscateNetworking\". When set to None the data is not obfuscated. When set to ObfuscateNetworking the IP addresses and the cluster domain name are obfuscated. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is None.", diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 78ee7c26a65..b2e8cb0a2f8 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -371,7 +371,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/config/v1.WebhookTokenAuthenticator": schema_openshift_api_config_v1_WebhookTokenAuthenticator(ref), "github.com/openshift/api/config/v1.featureSetBuilder": schema_openshift_api_config_v1_featureSetBuilder(ref), "github.com/openshift/api/config/v1alpha1.GatherConfig": schema_openshift_api_config_v1alpha1_GatherConfig(ref), - "github.com/openshift/api/config/v1alpha1.Identity": schema_openshift_api_config_v1alpha1_Identity(ref), "github.com/openshift/api/config/v1alpha1.ImagePolicy": schema_openshift_api_config_v1alpha1_ImagePolicy(ref), "github.com/openshift/api/config/v1alpha1.ImagePolicyList": schema_openshift_api_config_v1alpha1_ImagePolicyList(ref), "github.com/openshift/api/config/v1alpha1.ImagePolicySpec": schema_openshift_api_config_v1alpha1_ImagePolicySpec(ref), @@ -381,6 +380,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/config/v1alpha1.InsightsDataGatherSpec": schema_openshift_api_config_v1alpha1_InsightsDataGatherSpec(ref), "github.com/openshift/api/config/v1alpha1.InsightsDataGatherStatus": schema_openshift_api_config_v1alpha1_InsightsDataGatherStatus(ref), "github.com/openshift/api/config/v1alpha1.Policy": schema_openshift_api_config_v1alpha1_Policy(ref), + "github.com/openshift/api/config/v1alpha1.PolicyFulcioSubject": schema_openshift_api_config_v1alpha1_PolicyFulcioSubject(ref), + "github.com/openshift/api/config/v1alpha1.PolicyIdentity": schema_openshift_api_config_v1alpha1_PolicyIdentity(ref), + "github.com/openshift/api/config/v1alpha1.PolicyRootOfTrust": schema_openshift_api_config_v1alpha1_PolicyRootOfTrust(ref), "github.com/openshift/api/console/v1.ApplicationMenuSpec": schema_openshift_api_console_v1_ApplicationMenuSpec(ref), "github.com/openshift/api/console/v1.CLIDownloadLink": schema_openshift_api_console_v1_CLIDownloadLink(ref), "github.com/openshift/api/console/v1.ConsoleCLIDownload": schema_openshift_api_console_v1_ConsoleCLIDownload(ref), @@ -18022,46 +18024,6 @@ func schema_openshift_api_config_v1alpha1_GatherConfig(ref common.ReferenceCallb } } -func schema_openshift_api_config_v1alpha1_Identity(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "identityMatchPolicy": { - SchemaProps: spec.SchemaProps{ - Description: "identityMatchPolicy set the type of matching to be used. Valid values are \"MatchRepository\", \"ExactRepository\". When omitted, the default value is \"MatchRepoDigestOrExact\". If set identityMatchPolicy to ExactRepository, then the dockerRepository must be specified. If set identityMatchPolicy to remapIdentity, then the prefix, and signedPrefix must be specified. \"MatchRepository\" means that the identity in the signature must be in the same repository as the image identity. \"ExactRepository\" means that the identity in the signature must be in the same repository as a specific identity specified by \"dockerRepository\". \"remapIdentity\" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the \"prefix\" with the specified “signed prefix” if the the image identity matches the specified prefix.", - Type: []string{"string"}, - Format: "", - }, - }, - "dockerRepository": { - SchemaProps: spec.SchemaProps{ - Description: "dockerReference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to \"exactReference\".", - Type: []string{"string"}, - Format: "", - }, - }, - "prefix": { - SchemaProps: spec.SchemaProps{ - Description: "prefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to \"remapIdentity\".", - Type: []string{"string"}, - Format: "", - }, - }, - "signedPrefix": { - SchemaProps: spec.SchemaProps{ - Description: "signedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to \"remapIdentity\".", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - func schema_openshift_api_config_v1alpha1_ImagePolicy(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -18170,14 +18132,14 @@ func schema_openshift_api_config_v1alpha1_ImagePolicySpec(ref common.ReferenceCa Description: "ImagePolicySpec is the specification of the ImagePolicy CRD.", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "images": { + "scopes": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ "x-kubernetes-list-type": "set", }, }, SchemaProps: spec.SchemaProps{ - Description: "images defines the list of images assigned to a policy. Each item refers to an image or repository in a registry implementing the \"Docker Registry HTTP API V2\". \"images\" uses one of the following scopes: - complete image name, either using a tag or digest - prefixes of individual-image scopes - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. For more information about the format, see the document about the docker transport field: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker", + Description: "scopes defines the list of image identities assigned to a policy. Each item refers to an image or repository in a registry implementing the \"Docker Registry HTTP API V2\". \"scopes\" uses one of the following: - complete image name, either using a tag or digest - prefixes of individual-image scopes - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. For more information about the format, see the document about the docker transport field: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -18192,13 +18154,13 @@ func schema_openshift_api_config_v1alpha1_ImagePolicySpec(ref common.ReferenceCa }, "policy": { SchemaProps: spec.SchemaProps{ - Description: "policy defines the verification policy for the images in the images list", + Description: "policy defines the verification policy for the items in the scopes list", Default: map[string]interface{}{}, Ref: ref("github.com/openshift/api/config/v1alpha1.Policy"), }, }, }, - Required: []string{"images", "policy"}, + Required: []string{"scopes", "policy"}, }, }, Dependencies: []string{ @@ -18384,56 +18346,138 @@ func schema_openshift_api_config_v1alpha1_Policy(ref common.ReferenceCallback) c return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "Policy defines the verification policy for the images in the images list.", + Description: "Policy defines the verification policy for the items in the scopes list.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "rootOfTrust": { + SchemaProps: spec.SchemaProps{ + Description: "rootOfTrust specifies the public key, the Fulcio certificate and the Rekor public key. Requires only one of keyData or fulcioCAData must be set.", + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/config/v1alpha1.PolicyRootOfTrust"), + }, + }, + "fulcioSubject": { + SchemaProps: spec.SchemaProps{ + Description: "fulcioSubject specifies OIDC issuer and the email of the fulcio authentication configuration. Required if rootOfTrust.fulcioCAData is set.", + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/config/v1alpha1.PolicyFulcioSubject"), + }, + }, + "signedIdentity": { + SchemaProps: spec.SchemaProps{ + Description: "signedIdentity specifies what image identity the signature claims about the image.", + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/config/v1alpha1.PolicyIdentity"), + }, + }, + }, + Required: []string{"rootOfTrust"}, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/config/v1alpha1.PolicyFulcioSubject", "github.com/openshift/api/config/v1alpha1.PolicyIdentity", "github.com/openshift/api/config/v1alpha1.PolicyRootOfTrust"}, + } +} + +func schema_openshift_api_config_v1alpha1_PolicyFulcioSubject(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PolicyFulcioSubject defines the OIDC issuer and the email of the fulcio authentication configuration.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "oidcIssuer": { SchemaProps: spec.SchemaProps{ - Description: "oidcIssuer contains the expected OIDC issuer. Example: \"https://expected.OIDC.issuer/\" Required if fulcioCAData is set. subjectEmail must be set and keyData must be empty if oidcIssuer is set", + Description: "oidcIssuer contains the expected OIDC issuer. Example: \"https://expected.OIDC.issuer/\" Required if rootOfTrust.fulcioCAData is set.", Type: []string{"string"}, Format: "", }, }, - "subjectEmail": { + "signedEmail": { SchemaProps: spec.SchemaProps{ - Description: "subjectEmail holds the email address of the subject. Example: \"expected-signing-user@example.com\" Required if fulcioCAData is set. oidcIssuer must be set and keyData must be empty if subjectEmail is set.", + Description: "signedEmail holds the email address the the certificate is issued for. Example: \"expected-signing-user@example.com\" Required if rootOfTrust.fulcioCAData is set.", Type: []string{"string"}, Format: "", }, }, - "keyData": { + }, + }, + }, + } +} + +func schema_openshift_api_config_v1alpha1_PolicyIdentity(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PolicyIdentity defines image identity the signature claims about the image.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "matchPolicy": { SchemaProps: spec.SchemaProps{ - Description: "keyData contains inline base64 data of the public key. keyData can be empty if the image got signed keyless. Requires oidcIssuer, subjectEmail, and fulcioCAData to be empty if keyData is set.", + Description: "matchPolicy sets the type of matching to be used. Valid values are \"MatchRepoDigestOrExact\", \"MatchRepository\", \"ExactRepository\", \"RemapIdentity\". When omitted, the default value is \"MatchRepoDigestOrExact\". If set matchPolicy to ExactRepository, then the repository must be specified. If set matchPolicy to remapIdentity, then the remapPrefix, and remapSignedPrefix must be specified. \"MatchRepoDigestOrExact\" means that the identity in the signature must be in the same repository as the image identity if the image identity is referenced by a digest. Otherwise, the identity in the signature must be the same as the image identity. \"MatchRepository\" means that the identity in the signature must be in the same repository as the image identity. \"ExactRepository\" means that the identity in the signature must be in the same repository as a specific identity specified by \"dockerRepository\". \"remapIdentity\" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the \"remapPrefix\" with the specified “remapSignedPrefix” if the the image identity matches the specified remapPrefix.", Type: []string{"string"}, Format: "", }, }, - "fulcioCAData": { + "repository": { SchemaProps: spec.SchemaProps{ - Description: "fulcioCAData contains inline base64 data for the fulcio CA certificate.", + Description: "reference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to \"exactReference\".", Type: []string{"string"}, Format: "", }, }, - "rekorKeyData": { + "remapPrefix": { SchemaProps: spec.SchemaProps{ - Description: "rekorKeyData contains inline base64 data of the rekor public key. Required if fulcioCAData is set.", + Description: "remapPrefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to \"remapIdentity\".", Type: []string{"string"}, Format: "", }, }, - "signedIdentity": { + "remapSignedPrefix": { SchemaProps: spec.SchemaProps{ - Description: "signedIdentity specifies what image identity the signature. claims about the image.", - Default: map[string]interface{}{}, - Ref: ref("github.com/openshift/api/config/v1alpha1.Identity"), + Description: "remapSignedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to \"remapIdentity\".", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_openshift_api_config_v1alpha1_PolicyRootOfTrust(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PolicyRootOfTrust defines the public key, the Fulcio certificate and the Rekor public key.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "keyData": { + SchemaProps: spec.SchemaProps{ + Description: "keyData contains inline base64 data of the public key. keyData can be empty if the image got signed keyless. Requires only one of keyData and fulcioCAData must be set.", + Type: []string{"string"}, + Format: "", + }, + }, + "fulcioCAData": { + SchemaProps: spec.SchemaProps{ + Description: "fulcioCAData contains inline base64 data for the fulcio CA certificate. Requires only one of keyData and fulcioCAData must be set.", + Type: []string{"string"}, + Format: "", + }, + }, + "rekorKeyData": { + SchemaProps: spec.SchemaProps{ + Description: "rekorKeyData contains inline base64 data of the Rekor public key. Required if fulcioCAData is set.", + Type: []string{"string"}, + Format: "", }, }, }, }, }, - Dependencies: []string{ - "github.com/openshift/api/config/v1alpha1.Identity"}, } } diff --git a/openapi/openapi.json b/openapi/openapi.json index 7fc8ea860a5..d5c09915779 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -9910,27 +9910,6 @@ } } }, - "com.github.openshift.api.config.v1alpha1.Identity": { - "type": "object", - "properties": { - "dockerRepository": { - "description": "dockerReference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to \"exactReference\".", - "type": "string" - }, - "identityMatchPolicy": { - "description": "identityMatchPolicy set the type of matching to be used. Valid values are \"MatchRepository\", \"ExactRepository\". When omitted, the default value is \"MatchRepoDigestOrExact\". If set identityMatchPolicy to ExactRepository, then the dockerRepository must be specified. If set identityMatchPolicy to remapIdentity, then the prefix, and signedPrefix must be specified. \"MatchRepository\" means that the identity in the signature must be in the same repository as the image identity. \"ExactRepository\" means that the identity in the signature must be in the same repository as a specific identity specified by \"dockerRepository\". \"remapIdentity\" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the \"prefix\" with the specified “signed prefix” if the the image identity matches the specified prefix.", - "type": "string" - }, - "prefix": { - "description": "prefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to \"remapIdentity\".", - "type": "string" - }, - "signedPrefix": { - "description": "signedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to \"remapIdentity\".", - "type": "string" - } - } - }, "com.github.openshift.api.config.v1alpha1.ImagePolicy": { "description": "ImagePolicy holds namespace-wide configuration configuration for image signature verification\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", "type": "object", @@ -9997,23 +9976,23 @@ "description": "ImagePolicySpec is the specification of the ImagePolicy CRD.", "type": "object", "required": [ - "images", + "scopes", "policy" ], "properties": { - "images": { - "description": "images defines the list of images assigned to a policy. Each item refers to an image or repository in a registry implementing the \"Docker Registry HTTP API V2\". \"images\" uses one of the following scopes: - complete image name, either using a tag or digest - prefixes of individual-image scopes - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. For more information about the format, see the document about the docker transport field: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker", + "policy": { + "description": "policy defines the verification policy for the items in the scopes list", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.Policy" + }, + "scopes": { + "description": "scopes defines the list of image identities assigned to a policy. Each item refers to an image or repository in a registry implementing the \"Docker Registry HTTP API V2\". \"scopes\" uses one of the following: - complete image name, either using a tag or digest - prefixes of individual-image scopes - a wildcarded expression for matching all subdomains, the wildcard only presents at the beginning, *.example.com is a valid case, but example*.*.com is not. For more information about the format, see the document about the docker transport field: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker", "type": "array", "items": { "type": "string", "default": "" }, "x-kubernetes-list-type": "set" - }, - "policy": { - "description": "policy defines the verification policy for the images in the images list", - "default": {}, - "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.Policy" } } }, @@ -10115,32 +10094,79 @@ "type": "object" }, "com.github.openshift.api.config.v1alpha1.Policy": { - "description": "Policy defines the verification policy for the images in the images list.", + "description": "Policy defines the verification policy for the items in the scopes list.", "type": "object", + "required": [ + "rootOfTrust" + ], "properties": { - "fulcioCAData": { - "description": "fulcioCAData contains inline base64 data for the fulcio CA certificate.", + "fulcioSubject": { + "description": "fulcioSubject specifies OIDC issuer and the email of the fulcio authentication configuration. Required if rootOfTrust.fulcioCAData is set.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.PolicyFulcioSubject" + }, + "rootOfTrust": { + "description": "rootOfTrust specifies the public key, the Fulcio certificate and the Rekor public key. Requires only one of keyData or fulcioCAData must be set.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.PolicyRootOfTrust" + }, + "signedIdentity": { + "description": "signedIdentity specifies what image identity the signature claims about the image.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.PolicyIdentity" + } + } + }, + "com.github.openshift.api.config.v1alpha1.PolicyFulcioSubject": { + "description": "PolicyFulcioSubject defines the OIDC issuer and the email of the fulcio authentication configuration.", + "type": "object", + "properties": { + "oidcIssuer": { + "description": "oidcIssuer contains the expected OIDC issuer. Example: \"https://expected.OIDC.issuer/\" Required if rootOfTrust.fulcioCAData is set.", "type": "string" }, - "keyData": { - "description": "keyData contains inline base64 data of the public key. keyData can be empty if the image got signed keyless. Requires oidcIssuer, subjectEmail, and fulcioCAData to be empty if keyData is set.", + "signedEmail": { + "description": "signedEmail holds the email address the the certificate is issued for. Example: \"expected-signing-user@example.com\" Required if rootOfTrust.fulcioCAData is set.", + "type": "string" + } + } + }, + "com.github.openshift.api.config.v1alpha1.PolicyIdentity": { + "description": "PolicyIdentity defines image identity the signature claims about the image.", + "type": "object", + "properties": { + "matchPolicy": { + "description": "matchPolicy sets the type of matching to be used. Valid values are \"MatchRepoDigestOrExact\", \"MatchRepository\", \"ExactRepository\", \"RemapIdentity\". When omitted, the default value is \"MatchRepoDigestOrExact\". If set matchPolicy to ExactRepository, then the repository must be specified. If set matchPolicy to remapIdentity, then the remapPrefix, and remapSignedPrefix must be specified. \"MatchRepoDigestOrExact\" means that the identity in the signature must be in the same repository as the image identity if the image identity is referenced by a digest. Otherwise, the identity in the signature must be the same as the image identity. \"MatchRepository\" means that the identity in the signature must be in the same repository as the image identity. \"ExactRepository\" means that the identity in the signature must be in the same repository as a specific identity specified by \"dockerRepository\". \"remapIdentity\" means that the signature must be in the same as the remapped image identity. Remapped image identity is obtained by replacing the \"remapPrefix\" with the specified “remapSignedPrefix” if the the image identity matches the specified remapPrefix.", "type": "string" }, - "oidcIssuer": { - "description": "oidcIssuer contains the expected OIDC issuer. Example: \"https://expected.OIDC.issuer/\" Required if fulcioCAData is set. subjectEmail must be set and keyData must be empty if oidcIssuer is set", + "remapPrefix": { + "description": "remapPrefix is the prefix of the image identity to be matched. This field is required if identityMatchPolicy is set to \"remapIdentity\".", "type": "string" }, - "rekorKeyData": { - "description": "rekorKeyData contains inline base64 data of the rekor public key. Required if fulcioCAData is set.", + "remapSignedPrefix": { + "description": "remapSignedPrefix is the prefix of the image identity to be matched in the signature. This field is required if identityMatchPolicy is set to \"remapIdentity\".", "type": "string" }, - "signedIdentity": { - "description": "signedIdentity specifies what image identity the signature. claims about the image.", - "default": {}, - "$ref": "#/definitions/com.github.openshift.api.config.v1alpha1.Identity" + "repository": { + "description": "reference is the reference of the image identity to be matched. This field is required if identityMatchPolicy is set to \"exactReference\".", + "type": "string" + } + } + }, + "com.github.openshift.api.config.v1alpha1.PolicyRootOfTrust": { + "description": "PolicyRootOfTrust defines the public key, the Fulcio certificate and the Rekor public key.", + "type": "object", + "properties": { + "fulcioCAData": { + "description": "fulcioCAData contains inline base64 data for the fulcio CA certificate. Requires only one of keyData and fulcioCAData must be set.", + "type": "string" }, - "subjectEmail": { - "description": "subjectEmail holds the email address of the subject. Example: \"expected-signing-user@example.com\" Required if fulcioCAData is set. oidcIssuer must be set and keyData must be empty if subjectEmail is set.", + "keyData": { + "description": "keyData contains inline base64 data of the public key. keyData can be empty if the image got signed keyless. Requires only one of keyData and fulcioCAData must be set.", + "type": "string" + }, + "rekorKeyData": { + "description": "rekorKeyData contains inline base64 data of the Rekor public key. Required if fulcioCAData is set.", "type": "string" } }