Installation
The policy-controller project
provides an admission controller for Kubernetes that can validate container image
signatures and attestations. The recommended way to install it is with the
official Helm chart.
Prerequisites
- A Kubernetes cluster and
kubectlconfigured to access it. See the policy-controller support policy for the Kubernetes versions each release is tested against. - Helm v3
Install with Helm
Add the Sigstore Helm repository and install the chart:
helm repo add sigstore https://sigstore.github.io/helm-charts
helm repo update
kubectl create namespace cosign-system
helm install policy-controller -n cosign-system sigstore/policy-controller
This deploys the policy-controller admission webhook into the cosign-system
namespace. The chart installs the ClusterImagePolicy and TrustRoot Custom Resource Definitions (CRDs) automatically (installCRDs: true). For the full list of configurable values, see the
chart README.
Verify the installation
Confirm the webhook pods are running:
kubectl get pods -n cosign-system
Enabling policy enforcement
The policy-controller admission controller only validates resources in
namespaces that have chosen to opt-in. Label the namespaces you want protected:
kubectl label namespace my-namespace policy.sigstore.dev/include=true
See the Configure policy-controller admission controller for namespaces instructions for more details.
The webhook validates that container images have been signed, and resolves image tags to digests to ensure the image being run is not different from when it was admitted.
Unmatched images
Images that do not match any ClusterImagePolicy are denied by default. To change this, set no-match-policy in your Helm values:
webhook:
configData:
no-match-policy: warn
Valid values: deny (default), warn, allow. If you didn’t install with Helm, patch the config-policy-controller ConfigMap directly:
kubectl patch configmap config-policy-controller -n cosign-system \
--type merge \
-p '{"data":{"no-match-policy":"warn"}}'
Using a private Sigstore instance (custom TUF root)
If you run a private instance of Sigstore components, you can specify your own
TUF root by mounting your TUF root.json file into the container (for example
by mounting a Secret) and then pointing to it with the --tuf-root argument, as
well as using the --tuf-mirror argument to point to where the TUF mirror is.
There is an optional Secret tuf-root that you can create with key root
containing the root.json file, which gets mounted as /var/run/tuf/root.json.
With the Helm chart, create the Secret and mount it yourself. Create a Secret with your root:
kubectl create secret generic tuf-root -n cosign-system \
--from-file=root=./root.json
Mount the Secret into the webhook container via your Helm values file:
webhook:
volumes:
- name: tuf-root
secret:
secretName: tuf-root
items:
- key: root
path: root.json
volumeMounts:
- name: tuf-root
mountPath: /var/run/tuf
readOnly: true
Then point the webhook at the mounted root:
helm upgrade policy-controller -n cosign-system sigstore/policy-controller --reuse-values \
-f your-values.yaml \
--set webhook.extraArgs.tuf-root=/var/run/tuf/root.json \
--set webhook.extraArgs.tuf-mirror=https://tuf.example.com
To disable TUF entirely (for air-gapped environments or when using only sigstoreKeys-based TrustRoot resources):
helm upgrade policy-controller -n cosign-system sigstore/policy-controller --reuse-values \
--set webhook.extraArgs.disable-tuf=true
Tuning the resync period
The policy-controller resyncs ClusterImagePolicies by default every 10 hours.
Customize the resync period by using the --policy-resync-period argument and
defining a duration for the policy-webhook deployment:
helm upgrade policy-controller -n cosign-system sigstore/policy-controller --reuse-values \
--set webhook.extraArgs.policy-resync-period=2h
See the
Golang time package’s ParseDuration
for example duration string formats. The TrustRoot resync period defaults to 24 hours and is controlled by --trustroot-resync-period.
See the Configuring policy-controller ClusterImagePolicy instructions for more details on configuration.
Test a policy without a cluster
The policy-tester tool validates a ClusterImagePolicy against an image locally, without a running cluster. Download the tester-<os>-<arch> binary for your platform from the releases page, or build it from source:
git clone https://github.com/sigstore/policy-controller
cd policy-controller
make policy-tester
./policy-tester --policy=my-policy.yaml --image=ghcr.io/example/app:v1.0.0