1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00
kyverno/pkg/cosign/cosign.go
Jim Bugwadia 13caaed8b7
Feature/cosign (#2078)
* add image verification

* inline policy list

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* cosign version and dependencies updates

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add registry initialization

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add build tag to exclude k8schain for cloud providers

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add build tag to exclude k8schain for cloud providers

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* generate deep copy and other fixtures

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix deep copy issues

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* mutate images to add digest

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add certificates to Kyverno container for HTTPS lookups

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* align flag syntax

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update docs

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update dependencies

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update dependencies

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* patch image with digest and fix checks

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* hardcode image for demos

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add default registry (docker.io) before calling reference.Parse

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix definition

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* increase webhook timeout

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix args

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* run gofmt

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* rename for clarity

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix HasImageVerify check

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* align make test commands

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* align make test commands

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* align make test commands

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix linter error

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* format

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* handle API conflict and retry

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* format

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix reviewdog issues

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix make for unit tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* improve error message

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix durations

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* handle errors in tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* print policy name

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add retries and duration to error log

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix time check in tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* round creation times in test

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix retry loop

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove timing check for policy creation

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix e2e error - policy not found

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* update string comparison method

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* fix test Generate_Namespace_Label_Actions

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* add debug info for e2e tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix error

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix generate bug

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix format

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add check for update operations

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* increase time for deleteing a resource

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix check

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

Co-authored-by: Shuting Zhao <shutting06@gmail.com>
2021-07-09 18:01:46 -07:00

116 lines
3.3 KiB
Go

package cosign
import (
"context"
"crypto"
"encoding/json"
"fmt"
"github.com/go-logr/logr"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/authn/k8schain"
"github.com/google/go-containerregistry/pkg/name"
"github.com/pkg/errors"
"github.com/sigstore/cosign/pkg/cosign"
"github.com/sigstore/sigstore/pkg/signature"
"k8s.io/client-go/kubernetes"
)
// Initialize loads the image pull secrets and initializes the default auth method for container registry API calls
func Initialize(client kubernetes.Interface, namespace, serviceAccount string, imagePullSecrets []string) error {
var kc authn.Keychain
kcOpts := &k8schain.Options{
Namespace: namespace,
ServiceAccountName: serviceAccount,
ImagePullSecrets: imagePullSecrets,
}
kc, err := k8schain.New(context.Background(), client, *kcOpts)
if err != nil {
return errors.Wrap(err, "failed to initialize registry keychain")
}
authn.DefaultKeychain = kc
return nil
}
func Verify(imageRef string, key []byte, log logr.Logger) (digest string, err error) {
pubKey, err := decodePEM(key)
if err != nil {
return "", errors.Wrapf(err, "failed to decode PEM %v", string(key))
}
cosignOpts := &cosign.CheckOpts{
Annotations: map[string]interface{}{},
Claims: false,
Tlog: false,
Roots: nil,
PubKey: pubKey,
}
ref, err := name.ParseReference(imageRef)
if err != nil {
return "", errors.Wrap(err, "failed to parse image")
}
verified, err := cosign.Verify(context.Background(), ref, cosignOpts, "https://rekor.sigstore.dev")
if err != nil {
return "", errors.Wrap(err, "failed to verify image")
}
digest, err = extractDigest(imageRef, verified, log)
if err != nil {
return "", errors.Wrap(err, "failed to get digest")
}
return digest, nil
}
func decodePEM(raw []byte) (pub cosign.PublicKey, err error) {
// PEM encoded file.
ed, err := cosign.PemToECDSAKey(raw)
if err != nil {
return nil, errors.Wrap(err, "pem to ecdsa")
}
return signature.ECDSAVerifier{Key: ed, HashAlg: crypto.SHA256}, nil
}
func extractDigest(imgRef string, verified []cosign.SignedPayload, log logr.Logger) (string, error) {
var jsonMap map[string]interface{}
for _, vp := range verified {
if err := json.Unmarshal(vp.Payload, &jsonMap); err != nil {
return "", err
}
log.V(4).Info("image verification response", "image", imgRef, "payload", jsonMap)
// The cosign response is in the JSON format:
// {
// "critical": {
// "identity": {
// "docker-reference": "registry-v2.nirmata.io/pause"
// },
// "image": {
// "docker-manifest-digest": "sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108"
// },
// "type": "cosign container image signature"
// },
// "optional": null
// }
critical := jsonMap["critical"].(map[string]interface{})
if critical != nil {
typeStr := critical["type"].(string)
if typeStr == "cosign container image signature" {
identity := critical["identity"].(map[string]interface{})
if identity != nil {
image := critical["image"].(map[string]interface{})
if image != nil {
return image["docker-manifest-digest"].(string), nil
}
}
}
}
}
return "", fmt.Errorf("digest not found for " + imgRef)
}