- Valid image in some registry, say something like
docker.io:/jonnyman9/hello-node:latest
- Valid signature being served by some signature server, say something like
https://sigserver.com
- You have access to the public PGP key used to sign the image, say something like
pubring.gpg
There really only is 1 important file we need, the machine-config.yaml
that forces the host to verify the image against some signature when pulling it in. This one file however is made up of 3 smaller components:
pubring.gpg
default.yaml
policy.json
Let's look at each in detail.
The PGP/GPG public key that was used to create the signature.
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFqHrTIBCAC38ftILiXtiSLkKrRpuilHWf+oBio1Lm11BryqwNmbm4boDBEH
zkNkqquOryPnDRVyKqSbPxDP6OdEeuoRAhFaWCijVHj+BHELhI9XXqMP8+DJjpoo
gmqF9BcQf+nKz4bb+HG5jB5FMN02O6Xgv+RER3avrRrmo4uQVpIrzuSVJ1qLgYn/
Zz0mW9o6w7cxdOqKKTBaMNrYlo4qVh9nq1oZ5JxXZ7rtDjAzBtOCsHFE7pPW43PM
ZToTw27o2PbdBCJqnUVYGAJvd//wqyELL+0lI+gkgispQUz3quwctCufGKxSg0L7
klACtLAGLa4Orz0WmicR4976z7LJLvex+95hABEBAAG0IW9wZW5zaGlmdCA8b3Bl
bnNoaWZ0QGV4YW1wbGUuY29tPokBOQQTAQIAIwUCWoetMgIbLwcLCQgHAwIBBhUI
AgkKCwQWAgMBAh4BAheAAAoJED/8ykA1UK0V+qUIALCUVSVAfkkscpl61M616XK/
QA7piViIxJzIzs0XBYI0W4NuIEpJog/1gkQjmngKowZOMVWd5eki7EEDB48T0+aR
3/2n2MSqU8JI9FXiT8LqcbNWmc6IN89RatPce9oHcjaB39/BWuMP1p47o1zmcURf
jzCt+7nKsoE4utWg3OC8G2xhiTRmGeyJfH35whBVCGV1mtXa6AYwj0f+kKW7n/NR
Roi0Q3oK5Gewn0UfX/gWNiLumwADCCFE7rBIxOmOcouQHe9bEe+2vfCkOG0mfdVP
A7c8gzI9ptC1caydQRL+CHtZ+TmcNhWXOz66KVoKAUJFj5V0+GP93MNcq+0xg+0=
=Bh2m
-----END PGP PUBLIC KEY BLOCK-----
This configures where the signature server is.
docker:
docker.io:
sigstore: https://sigserver.com
This configures where to look for the public key.
{
"default": [{
"type": "insecureAcceptAnything"
}],
"transports": {
"docker": {
"docker.io": [{
"type": "signedBy",
"keyType": "GPGKeys",
"keyPath": "/root/pubkey.gpg"
}]
},
"docker-daemon": {
"": [{"type":"insecureAcceptAnything"}]
}
}
}
This is the real file we need. We take the files above and can use some a bit of python to create what we need to put into the file.
cat pubkey.gpg | python3 -c "import sys, urllib.parse; print(urllib.parse.quote(''.join(sys.stdin.readlines())))"
cat default.yaml | python3 -c "import sys, urllib.parse; print(urllib.parse.quote(''.join(sys.stdin.readlines())))"
cat policy.json | python3 -c "import sys, urllib.parse; print(urllib.parse.quote(''.join(sys.stdin.readlines())))"
After you cat
each file, grab the output and paste it into your machine-config.yaml
so that yours matches below. Don't forget to prepend with data:,
.
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
labels:
machineconfiguration.openshift.io/role: worker
name: 50-worker-signatures
spec:
config:
ignition:
version: 2.2.0
storage:
files:
- path: /etc/containers/policy.json
mode: 0644
filesystem: root
contents:
source: data:,%7B%0A%20%20%20%20%22default%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22insecureAcceptAnything%22%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22transports%22%3A%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22docker%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22docker.io%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22signedBy%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22keyType%22%3A%20%22GPGKeys%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22keyPath%22%3A%20%22/root/pubkey.gpg%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22docker-daemon%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%3A%20%5B%7B%22type%22%3A%22insecureAcceptAnything%22%7D%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%7D%0A
- path: /etc/containers/registries.d/default.yaml
mode: 0644
filesystem: root
contents:
source: data:,docker%3A%0A%20%20docker.io%3A%0A%20%20%20%20sigstore%3A%20http%3A//sigstore-service%3A8080%0A
- path: /root/pubkey.gpg
mode: 0644
filesystem: root
contents:
source: data:,-----BEGIN%20PGP%20PUBLIC%20KEY%20BLOCK-----%0A%0AmQENBFqHrTIBCAC38ftILiXtiSLkKrRpuilHWf%2BoBio1Lm11BryqwNmbm4boDBEH%0AzkNkqquOryPnDRVyKqSbPxDP6OdEeuoRAhFaWCijVHj%2BBHELhI9XXqMP8%2BDJjpoo%0AgmqF9BcQf%2BnKz4bb%2BHG5jB5FMN02O6Xgv%2BRER3avrRrmo4uQVpIrzuSVJ1qLgYn/%0AZz0mW9o6w7cxdOqKKTBaMNrYlo4qVh9nq1oZ5JxXZ7rtDjAzBtOCsHFE7pPW43PM%0AZToTw27o2PbdBCJqnUVYGAJvd//wqyELL%2B0lI%2BgkgispQUz3quwctCufGKxSg0L7%0AklACtLAGLa4Orz0WmicR4976z7LJLvex%2B95hABEBAAG0IW9wZW5zaGlmdCA8b3Bl%0AbnNoaWZ0QGV4YW1wbGUuY29tPokBOQQTAQIAIwUCWoetMgIbLwcLCQgHAwIBBhUI%0AAgkKCwQWAgMBAh4BAheAAAoJED/8ykA1UK0V%2BqUIALCUVSVAfkkscpl61M616XK/%0AQA7piViIxJzIzs0XBYI0W4NuIEpJog/1gkQjmngKowZOMVWd5eki7EEDB48T0%2BaR%0A3/2n2MSqU8JI9FXiT8LqcbNWmc6IN89RatPce9oHcjaB39/BWuMP1p47o1zmcURf%0AjzCt%2B7nKsoE4utWg3OC8G2xhiTRmGeyJfH35whBVCGV1mtXa6AYwj0f%2BkKW7n/NR%0ARoi0Q3oK5Gewn0UfX/gWNiLumwADCCFE7rBIxOmOcouQHe9bEe%2B2vfCkOG0mfdVP%0AA7c8gzI9ptC1caydQRL%2BCHtZ%2BTmcNhWXOz66KVoKAUJFj5V0%2BGP93MNcq%2B0xg%2B0%3D%0A%3DBh2m%0A-----END%20PGP%20PUBLIC%20KEY%20BLOCK-----%0A
After, apply this file to your cluster, warning this takes a while.
oc apply -f ./machine-config.yaml
Try and deploy any app in OpenShift using an image from docker.io
and see it succeed if your signatures are available and valid, and see it fail if not.
oc new-project example-app
oc new-app docker.io/jonnyman9/hello-node:latest