Skip to content

Commit c20735d

Browse files
authored
Merge pull request #355 from vaikas/issue-354
Fix issue 354.
2 parents 575355c + f15e269 commit c20735d

12 files changed

+394
-18
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Copyright 2022 The Sigstore Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: Test policy-controller with ClusterImagePolicy TUF disabled
16+
17+
on:
18+
pull_request:
19+
branches: [ 'main', 'release-*' ]
20+
21+
defaults:
22+
run:
23+
shell: bash
24+
25+
permissions: read-all
26+
27+
jobs:
28+
cip-test-no-tuf:
29+
name: ClusterImagePolicy e2e tests TUF disabled
30+
runs-on: ubuntu-latest
31+
32+
strategy:
33+
matrix:
34+
k8s-version:
35+
- v1.22.x
36+
- v1.23.x
37+
- v1.24.x
38+
- v1.25.x
39+
40+
env:
41+
KO_DOCKER_REPO: "registry.local:5000/policy-controller"
42+
SCAFFOLDING_RELEASE_VERSION: "v0.4.12"
43+
GO111MODULE: on
44+
GOFLAGS: -ldflags=-s -ldflags=-w
45+
KOCACHE: ~/ko
46+
COSIGN_EXPERIMENTAL: true
47+
48+
steps:
49+
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v2.4.0
50+
- uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f # v2.2.0
51+
with:
52+
go-version: '1.18'
53+
check-latest: true
54+
55+
# will use the latest release available for ko
56+
- uses: imjasonh/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa # v0.6
57+
58+
- uses: imranismail/setup-kustomize@a76db1c6419124d51470b1e388c4b29476f495f1 # v1.6.1
59+
60+
- name: Install yq
61+
uses: mikefarah/yq@1f0881fb5faf371694bfa108753cda0b824f5037 # v4.27.3
62+
63+
- name: Setup mirror
64+
uses: chainguard-dev/actions/setup-mirror@main
65+
with:
66+
mirror: mirror.gcr.io
67+
68+
- uses: sigstore/cosign-installer@main
69+
with:
70+
cosign-release: 'v1.13.1'
71+
72+
- name: Install cluster + sigstore
73+
uses: sigstore/scaffolding/actions/setup@main
74+
with:
75+
k8s-version: ${{ matrix.k8s-version}}
76+
version: ${{ env.SCAFFOLDING_RELEASE_VERSION }}
77+
78+
- name: Install policy-controller
79+
env:
80+
GIT_HASH: ${{ github.sha }}
81+
GIT_VERSION: ci
82+
LDFLAGS: ""
83+
POLICY_CONTROLLER_YAML: test/kustomize-no-tuf/policy-controller-e2e.yaml
84+
KO_PREFIX: registry.local:5000/policy-controller
85+
POLICY_CONTROLLER_ARCHS: linux/amd64
86+
run: |
87+
make ko-policy-controller
88+
kustomize build test/kustomize-no-tuf | kubectl apply -f -
89+
90+
# Wait for the webhook to come up and become Ready
91+
kubectl rollout status --timeout 5m --namespace cosign-system deployments/webhook
92+
93+
- name: Run Cluster Image Policy Tests that only tests keys, no keyless
94+
timeout-minutes: 15
95+
run: |
96+
./test/e2e_test_cluster_image_policy_no_tuf.sh
97+
98+
- name: Collect diagnostics
99+
if: ${{ failure() }}
100+
uses: chainguard-dev/actions/kind-diag@84c993eaf02da1c325854fb272a4df9184bd80fc # main

.github/workflows/kind-cluster-image-policy.yaml

+4-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545

4646
env:
4747
KO_DOCKER_REPO: "registry.local:5000/policy-controller"
48-
SCAFFOLDING_RELEASE_VERSION: "v0.4.8"
48+
SCAFFOLDING_RELEASE_VERSION: "v0.4.12"
4949
GO111MODULE: on
5050
GOFLAGS: -ldflags=-s -ldflags=-w
5151
KOCACHE: ~/ko
@@ -71,7 +71,9 @@ jobs:
7171
with:
7272
mirror: mirror.gcr.io
7373

74-
- uses: sigstore/cosign-installer@9becc617647dfa20ae7b1151972e9b3a2c338a2b # v2.3.0
74+
- uses: sigstore/cosign-installer@main
75+
with:
76+
cosign-release: 'v1.13.1'
7577

7678
- name: Install cluster + sigstore
7779
uses: sigstore/scaffolding/actions/setup@main

.github/workflows/kind-e2e-cosigned.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ jobs:
5757
- name: Install yq
5858
uses: mikefarah/yq@5e490527de24715db37869037083f7f391dde5a6 # v4.27.3
5959

60-
- uses: sigstore/cosign-installer@9becc617647dfa20ae7b1151972e9b3a2c338a2b # v2.3.0
60+
- uses: sigstore/cosign-installer@main
61+
with:
62+
cosign-release: 'v1.13.1'
6163

6264
- name: Setup mirror
6365
uses: chainguard-dev/actions/setup-mirror@main

.github/workflows/policy-tester-examples.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ jobs:
4949
run: |
5050
make policy-tester
5151
52-
- name: Install cosign
53-
uses: sigstore/cosign-installer@9becc617647dfa20ae7b1151972e9b3a2c338a2b # v2.5.0
52+
- uses: sigstore/cosign-installer@main
53+
with:
54+
cosign-release: 'v1.13.1'
5455

5556
- name: Setup local registry
5657
run: |

cmd/webhook/main.go

+18-11
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ var webhookName = flag.String("webhook-name", "policy.sigstore.dev", "The name o
6363
var tufMirror = flag.String("tuf-mirror", tuf.DefaultRemoteRoot, "Alternate TUF mirror. If left blank, public sigstore one is used")
6464
var tufRoot = flag.String("tuf-root", "", "Alternate TUF root.json. If left blank, public sigstore one is used")
6565

66+
// Do not initialize TUF at all.
67+
// https://github.com/sigstore/policy-controller/issues/354
68+
var disableTUF = flag.Bool("disable-tuf", false, "Disable TUF support.")
69+
6670
func main() {
6771
opts := webhook.Options{
6872
ServiceName: "webhook",
@@ -76,18 +80,21 @@ func main() {
7680

7781
flag.Parse()
7882

79-
// If they provided an alternate TUF root file to use, read it here.
80-
var tufRootBytes []byte
81-
var err error
82-
if *tufRoot != "" {
83-
tufRootBytes, err = os.ReadFile(*tufRoot)
84-
if err != nil {
85-
logging.FromContext(ctx).Panicf("Failed to read alternate TUF root file %s : %v", *tufRoot, err)
83+
// If TUF has been disabled do not try to set it up.
84+
if !*disableTUF {
85+
// If they provided an alternate TUF root file to use, read it here.
86+
var tufRootBytes []byte
87+
var err error
88+
if *tufRoot != "" {
89+
tufRootBytes, err = os.ReadFile(*tufRoot)
90+
if err != nil {
91+
logging.FromContext(ctx).Panicf("Failed to read alternate TUF root file %s : %v", *tufRoot, err)
92+
}
93+
}
94+
logging.FromContext(ctx).Infof("Initializing TUF root from %s => %s", *tufRoot, *tufMirror)
95+
if err := tuf.Initialize(ctx, *tufMirror, tufRootBytes); err != nil {
96+
logging.FromContext(ctx).Panicf("Failed to initialize TUF client from %s : %v", *tufRoot, err)
8697
}
87-
}
88-
logging.FromContext(ctx).Infof("Initializing TUF root from %s => %s", *tufRoot, *tufMirror)
89-
if err := tuf.Initialize(ctx, *tufMirror, tufRootBytes); err != nil {
90-
logging.FromContext(ctx).Panicf("Failed to initialize TUF client from %s : %v", *tufRoot, err)
9198
}
9299

93100
v := version.GetVersionInfo()

test/e2e_test_cluster_image_policy.sh

+4
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,10 @@ kubectl delete cip --all
545545
kubectl delete ns demo-key-sha512
546546
echo '::endgroup::'
547547

548+
# These tests have been running for awhile now, so grab a new OIDC_TOKEN since
549+
# we've seen them expire in the middle of the tests.
550+
export OIDC_TOKEN=`curl -s ${ISSUER_URL}`
551+
548552
# Publish the first test image
549553
echo '::group:: publish test image demoEphemeralImage'
550554
pushd $(mktemp -d)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright 2022 The Sigstore Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
18+
set -ex
19+
20+
if [[ -z "${KO_DOCKER_REPO}" ]]; then
21+
echo "Must specify env variable KO_DOCKER_REPO"
22+
exit 1
23+
fi
24+
25+
if [[ -z "${FULCIO_URL}" ]]; then
26+
echo "Must specify env variable FULCIO_URL"
27+
exit 1
28+
fi
29+
30+
if [[ -z "${REKOR_URL}" ]]; then
31+
echo "Must specify env variable REKOR_URL"
32+
exit 1
33+
fi
34+
35+
if [[ "${NON_REPRODUCIBLE}"=="1" ]]; then
36+
echo "creating non-reproducible build by adding a timestamp"
37+
export TIMESTAMP=`date +%s`
38+
else
39+
export TIMESTAMP="TIMESTAMP"
40+
fi
41+
42+
# To simplify testing failures, use this function to execute a kubectl to create
43+
# our job and verify that the failure is expected.
44+
assert_error() {
45+
local KUBECTL_OUT_FILE="/tmp/kubectl.failure.out"
46+
match="$@"
47+
echo looking for ${match}
48+
kubectl delete job demo -n ${NS} --ignore-not-found=true
49+
if kubectl create -n ${NS} job demo --image=${demoimage} 2> ${KUBECTL_OUT_FILE} ; then
50+
echo Failed to block expected Job failure!
51+
exit 1
52+
else
53+
echo Successfully blocked Job creation with expected error: "${match}"
54+
if ! grep -q "${match}" ${KUBECTL_OUT_FILE} ; then
55+
echo Did not get expected failure message, wanted "${match}", got
56+
cat ${KUBECTL_OUT_FILE}
57+
exit 1
58+
fi
59+
fi
60+
}
61+
62+
# Publish test image
63+
echo '::group:: publish test image demoimage'
64+
pushd $(mktemp -d)
65+
go mod init example.com/demo
66+
cat <<EOF > main.go
67+
package main
68+
import "fmt"
69+
func main() {
70+
fmt.Println("hello world TIMESTAMP")
71+
}
72+
EOF
73+
74+
sed -i'' -e "s@TIMESTAMP@${TIMESTAMP}@g" main.go
75+
cat main.go
76+
export demoimage=`ko publish -B example.com/demo`
77+
echo Created image $demoimage
78+
popd
79+
echo '::endgroup::'
80+
81+
echo '::group:: Create and label new namespace for verification'
82+
kubectl create namespace demo-no-tuf
83+
kubectl label namespace demo-no-tuf policy.sigstore.dev/include=true
84+
export NS=demo-no-tuf
85+
echo '::endgroup::'
86+
87+
echo '::group:: Generate New Signing Key that we use for key-ful signing'
88+
COSIGN_PASSWORD="" cosign generate-key-pair
89+
echo '::endgroup::'
90+
91+
# Create CIP that requires a signature with a key.
92+
echo '::group:: Create CIP that requires a keyful signature'
93+
yq '. | .spec.authorities[0].key.data |= load_str("cosign.pub")' ./test/testdata/policy-controller/e2e/cip-key-no-rekor.yaml | kubectl apply -f -
94+
95+
# Give the policy controller a moment to update the configmap
96+
# and pick up the change in the admission controller.
97+
sleep 5
98+
echo '::endgroup::'
99+
100+
# This image has not been signed with our key
101+
# so should fail
102+
echo '::group:: test job rejection'
103+
expected_error='no matching signatures'
104+
assert_error ${expected_error}
105+
echo '::endgroup::'
106+
107+
# Sign it with key
108+
echo '::group:: Sign demoimage with key, do not add to rekor'
109+
COSIGN_PASSWORD="" cosign sign --no-tlog-upload --key cosign.key --allow-insecure-registry ${demoimage}
110+
echo '::endgroup::'
111+
112+
# TODO(vaikas): This fails because it doesn't have a Rekor entry. Which it obvs
113+
# does not because of --no-tlog-upload above.
114+
#echo '::group:: Verify demoimage with cosign key'
115+
#cosign verify --key cosign.pub --allow-insecure-registry ${demoimage}
116+
#echo '::endgroup::'
117+
118+
# Then let's test attestations work too with key.
119+
echo '::group:: Create CIP that requires a keyful attestation'
120+
yq '. | .spec.authorities[0].key.data |= load_str("cosign.pub")' ./test/testdata/policy-controller/e2e/cip-key-with-attestations-no-rekor.yaml | kubectl apply -f -
121+
122+
# Give the policy controller a moment to update the configmap
123+
# and pick up the change in the admission controller.
124+
sleep 5
125+
echo '::endgroup::'
126+
127+
# This image has been signed with key, but does not have a key attestation
128+
# so should fail
129+
echo '::group:: test job rejection'
130+
expected_error='no matching attestations'
131+
assert_error ${expected_error}
132+
echo '::endgroup::'
133+
134+
# Fine, so create an attestation for it.
135+
echo '::group:: create keyful attestation, do not add to rekor'
136+
echo -n 'foobar key e2e test' > ./predicate-file-key-custom
137+
COSIGN_PASSWORD="" cosign attest --predicate ./predicate-file-key-custom --key ./cosign.key --allow-insecure-registry --no-tlog-upload ${demoimage}
138+
139+
# TODO(vaikas): This again fails though it really shouldn't.
140+
#cosign verify-attestation --key ./cosign.pub --allow-insecure-registry ${demoimage}
141+
echo '::endgroup::'
142+
143+
export KUBECTL_SUCCESS_FILE="/tmp/kubectl.success.out"
144+
echo '::group:: test job success with key signature and key attestation'
145+
# We signed this with key and it has a key attestation, so should pass.
146+
if ! kubectl create -n ${NS} job demo2 --image=${demoimage} 2> ${KUBECTL_SUCCESS_FILE} ; then
147+
echo Failed to create job with both key signature and attestation
148+
cat ${KUBECTL_SUCCESS_FILE}
149+
exit 1
150+
else
151+
echo Created the job with key signature and an attestation
152+
fi
153+
echo '::endgroup::'
154+
155+
echo '::group::' Cleanup
156+
kubectl delete cip --all
157+
kubectl delete ns ${NS}
158+
rm cosign.key cosign.pub
159+
echo '::endgroup::'

test/e2e_test_cluster_image_policy_with_attestations.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,6 @@ echo '::endgroup::'
268268

269269
echo '::group::' Cleanup
270270
kubectl delete cip --all
271-
kubectl delete ns demo-attestations
271+
kubectl delete ns ${NS}
272272
rm cosign.key cosign.pub
273273
echo '::endgroup::'

test/e2e_test_cluster_image_policy_with_warn.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,5 +198,5 @@ echo '::endgroup::'
198198

199199
echo '::group::' Cleanup
200200
kubectl delete cip --all
201-
kubectl delete ns demo-keyless-signing
201+
kubectl delete ns ${NS}
202202
echo '::endgroup::'

0 commit comments

Comments
 (0)