Skip to content

Commit 208bf97

Browse files
Sean SundbergAndrew Trice
andauthored
Adds image security enforcement steps in reference/tools (#444)
- Adds a tools page to describe image signing per https://github.ibm.com/gsi-labs/industry-cloud-planning/issues/143 - This documentation is in conjunction with IBM/ibm-garage-tekton-tasks#127 Co-authored-by: Andrew Trice <amtrice@us.ibm.com> Signed-off-by: Sean Sundberg <seansund@us.ibm.com> Co-authored-by: Andrew Trice <amtrice@us.ibm.com>
1 parent d3ef43b commit 208bf97

File tree

3 files changed

+173
-1
lines changed

3 files changed

+173
-1
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Container Image Security Enforcement
2+
3+
Container Image Security Enforcement enables trust within your container workloads.
4+
5+
Container Image Security Enforcement verifies container images before deploying them to a cluster. You can control where images are deployed from, enforce Vulnerability Advisor policies, and ensure that content trust is properly applied to the image. If an image does not meet your policy requirements, the pod is not deployed to your cluster or updated.
6+
7+
Container Image security is applied on a per-cluster basis. This can be enabled in for a cluster in IBM Cloud in a single command using the [IBM Cloud CLI](https://cloud.ibm.com/docs/cli).
8+
9+
```shell
10+
ibmcloud oc cluster image-security enable -c <cluster name>
11+
```
12+
13+
This command will configure the cluster to use Container Image Security, which installs [Portieris](https://github.com/IBM/portieris) in the cluster, and will also create `ClusterImagePolicy` instances to enforce signatures for IBM Cloud images.
14+
15+
Portieris is a Kubernetes admission controller for the enforcement of image security policies. With Portieris you can create image security policies either for each Kubernetes namespace or at the cluster level, and enforce different rules for different images. Portieris will block deployment for any image that fails signature validation as defined by the image policies. Thus ensuring that the images running inside of your cluster are unmodified from their original source.
16+
17+
18+
!!!note
19+
Portieris can be used in clusters that are not running on IBM Cloud by <a href="https://github.com/IBM/portieris#installing-portieris">installing via the helm chart</a>.
20+
21+
## Enabling Policy Enforcement
22+
23+
Portieris uses [RedHat Signatures](https://www.redhat.com/en/blog/container-image-signing) to sign container images.
24+
25+
To take advantage of Portieris and policy enforcement, you need 3 things:
26+
1. A GnuPG key to sign container images, stored in a vault
27+
2. A process to sign container images using the key from the credentials vault
28+
3. An `ImagePolicy` or `ClusterImagePolicy` that can instruct Portieris to apply enforcemnt rules
29+
30+
The following steps are based on [signing images for trusted content](https://cloud.ibm.com/docs/Registry?topic=Registry-registry_trustedcontent).
31+
32+
### Getting started quickly
33+
34+
A script that demonstrates how to easily create a GPG key, publish it to a vault, setup cluster secrets, and setup a default ClusterImagePolicy (as described below) is available at https://github.com/IBM/ibm-garage-tekton-tasks/blob/image-signing/utilities/setup-image-signing-keys.sh
35+
36+
The [toolkit's 2-build-tag-push.yaml](https://github.com/IBM/ibm-garage-tekton-tasks/blob/main/tasks/2-build-tag-push.yaml) tekton task has also been updated to accept the output of this script and enforce signatures during the builder's push phase.
37+
38+
### Create an Image Signing Key
39+
40+
An image signing key must be created to sign the container images. This can be done by executing the following command:
41+
42+
```shell
43+
gpg --generate-key
44+
```
45+
46+
This will create a public and private key combination that can be used to sign and verify container images. The output of the `gpg --generate-key` command will show the fingerprint of the newly generated key. This fingerprint will be needed in the following steps.
47+
48+
#### Saving the private key in a vault
49+
50+
51+
Once your key has been generated, the private key should be stored within a credentials vault, such as [Key Protect](/tools/secret-management-with-key-protect) or [IBM HyperProtect Crypto Services](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-overview).
52+
53+
The private key should be placed in the vault as a base64 encoded string, which can be accessed by your [Tekton](/tools/tekton) pipeline during the image building task.
54+
55+
To place the private key in a vault
56+
57+
```shell
58+
ENCODED_PRIVATE_KEY=$(gpg --export-secret-key <KEY_FINGERPRINT> | base64)
59+
60+
curl -X POST https://<region>.kms.cloud.ibm.com/api/v2/keys \
61+
-H 'authorization: Bearer <IAM_token>' \
62+
-H 'bluemix-instance: <instance_ID>' \
63+
-H 'content-type: application/vnd.ibm.kms.key+json' \
64+
-d "{
65+
\"metadata\": {
66+
\"collectionType\": \"application/vnd.ibm.kms.key+json\",
67+
\"collectionTotal\": 1
68+
},
69+
\"resources\": [
70+
{
71+
\"type\": \"application/vnd.ibm.kms.key+json\",
72+
\"name\": \"image-signing-key\",
73+
\"aliases\": [],
74+
\"description\": \"Private key for signing container images\",
75+
\"payload\": \"$ENCODED_PRIVATE_KEY\",
76+
\"extractable\": true
77+
}
78+
]
79+
}"
80+
```
81+
82+
Both [Key Protect](https://cloud.ibm.com/apidocs/key-protect) and [Hyper Protect Crypto Services](https://cloud.ibm.com/apidocs/hs-crypto) have an identical API, so the previous steps are identical except that a different API endpoint is used.
83+
84+
#### Saving the public key
85+
86+
The public key needs to be made available to the cluster for verifying container image signatures by either creating a secret within the cluster, or making the public key available through [Artifactory](/tools/artifactory/).
87+
88+
Use the following commands to make the public key available for policy enforcement by creating a secret within the cluster:
89+
90+
```shell
91+
gpg --export --armour <KEY_FINGERPRINT> > key.pubkey
92+
oc create secret generic image-signing-public-key --from-file=key=key.pubkey
93+
```
94+
95+
### Signing container images
96+
97+
Container image policy enforcement will reject images that are not signed, so you need to sign images either when they are pushed to the container registry. This can be done using either the `skopeo copy` command or `buildah push` command, depending when you want to sign your images.
98+
99+
#### Extracting the private key for signing
100+
101+
The follwoing commands can be used to access your private key from the vault, and import it into gpg for use in signing. This would be used inside of your pipeline:
102+
103+
```shell
104+
echo "Getting private key from keystore for image signing"
105+
curl -s -o payload \
106+
https://<region>.kms.cloud.ibm.com/api/v2/keys/<key_ID_or_alias> \
107+
-H "Authorization: Bearer <IAM_token>" \
108+
-H "Content-Type: application/json" \
109+
-H "bluemix-instance: <instance_ID>"
110+
111+
ENCODEDKEY=$(jq ".resources[0].payload" -r payload)
112+
echo $ENCODEDKEY > encodedkey
113+
base64 -d encodedkey > decodedkey
114+
115+
echo "Importing key"
116+
gpg --import decodedkey
117+
```
118+
119+
Once the key is imported, then the image can be signed. If the image is being signed at build time, the signature can be specified by the `--sign-by` paramter to the `buidah` command:
120+
121+
```shell
122+
buildah --sign-by <KEY_FINGERPRINT> --storage-driver=overlay push --digestfile ./image-digest ${APP_IMAGE} docker://${APP_IMAGE}
123+
```
124+
125+
If the image is being signed at copy-time, it can be specified as a parameter to the `skopeo` command:
126+
127+
```shell
128+
skopeo --sign-by <KEY_FINGERPRINT> copy ${IMAGE_FROM_CREDS} docker://${IMAGE_FROM} docker://${IMAGE_TO}
129+
```
130+
131+
### Create image policies
132+
133+
Finally, image policies need to be created to instruct Portieris which keys should be used to sign images from specific container registries. These policies can be applied globally to the entire cluster using a `ClusterImagePolicy`, or to a specific namespace using an `ImagePolicy`. In those policies, rules can be defined for enforcement for specific container registries/namespaces, or globally to all container registries used by the cluster.
134+
135+
For example, the following `ClusterImagePolicy` enforces a policy that all images in the container registry `icr.io/mynamespace/*` must be signed by the public key that was earlier created and placed into the `image-signing-public-key` cluster secret.
136+
137+
```yaml
138+
apiVersion: portieris.cloud.ibm.com/v1
139+
kind: ClusterImagePolicy
140+
metadata:
141+
name: mynamespace-cluster-image-policy
142+
spec:
143+
repositories:
144+
- name: "icr.io/mynamespace/*"
145+
policy:
146+
simple:
147+
requirements:
148+
- type: "signedBy"
149+
keySecret: image-signing-public-key
150+
```
151+
152+
More information about policies and enforcement can be found in the [Portieris Policies documentation](https://github.com/IBM/portieris/blob/master/POLICIES.md)
153+
154+
155+
## Tekton tasks
156+
157+
A script that demonstrates how to easily create a GPG key, publish it to a vault, setup cluster secrets, and setup a default ClusterImagePolicy is available at https://github.com/IBM/ibm-garage-tekton-tasks/blob/image-signing/utilities/setup-image-signing-keys.sh
158+
159+
The [toolkit's 2-build-tag-push.yaml](https://github.com/IBM/ibm-garage-tekton-tasks/blob/main/tasks/2-build-tag-push.yaml) tekton task has also been updated to accept the output of this script and enforce signatures during the builder's push phase.
160+
161+
162+
## Additional Information
163+
164+
Additional information on trusted content and policy enforcement can be found at:
165+
- [Signing images for trusted content](https://cloud.ibm.com/docs/Registry?topic=Registry-registry_trustedcontent)
166+
- [Gnu Privact Guard (GPG)](https://gnupg.org/)
167+
- [RedHat Signatures](https://www.redhat.com/en/blog/container-image-signing)
168+
- [Portieris](https://github.com/IBM/portieris)
169+
- [Portieris Policies](https://github.com/IBM/portieris/blob/master/POLICIES.md)
170+
- [Key Protect API Docs](https://cloud.ibm.com/apidocs/key-protect)
171+
- [Hyper Protect API Docs](https://cloud.ibm.com/apidocs/hs-crypto)

docs/reference/tools/ibm-cloud-container-registry.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ IBM Cloud Container Registry is not only a Docker registry hosted in IBM Cloud,
103103

104104
[**Vulnerability Advisor**](https://cloud.ibm.com/docs/services/va){: target=_blank} scans images in the registry to search for known security issues and generates reports with advice on how to fix your images and better secure your environment. Lists of the vulnerabilities scanned for are available in [Vulnerable packages](https://cloud.ibm.com/docs/services/va?topic=va-va_index#packages){: target=_blank}. An administrator can specify exemptions that should not be reported. [Running containers are not scanned](https://cloud.ibm.com/docs/services/Registry?topic=registry-registry_release_notes#27jun2019){: target=_blank}, just the images in the registry. In the image lists shown above, the *Security status* column shows the number of issues found; the report will explain them in greater detail. In the console, click on the number of issues for details.
105105

106-
[**Trusted content technology**](https://cloud.ibm.com/docs/services/Registry?topic=registry-registry_trustedcontent){: target=_blank}: IBM Cloud Container Registry supports images signed using [Docker Content Trust (DCT)](https://docs.docker.com/engine/security/trust/content_trust/){: target=_blank}. The signature confirms who built the image, such as the CI tool. The push and pull commands maintain image signatures.
106+
[**Trusted content technology**](https://cloud.ibm.com/docs/services/Registry?topic=registry-registry_trustedcontent): IBM Cloud Container Registry supports images signed using [RedHat Signatures](https://www.redhat.com/en/blog/container-image-signing). The signature confirms who built the image, such as the CI tool. The push and pull commands maintain image signatures.
107107

108108
[**Container Image Security Enforcement**](https://cloud.ibm.com/docs/services/Registry?topic=registry-security_enforce#security_enforce){: target=_blank} verifies container images before deploying them to a cluster. You can control where images are deployed from, enforce Vulnerability Advisor policies, and ensure that content trust is properly applied to the image. If an image does not meet your policy requirements, the pod is not deployed to your cluster or updated.
109109

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ nav:
158158
- OpenShift Pipelines/Tekton: reference/tools/tekton.md
159159
- IBM Container Registry: reference/tools/ibm-cloud-container-registry.md
160160
- IBM Key Protect: reference/tools/key-protect.md
161+
- Container Image Security Enforcement: reference/tools/container-image-security-enforcement.md
161162
- Pipeline Task Reference:
162163
- Pipelines: reference/tasks/pipelines.md
163164
- placeholder: reference/tasks/placeholder.md

0 commit comments

Comments
 (0)