Skip to content

Latest commit

 

History

History
364 lines (279 loc) · 17.3 KB

POLICIES.md

File metadata and controls

364 lines (279 loc) · 17.3 KB
copyright lastupdated
years
2020, 2022
2022-04-26

Portieris policies

Image policy resources

Portieris defines two custom resource types for policy. Image policy resources and cluster image policy resources.

For both types of resource, if multiple resources exist, they are merged together and can be protected by a role-based access control (RBAC) policy.

  • Image policy resources, ImagePolicy, are configured in a Kubernetes namespace and define Portieris' behavior in that namespace. If image policy resources exist in a namespace, the policies from those image policy resources are used exclusively. If a match doesn't exist for the workload image in ImagePolicy, cluster image policy resources, ClusterImagePolicy, are not examined. Images in deployed workloads are wildcard matched against the set of policies defined, if a policy doesn't match the workload image, deployment is denied.

    The following example allows any image from the icr.io registry with no further checks (the policy is empty).

    apiVersion: portieris.cloud.ibm.com/v1
    kind: ImagePolicy
    metadata:
      name: allow-all-icrio
    spec:
       repositories:
        - name: "icr.io/*"
          policy:
  • Cluster image policy resources, ClusterImagePolicy, are configured at the cluster level, and take effect whenever an image policy resource, ImagePolicy, is not defined in the namespace where the workload is deployed. These cluster image policy resources have the same structure as namespace image policy resources and, if a matching policy is not found for an image, deployment is denied.

    The following example allows all images from all registries with no checks.

    apiVersion: portieris.cloud.ibm.com/v1
    kind: ClusterImagePolicy
    metadata:
      name: portieris-default-cluster-image-policy
    spec:
      repositories:
      - name: '*'
        policy:

Installation default policies

Default policies are installed when Portieris is installed. You must review and change these according to your requirements. You must customize the installation default policies.

Repository matching

When an image is evaluated for admission, the set of policies is wildcard matched on the repository name. If multiple matches are found, the most specific match is used.

Policy

A policy consists of an array of objects that define requirements on the image by using either trust: (Docker Content Trust and Notary v1), simple: (Red Hat Simple Signing), or vulnerability: objects.

Important If your policy was developed before Portieris v0.10.0, the policy has the API version: apiVersion: securityenforcement.admission.cloud.ibm.com/v1beta1 To ensure that the policy is enforced, you must update the API version to: apiVersion: portieris.cloud.ibm.com/v1

Image mutation option

You can also set a mutate image, mutateImage: bool, behavior preference for each policy. The default value is true, which is also the original behavior and means that, on successful admission, the container's image property is mutated to ensure that the immutable digest form of the image is used. If the value is false, the original image reference is retained with the consequences that are described in the readme file.

Example

apiVersion: portieris.cloud.ibm.com/v1
kind: ImagePolicy
metadata:
  name: signedby-me
spec:
   repositories:
    - name: "icr.io/*"
      policy:
        mutateImage: false
        simple:
          requirements:
          - type: "signedBy"
            keySecret: my-pubkey

trust (Docker Content Trust and Notary)

Portieris supports sourcing trust data from the following registries without additional configuration in the image policy:

  • IBM Cloud® Container Registry
  • Quay.io
  • Docker Hub

To use a different trust server for a repository, you can specify the trustServer parameter in your policy:

Example

apiVersion: portieris.cloud.ibm.com/v1
kind: ImagePolicy
metadata:
  name: allow-custom
spec:
   repositories:
    - name: "icr.io/*"
      policy:
        trust:
          enabled: true
          trustServer: "https://icr.io:4443" # Optional, custom trust server for repository

For more information, see Customizing policies.

Specifying trusted content signers in custom policies

If you use content trust, you can verify that images are signed by particular signers. Deployment is allowed only if the most recent signed version is signed by all the listed signers. To add a signer to a repository, see Managing trusted signers.

To configure the policy to verify that an image is signed by a particular signer:

  1. Get the signer name (the name that was used in docker trust signer add), and the signer's public key.

  2. Generate a Kubernetes secret with the signer name and their public key.

    kubectl create secret generic <secret_name> --from-literal=name=<signer_name> --from-file=publicKey=<key.pub>
    
  3. Add the secret to the signerSecrets list for the repository in your policy.

    - name: example
      policy:
        trust:
          enabled: true
          signerSecrets:
          - name: <secret_name>

simple (Red Hat simple signing)

The policy requirements are similar to those requirements defined for the configuration files that are consulted when you're using the Red Hat® tools policy requirements. However, the main difference is that the public key in a signedBy requirement is defined in a keySecret attribute, the value is the name of an in-scope Kubernetes secret that contains a public key block. The value of keyType, keyPath, and keyData, see policy requirements, can't be provided. If multiple keys are present in the key ring, the requirement is satisfied if the signature is signed by any one of them.

To export one, or more, public keys that are identified by <finger-print>, to a key ring, from GNU Privacy Guard (GPG) and create a KeySecret from it, you can use the following script.

gpg --export --armour <finger-print> [<finger-print>] > my.pubkey
kubectl create secret generic my-pubkey --from-file=key=my.pubkey

When you create the secret, ensure that you're creating the key with a value of key.

kubectl create secret generic my-pubkey --from-file=key=<your_pub_key_file>

The following example requires that images from icr.io are signed by the identity with its public key in my-pubkey. If multiple public keys are present in my-pubkey, the image is required to be signed by any one of them.

apiVersion: portieris.cloud.ibm.com/v1
kind: ImagePolicy
metadata:
  name: signedby-me
spec:
   repositories:
    - name: "icr.io/*"
      policy:
        simple:
          requirements:
          - type: "signedBy"
            keySecret: my-pubkey

The following example requires that images from icr.io are signed by the identity with public key in my-pubkey and the identity with public key in your-pubkey.

apiVersion: portieris.cloud.ibm.com/v1
kind: ImagePolicy
metadata:
  name: signedby-me
spec:
   repositories:
    - name: "icr.io/*"
      policy:
        simple:
          requirements:
          - type: "signedBy"
            keySecret: my-pubkey
          - type: "signedBy"
            keySecret: your-pubkey

The following example requires that a specific image is signed, but it allows the registry location to change. In this pattern, a policy for each image is required to exactly define the new location.

apiVersion: portieris.cloud.ibm.com/v1
kind: ImagePolicy
metadata:
  name: db2mirror
spec:
   repositories:
    - name: "uk.icr.io/mymirror/db2/db2manager:6.1.0.0"
      policy:
        simple:
          requirements:
          - type: "signedBy"
            keySecret: db2-pubkey
            signedIdentity:
                type: "matchExactRepository"
                dockerRepository: "icr.io/ibm/db2/db2manager"

The following example allows many images with a common origin that moved with their original signature, for example, by mirroring, in this case from icr.io/db2 to registry.myco.com:5000/mymirror/ibmdb2.

apiVersion: portieris.cloud.ibm.com/v1
kind: ImagePolicy
metadata:
  name: remapDB2Example
spec:
   repositories:
    - name: "registry.myco.com:5000/mymirror/ibmdb2"
      policy:
        simple:
          requirements:
          - type: "signedBy"
            keySecret: db2-pubkey
            signedIdentity:
                type: "remapIdentity"
                prefix: "registry.myco.com:5000/mymirror/ibmdb2"
                signedPrefix: "icr.io/db2"

You can also specify the location of signature storage for registries that don't support the registry extension. Where storeSecret identifies an in-scope Kubernetes secret that contains username and password data items that are used to authenticate with the server referenced in storeURL.

apiVersion: portieris.cloud.ibm.com/v1
kind: ImagePolicy
metadata:
  name: db2mirror
spec:
   repositories:
    - name: "uk.icr.io/mymirror/db2/db2manager:6.1.0.0"
      policy:
        simple:
          storeURL: https://server.another.com/signatures
          storeSecret: another-secret
          requirements:
          - type: "signedBy"
            keySecret: db2-pubkey

vulnerability

Vulnerability policies enable you to admit or deny pod admission based on the security status of the container images within the pod. Vulnerability-based admission is available for Vulnerability Advisor for IBM Cloud Container Registry. Vulnerability Advisor is available for any image in IBM Cloud Container Registry.

Example policy:

apiVersion: portieris.cloud.ibm.com/v1
kind: ImagePolicy
metadata:
  name: block-vulnerable-images
spec:
   repositories:
    - name: "uk.icr.io/*"
      policy:
        vulnerability:
          ICCRVA:
            enabled: true
            account: "an-IBM-Cloud-account-id"

Vulnerability Advisor for IBM Cloud Container Registry details

For each container in the pod that is being considered for admission, a vulnerability status report is retrieved for the image that is specified by the container.

The optional account parameter specifies the IBM Cloud® account from where exemptions are retrieved for images that match the policy repository name.

If the report returns an overall status of OK, WARN, or UNSUPPORTED the pod is allowed. In the event of any other status, or any error condition, the pod is denied.

Note Recently pushed images to the registry that have not completed scanning are denied admission.

Customizing policies

You can change the policy that Portieris uses to permit images, either at the cluster or Kubernetes namespace level. In the policy, you can specify different enforcement rules for different images.

Tip You must have a policy set. Otherwise, deployments to your cluster fail. If you don't want to enforce any image security policies, Uninstall Portieris.

When you apply a deployment, Portieris checks whether the Kubernetes namespace that you are deploying to has a policy to apply. If it does not, Portieris uses the cluster-wide policy. Your deployment is denied if no namespace or cluster-wide policy exists.

The following table explains the .yaml properties that you must set in your Kubernetes custom resource definition .yaml file.

Field Description
kind For a cluster-wide policy, specify the kind as ClusterImagePolicy. For a Kubernetes namespace policy, specify as ImagePolicy.
//metadata/name Name the custom resource definition.
//spec/repositories/name[@*] Specify the repositories to allow images from. Wildcards (*) are allowed in repository names. Repositories are denied unless a matching entry in repositories allows it or applies further verification. An empty repositories list blocks deployment of all images. To allow all images without verification of any policies, set the name to * and omit the policy subsections.
//spec/repositories/name[@*]/policy Complete the subsections for trust and va enforcement. If you omit the policy subsections, it is equivalent to specifying enabled: false for each.
//spec/repositories/name[@*]/policy/trust/enabled Set as true to allow only images that are signed for content trust to be deployed. Set as false to ignore whether images are signed.
//spec/repositories/name[@*]/policy/trust/signerSecrets/name If you want to allow only images that are signed by particular users, specify the Kubernetes secret with the signer name. Omit this field or leave it empty to verify that images are signed without enforcing particular signers. For more information, see Specifying trusted content signers in custom policies.
//spec/repositories/name[@*]/policy/va/enabled Set as true to allow only images that pass the Vulnerability Advisor scan. Set as false to ignore the Vulnerability Advisor scan.

Table 1. Understanding the .yaml properties for the Kubernetes custom resource definition.

Field Description
//spec/repositories/name[@*]/policy/simple/requirements/type/insecureAcceptAnything This option accepts any image where signature validation isn't required. For more information, see insecureAcceptAnything.
//spec/repositories/name[@*]/policy/simple/requirements/type/reject This option rejects all images and signatures. For more information, see reject.
//spec/repositories/name[@*]/policy/simple/requirements/type/signedBy This option ensures that the image is signed with an expected identity and key. Valid options for this field are: matchExact, matchRepoDigestOrExact, matchRepository, exactReference, exactRepository, and remapIdentity. For more information about these options, see signedBy.

Table 2. Understanding the .yaml components for the Kubernetes custom resource definition for simple.

For more information, see Policy Requirements.

To customize your policies, complete the following steps:

  1. Create a Kubernetes custom resource definition .yaml file. For more information, see Table 1.

    apiVersion: portieris.cloud.ibm.com/v1
    kind: <ClusterImagePolicy_or_ImagePolicy>
    metadata:
      name: <crd_name>
    spec:
      repositories:
        - name: <repository_name>
          policy:
          trust:
              enabled: <true_or_false>
              signerSecrets:
              - name: <secret_name>
          va:
              enabled: <true_or_false>
  2. Apply the .yaml file to your cluster.

    kubectl apply -f <filepath>
    

Controlling who can customize policies

If role-based access control (RBAC) is enabled on your Kubernetes cluster, you can create a role to govern who can administer security policies on your cluster. For more information about applying RBAC rules to your cluster, see Using RBAC Authorization.

  • In your role, add a rule for security policies:

    - apiGroups: ["portieris.cloud.ibm.com"]
      resources: ["imagepolicies", "clusterimagepolicies"]
      verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]

    Tip You can create multiple roles to control what actions users can take. For example, change the verbs so that some users can use only the get or list policies. Alternatively, you can omit clusterimagepolicies from the resources list to grant access only to Kubernetes namespace policies.

  • Users who have access to delete custom resource definitions (CRDs) can delete the resource definition for security policies, which also deletes your security policies. Make sure to control who is allowed to delete CRDs. To grant access to delete CRDs, add a rule:

    - apiGroups: ["apiextensions.k8s.io/v1"]
      resources: ["CustomResourceDefinition"]
      verbs: ["delete"]

    Tip Users and Service Accounts with the cluster-admin role have access to all resources. The cluster-admin role grants access to administer security policies, even if you do not edit the role. Make sure to control who has the cluster-admin role, and grant access only to people that you want to allow to modify security policies.