Skip to content

Commit

Permalink
Merge pull request #61 from nirmata/multiple-fixes-for-ga-1.0
Browse files Browse the repository at this point in the history
feat: fixes for release 1.0
  • Loading branch information
JimBugwadia authored Nov 1, 2023
2 parents 5237de0 + 24f36bb commit d437871
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 23 deletions.
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The service manages Notation [trust policies](https://github.com/notaryproject/s

## Image Digest Mutation

To ensure image integrity and prevent tampering, the sevice replaces image tags, which are mutable and can be spoofed, with digests.
To ensure image integrity and prevent tampering, the service replaces image tags, which are mutable and can be spoofed, with digests.

The Kyverno policy passes the `images` variable to the services' `/checkimages` endpoint. The result returns a list of images with their JSON path and digests so Kyverno can mutate each image in the admission payload.

Expand All @@ -33,8 +33,9 @@ Here is an example:
"results": [
{
"name": "container1",
"op": "replace",
"path": "/spec/containers/0",
"image": "ghcr.io/kyverno/test-verify-image@sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105"
"value": "ghcr.io/kyverno/test-verify-image@sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105"
}
]
}
Expand All @@ -47,16 +48,16 @@ mutate:
foreach:
- list: "response.results"
patchesJson6902: |-
- path: {{ element.path }}
op: replace
value: {{ element.image }}
- path: '{{ element.path }}'
op: '{{ element.op }}'
value: '{{ element.value }}'
```
## Attestation Verification
In addition to verifying signatures, the extension service can verify signed metadata i.e. [attestations](https://nirmata.com/2022/03/15/a-map-for-kubernetes-supply-chain-security/).
To verify attestatons, the Kyverno policy can optionally pass a variable called `attestations` in the request:
To verify attestations, the Kyverno policy can optionally pass a variable called `attestations` in the request:

```yaml
- key: attestations
Expand Down Expand Up @@ -94,7 +95,7 @@ The `attestations` variable is a JSON array of where each entry has:
In the example above we are verifying the following:
1. the attestations `sbom/cyclone-dx` and `application/sarif+json` exist for all images
2. the `creationInfo.licenseListVersion` is equal to 3.17 in the SBOM and GPL licenses are not present.
3. the attatestion `application/vnd.cyclonedx` is available for all versions of the `844333597536.dkr.ecr.us-west-2.amazonaws.com/kyverno-demo` image and does not contain GPL licenses.
3. the attestation `application/vnd.cyclonedx` is available for all versions of the `844333597536.dkr.ecr.us-west-2.amazonaws.com/kyverno-demo` image and does not contain GPL licenses.

**NOTE:** The conditions key in the attestations must be escaped with `\` so kyverno does not substitute them before executing the extension service.

Expand All @@ -110,7 +111,7 @@ The cache stores the verification outcomes of images for the trust policy and ve

In a shared cluster, each team may have different signatures and trust policies. To support such use cases, the extension allows configuring multiple [trust policies](https://github.com/notaryproject/specifications/blob/main/specs/trust-store-trust-policy.md#trust-policy) and [trust stores](https://github.com/notaryproject/specifications/blob/main/specs/trust-store-trust-policy.md#trust-store) as Kubernetes custom resources.

The extension service allows specifying what trust policy they want to use for verification thus enabling multi tenancy. Mutliple teams can share one cluster and have different trust policies seperate from each other.
The extension service allows specifying what trust policy they want to use for verification thus enabling multi tenancy. Multiple teams can share one cluster and have different trust policies separate from each other.
To specify the trust policy to use, we can pass the `trustPolicy` variable in the request.
```yaml
- key: trustPolicy
Expand Down Expand Up @@ -174,6 +175,8 @@ notation sign 844333597536.dkr.ecr.us-east-1.amazonaws.com/kyverno-demo:v1 --key
kubectl create -f https://raw.githubusercontent.com/kyverno/kyverno/main/config/install-latest-testing.yaml
```

**Note: Kyverno version should be higher than v1.11.0**

2. Install the kyverno-notation-aws extension service

```sh
Expand Down
6 changes: 3 additions & 3 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ func getRegion(registry string) (string, error) {
return ecrRegion, nil
}

func getAuthFromIRSA(ctx context.Context, ref registry.Reference) (authn.AuthConfig, error) {
func getAuthFromIRSA(ctx context.Context, ref registry.Reference) (*authn.AuthConfig, error) {
awsEcrRegion, err := getRegion(ref.Registry)
if err != nil {
awsEcrRegion = os.Getenv("AWS_REGION")
}

var authConfig authn.AuthConfig
var authConfig *authn.AuthConfig
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(awsEcrRegion))
if err != nil {
return authConfig, errors.Wrapf(err, "failed to load default configuration")
Expand Down Expand Up @@ -72,7 +72,7 @@ func getAuthFromIRSA(ctx context.Context, ref registry.Reference) (authn.AuthCon
return authConfig, fmt.Errorf("invalid authorization token, expected the token to have two parts separated by ':', got %d parts", len(tokenSplit))
}

authConfig = authn.AuthConfig{
authConfig = &authn.AuthConfig{
Username: tokenSplit[0],
Password: tokenSplit[1],
}
Expand Down
9 changes: 6 additions & 3 deletions configs/samples/kyverno-policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ spec:
data:
- key: images
value: "{{images}}"
- key: imageReferences
value:
- "844333597536.dkr.ecr.us-west-2.amazonaws.com*"
- key: trustPolicy
value: "tp-{{request.namespace}}"
- key: attestations
Expand All @@ -50,6 +53,6 @@ spec:
foreach:
- list: "response.results"
patchesJson6902: |-
- path: {{ element.path }}
op: replace
value: {{ element.image }}
- path: '{{ element.path }}'
op: '{{ element.op }}'
value: '{{ element.value }}'
16 changes: 16 additions & 0 deletions configs/samples/test-pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
namespace: test-notation
labels:
app.kubernetes.io/name: MyApp
spec:
containers:
- name: myapp-container
image: 844333597536.dkr.ecr.us-west-2.amazonaws.com/kyverno-demo:v1
initContainers:
- name: init-myservice
image: busybox:1.28
- name: init-mydb
image: busybox:1.28
6 changes: 3 additions & 3 deletions configs/samples/trustpolicy.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apiVersion: notation.nirmata.io/v1alpha1
kind: TrustPolicy
metadata:
name: trustpolicy-sample
name: tp-test-notation
spec:
version: '1.0'
trustPolicyName: tp-test-notation
trustPolicies:
- name: aws-signer-tp
registryScopes:
- "*"
- "844333597536.dkr.ecr.us-west-2.amazonaws.com/kyverno-demo"
signatureVerification:
level: strict
override: {}
Expand All @@ -20,7 +20,7 @@ spec:
apiVersion: notation.nirmata.io/v1alpha1
kind: TrustPolicy
metadata:
name: trustpolicy-sample-fail
name: tp-test-notation-fail
spec:
version: '1.0'
trustPolicyName: tp-test-notation-fail
Expand Down
59 changes: 59 additions & 0 deletions configs/samples/validate-policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-images
spec:
validationFailureAction: Enforce
failurePolicy: Fail
webhookTimeoutSeconds: 30
schemaValidation: false
rules:
- name: call-aws-signer-extension
match:
any:
- resources:
namespaces:
- test-notation
kinds:
- Pod
operations:
- CREATE
- UPDATE
context:
- name: tlscerts
apiCall:
urlPath: "/api/v1/namespaces/kyverno-notation-aws/secrets/svc.kyverno-notation-aws.svc.tls-pair"
jmesPath: "base64_decode( data.\"tls.crt\" )"
- name: response
apiCall:
method: POST
data:
- key: images
value: "{{images}}"
- key: imageReferences
value:
- "844333597536.dkr.ecr.us-west-2.amazonaws.com*"
- key: trustPolicy
value: "tp-{{request.namespace}}"
- key: attestations
value:
- imageReference: "*"
type:
- name: sbom/example
conditions:
all:
- key: \{{creationInfo.licenseListVersion}}
operator: Equals
value: "3.17"
message: invalid license version
service:
url: https://svc.kyverno-notation-aws/checkimages
caBundle: '{{ tlscerts }}'
validate:
message: "{{ response.message }}"
deny:
conditions:
all:
- key: "{{ response.verified }}"
operator: EQUALS
value: false
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/kyverno/kyverno v1.10.2
github.com/kyverno/pkg/certmanager v0.0.10
github.com/kyverno/pkg/tls v0.0.9
github.com/nirmata/kyverno-notation-verifier v0.8.6
github.com/nirmata/kyverno-notation-verifier v0.8.9-0.20231101063150-4808b6668f52
github.com/notaryproject/notation-core-go v1.0.0-rc.4
github.com/pkg/errors v0.9.1
go.uber.org/zap v1.25.0
Expand Down Expand Up @@ -131,6 +131,7 @@ require (
github.com/google/certificate-transparency-go v1.1.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20221030203717-1711cefd7eec // indirect
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20230403180904-b8d1c0a1df12 // indirect
github.com/google/go-github/v45 v45.2.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
Expand Down Expand Up @@ -240,7 +241,7 @@ require (
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.9.1 // indirect
gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/api v0.115.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
Expand Down
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=
github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20221030203717-1711cefd7eec h1:GtokKAIyg0S9Y/60CO+gHUBHwYblbwfaUS3Qr+AejTc=
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20221030203717-1711cefd7eec/go.mod h1:7QLaBZxN+nMCx82XO5R7qPHq0m61liEg8yca68zymHo=
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20230403180904-b8d1c0a1df12 h1:LLLVB/7zCZVKI27rqA7bbZHZJxH1lL2jbLxdomX1Eew=
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20230403180904-b8d1c0a1df12/go.mod h1:CSeefFZsOfyNrYGXDafpWNkf3tUz17nKReR5INPRaMI=
github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI=
Expand Down Expand Up @@ -974,8 +976,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nirmata/kyverno-notation-verifier v0.8.6 h1:bJSIKyJ+CoK8Wop31QLHBz+fbJSg4TOegb17iiX+Zrc=
github.com/nirmata/kyverno-notation-verifier v0.8.6/go.mod h1:o4pf546Qdj5pTit7hJAhfUjnJlXhLKRzND6BGRlc9aE=
github.com/nirmata/kyverno-notation-verifier v0.8.9-0.20231101063150-4808b6668f52 h1:jMBTa93jgI9YxnAGROIMrdw5FtGqZbdCYJ3sEXpgRdk=
github.com/nirmata/kyverno-notation-verifier v0.8.9-0.20231101063150-4808b6668f52/go.mod h1:WEzJe/H49Xo8DhDlNDLKCh5wGb/T8gbv5FM7NoerKqI=
github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ=
github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=
github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE=
Expand Down Expand Up @@ -1824,8 +1826,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc=
gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
Expand Down

0 comments on commit d437871

Please sign in to comment.