apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    api-approved.openshift.io: https://github.com/openshift/api/pull/1457
    include.release.openshift.io/ibm-cloud-managed: "true"
    include.release.openshift.io/self-managed-high-availability: "true"
    include.release.openshift.io/single-node-developer: "true"
    release.openshift.io/feature-set: TechPreviewNoUpgrade
  name: imagepolicies.config.openshift.io
spec:
  group: config.openshift.io
  names:
    kind: ImagePolicy
    listKind: ImagePolicyList
    plural: imagepolicies
    singular: imagepolicy
  scope: Namespaced
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        description: "ImagePolicy holds namespace-wide configuration for image signature
          verification \n Compatibility 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."
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation
              of an object. Servers should convert recognized schemas to the latest
              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
              object represents. Servers may infer this from the endpoint the client
              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: spec holds user settable values for configuration
            properties:
              policy:
                description: policy contains configuration to allow scopes to be verified,
                  and defines how images not matching the verification policy will
                  be treated.
                properties:
                  rootOfTrust:
                    description: rootOfTrust specifies the root of trust for the policy.
                    properties:
                      fulcioCAWithRekor:
                        description: 'fulcioCAWithRekor defines the root of trust
                          based on the Fulcio certificate and the Rekor public key.
                          For more information about Fulcio and Rekor, please refer
                          to the document at: https://github.com/sigstore/fulcio and
                          https://github.com/sigstore/rekor'
                        properties:
                          fulcioCAData:
                            description: fulcioCAData contains inline base64-encoded
                              data for the PEM format fulcio CA. fulcioCAData must
                              be at most 8192 characters.
                            format: byte
                            maxLength: 8192
                            type: string
                          fulcioSubject:
                            description: fulcioSubject specifies OIDC issuer and the
                              email of the Fulcio authentication configuration.
                            properties:
                              oidcIssuer:
                                description: 'oidcIssuer contains the expected OIDC
                                  issuer. It will be verified that the Fulcio-issued
                                  certificate contains a (Fulcio-defined) certificate
                                  extension pointing at this OIDC issuer URL. When
                                  Fulcio issues certificates, it includes a value
                                  based on an URL inside the client-provided ID token.
                                  Example: "https://expected.OIDC.issuer/"'
                                type: string
                                x-kubernetes-validations:
                                - message: oidcIssuer must be a valid URL
                                  rule: isURL(self)
                              signedEmail:
                                description: 'signedEmail holds the email address
                                  the the Fulcio certificate is issued for. Example:
                                  "expected-signing-user@example.com"'
                                type: string
                                x-kubernetes-validations:
                                - message: invalid email address
                                  rule: self.matches('^\\S+@\\S+$')
                            required:
                            - oidcIssuer
                            - signedEmail
                            type: object
                          rekorKeyData:
                            description: rekorKeyData contains inline base64-encoded
                              data for the PEM format from the Rekor public key. rekorKeyData
                              must be at most 8192 characters.
                            format: byte
                            maxLength: 8192
                            type: string
                        required:
                        - fulcioCAData
                        - fulcioSubject
                        - rekorKeyData
                        type: object
                      policyType:
                        description: policyType serves as the union's discriminator.
                          Users are required to assign a value to this field, choosing
                          one of the policy types that define the root of trust. "PublicKey"
                          indicates that the policy relies on a sigstore publicKey
                          and may optionally use a Rekor verification. "FulcioCAWithRekor"
                          indicates that the policy is based on the Fulcio certification
                          and incorporates a Rekor verification.
                        enum:
                        - PublicKey
                        - FulcioCAWithRekor
                        type: string
                      publicKey:
                        description: publicKey defines the root of trust based on
                          a sigstore public key.
                        properties:
                          keyData:
                            description: keyData contains inline base64-encoded data
                              for the PEM format public key. KeyData must be at most
                              8192 characters.
                            format: byte
                            maxLength: 8192
                            type: string
                          rekorKeyData:
                            description: rekorKeyData contains inline base64-encoded
                              data for the PEM format from the Rekor public key. rekorKeyData
                              must be at most 8192 characters.
                            format: byte
                            maxLength: 8192
                            type: string
                        required:
                        - keyData
                        type: object
                    required:
                    - policyType
                    type: object
                    x-kubernetes-validations:
                    - message: publicKey is required when policyType is PublicKey,
                        and forbidden otherwise
                      rule: 'has(self.policyType) && self.policyType == ''PublicKey''
                        ? has(self.publicKey) : !has(self.publicKey)'
                    - message: fulcioCAWithRekor is required when policyType is FulcioCAWithRekor,
                        and forbidden otherwise
                      rule: 'has(self.policyType) && self.policyType == ''FulcioCAWithRekor''
                        ? has(self.fulcioCAWithRekor) : !has(self.fulcioCAWithRekor)'
                  signedIdentity:
                    description: signedIdentity specifies what image identity the
                      signature claims about the image. The required matchPolicy field
                      specifies the approach used in the verification process to verify
                      the identity in the signature and the actual image identity,
                      the default matchPolicy is "MatchRepoDigestOrExact".
                    properties:
                      exactRepository:
                        description: exactRepository is required if matchPolicy is
                          set to "ExactRepository".
                        properties:
                          repository:
                            description: repository is the reference of the image
                              identity to be matched. The value should be a repository
                              name (by omitting the tag or digest) in a registry implementing
                              the "Docker Registry HTTP API V2". For example, docker.io/library/busybox
                            maxLength: 512
                            type: string
                            x-kubernetes-validations:
                            - message: invalid repository or prefix in the signedIdentity,
                                should not include the tag or digest
                              rule: 'self.matches(''.*:([\\w][\\w.-]{0,127})$'')?
                                self.matches(''^(localhost:[0-9]+)$''): true'
                            - message: invalid repository or prefix in the signedIdentity
                              rule: self.matches('^(((?:[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]+)?)|(localhost(?::[0-9]+)?))(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$')
                        required:
                        - repository
                        type: object
                      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 exactRepository must be specified.
                          If set matchPolicy to RemapIdentity, then the remapIdentity
                          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 "repository". "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 “signedPrefix” if the the
                          image identity matches the specified remapPrefix.
                        enum:
                        - MatchRepoDigestOrExact
                        - MatchRepository
                        - ExactRepository
                        - RemapIdentity
                        type: string
                      remapIdentity:
                        description: remapIdentity is required if matchPolicy is set
                          to "RemapIdentity".
                        properties:
                          prefix:
                            description: prefix is the prefix of the image identity
                              to be matched. If the image identity matches the specified
                              prefix, that prefix is replaced by the specified “signedPrefix”
                              (otherwise it is used as unchanged and no remapping
                              takes place). This useful when verifying signatures
                              for a mirror of some other repository namespace that
                              preserves the vendor’s repository structure. The prefix
                              and signedPrefix values can be either host[:port] values
                              (matching exactly the same host[:port], string), repository
                              namespaces, or repositories (i.e. they must not contain
                              tags/digests), and match as prefixes of the fully expanded
                              form. For example, docker.io/library/busybox (not busybox)
                              to specify that single repository, or docker.io/library
                              (not an empty string) to specify the parent namespace
                              of docker.io/library/busybox.
                            maxLength: 512
                            type: string
                            x-kubernetes-validations:
                            - message: invalid repository or prefix in the signedIdentity,
                                should not include the tag or digest
                              rule: 'self.matches(''.*:([\\w][\\w.-]{0,127})$'')?
                                self.matches(''^(localhost:[0-9]+)$''): true'
                            - message: invalid repository or prefix in the signedIdentity
                              rule: self.matches('^(((?:[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]+)?)|(localhost(?::[0-9]+)?))(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$')
                          signedPrefix:
                            description: signedPrefix is the prefix of the image identity
                              to be matched in the signature. The format is the same
                              as "prefix". The values can be either host[:port] values
                              (matching exactly the same host[:port], string), repository
                              namespaces, or repositories (i.e. they must not contain
                              tags/digests), and match as prefixes of the fully expanded
                              form. For example, docker.io/library/busybox (not busybox)
                              to specify that single repository, or docker.io/library
                              (not an empty string) to specify the parent namespace
                              of docker.io/library/busybox.
                            maxLength: 512
                            type: string
                            x-kubernetes-validations:
                            - message: invalid repository or prefix in the signedIdentity,
                                should not include the tag or digest
                              rule: 'self.matches(''.*:([\\w][\\w.-]{0,127})$'')?
                                self.matches(''^(localhost:[0-9]+)$''): true'
                            - message: invalid repository or prefix in the signedIdentity
                              rule: self.matches('^(((?:[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]+)?)|(localhost(?::[0-9]+)?))(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$')
                        required:
                        - prefix
                        - signedPrefix
                        type: object
                    required:
                    - matchPolicy
                    type: object
                    x-kubernetes-validations:
                    - message: exactRepository is required when matchPolicy is ExactRepository,
                        and forbidden otherwise
                      rule: '(has(self.matchPolicy) && self.matchPolicy == ''ExactRepository'')
                        ? has(self.exactRepository) : !has(self.exactRepository)'
                    - message: remapIdentity is required when matchPolicy is RemapIdentity,
                        and forbidden otherwise
                      rule: '(has(self.matchPolicy) && self.matchPolicy == ''RemapIdentity'')
                        ? has(self.remapIdentity) : !has(self.remapIdentity)'
                required:
                - rootOfTrust
                type: object
              scopes:
                description: 'scopes defines the list of image identities assigned
                  to a policy. Each item refers to a scope in a registry implementing
                  the "Docker Registry HTTP API V2". Scopes matching individual images
                  are named Docker references in the fully expanded form, either using
                  a tag or digest. For example, docker.io/library/busybox:latest (not
                  busybox:latest). More general scopes are prefixes of individual-image
                  scopes, and specify a repository (by omitting the tag or digest),
                  a repository namespace, or a registry host (by only specifying the
                  host name and possibly a port number) or a wildcard expression starting
                  with `*.`, for matching all subdomains (not including a port number).
                  Wildcards are only supported for subdomain matching, and may not
                  be used in the middle of the host, i.e.  *.example.com is a valid
                  case, but example*.*.com is not. Please be aware that the scopes
                  should not be nested under the repositories of OpenShift Container
                  Platform images. If configured, the policies for OpenShift Container
                  Platform repositories will not be in effect. For additional details
                  about the format, please refer to the document explaining the docker
                  transport field, which can be found at: https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#docker'
                items:
                  maxLength: 512
                  type: string
                  x-kubernetes-validations:
                  - message: invalid image scope format, scope must contain a fully
                      qualified domain name or 'localhost'
                    rule: 'size(self.split(''/'')[0].split(''.'')) == 1 ? self.split(''/'')[0].split(''.'')[0].split('':'')[0]
                      == ''localhost'' : true'
                  - message: invalid image scope with wildcard, a wildcard can only
                      be at the start of the domain and is only supported for subdomain
                      matching, not path matching
                    rule: 'self.contains(''*'') ? self.matches(''^\\*(?:\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$'')
                      : true'
                  - message: invalid repository namespace or image specification in
                      the image scope
                    rule: '!self.contains(''*'') ? self.matches(''^((((?:[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]+)?)|(localhost(?::[0-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,}))?$'')
                      : true'
                maxItems: 256
                type: array
                x-kubernetes-list-type: set
            required:
            - policy
            - scopes
            type: object
          status:
            description: status contains the observed state of the resource.
            properties:
              conditions:
                description: conditions provide details on the status of this API
                  Resource.
                items:
                  description: "Condition contains details for one aspect of the current
                    state of this API Resource. --- This struct is intended for direct
                    use as an array at the field path .status.conditions.  For example,
                    \n type FooStatus struct{ // Represents the observations of a
                    foo's current state. // Known .status.conditions.type are: \"Available\",
                    \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
                    // +listType=map // +listMapKey=type Conditions []metav1.Condition
                    `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
                    protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
                  properties:
                    lastTransitionTime:
                      description: lastTransitionTime is the last time the condition
                        transitioned from one status to another. This should be when
                        the underlying condition changed.  If that is not known, then
                        using the time when the API field changed is acceptable.
                      format: date-time
                      type: string
                    message:
                      description: message is a human readable message indicating
                        details about the transition. This may be an empty string.
                      maxLength: 32768
                      type: string
                    observedGeneration:
                      description: observedGeneration represents the .metadata.generation
                        that the condition was set based upon. For instance, if .metadata.generation
                        is currently 12, but the .status.conditions[x].observedGeneration
                        is 9, the condition is out of date with respect to the current
                        state of the instance.
                      format: int64
                      minimum: 0
                      type: integer
                    reason:
                      description: reason contains a programmatic identifier indicating
                        the reason for the condition's last transition. Producers
                        of specific condition types may define expected values and
                        meanings for this field, and whether the values are considered
                        a guaranteed API. The value should be a CamelCase string.
                        This field may not be empty.
                      maxLength: 1024
                      minLength: 1
                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
                      type: string
                    status:
                      description: status of the condition, one of True, False, Unknown.
                      enum:
                      - "True"
                      - "False"
                      - Unknown
                      type: string
                    type:
                      description: type of condition in CamelCase or in foo.example.com/CamelCase.
                        --- Many .condition.type values are consistent across resources
                        like Available, but because arbitrary conditions can be useful
                        (see .node.status.conditions), the ability to deconflict is
                        important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
                      maxLength: 316
                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
                      type: string
                  required:
                  - lastTransitionTime
                  - message
                  - reason
                  - status
                  - type
                  type: object
                type: array
                x-kubernetes-list-map-keys:
                - type
                x-kubernetes-list-type: map
            type: object
        required:
        - spec
        type: object
    served: true
    storage: true
    subresources:
      status: {}
