mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-15 20:20:22 +00:00
feat: add support for sigstore bundle verification (#10567)
* feat: add support for sigstore bundle verification Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: missed change Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: ci Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: linter Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: another linter Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: add size check in layer Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> --------- Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> Co-authored-by: shuting <shuting@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
f69ffe12ec
commit
06ffd1c961
35 changed files with 710 additions and 46 deletions
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageVerificationType selects the type of verification algorithm
|
// ImageVerificationType selects the type of verification algorithm
|
||||||
// +kubebuilder:validation:Enum=Cosign;Notary
|
// +kubebuilder:validation:Enum=Cosign;SigstoreBundle;Notary
|
||||||
// +kubebuilder:default=Cosign
|
// +kubebuilder:default=Cosign
|
||||||
type ImageVerificationType string
|
type ImageVerificationType string
|
||||||
|
|
||||||
|
@ -18,8 +18,9 @@ type ImageVerificationType string
|
||||||
type ImageRegistryCredentialsProvidersType string
|
type ImageRegistryCredentialsProvidersType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Cosign ImageVerificationType = "Cosign"
|
Cosign ImageVerificationType = "Cosign"
|
||||||
Notary ImageVerificationType = "Notary"
|
SigstoreBundle ImageVerificationType = "SigstoreBundle"
|
||||||
|
Notary ImageVerificationType = "Notary"
|
||||||
|
|
||||||
DEFAULT ImageRegistryCredentialsProvidersType = "default"
|
DEFAULT ImageRegistryCredentialsProvidersType = "default"
|
||||||
AWS ImageRegistryCredentialsProvidersType = "amazon"
|
AWS ImageRegistryCredentialsProvidersType = "amazon"
|
||||||
|
@ -46,7 +47,7 @@ type ImageVerification struct {
|
||||||
ValidationFailureAction *ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
|
ValidationFailureAction *ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
|
||||||
|
|
||||||
// Type specifies the method of signature validation. The allowed options
|
// Type specifies the method of signature validation. The allowed options
|
||||||
// are Cosign and Notary. By default Cosign is used if a type is not specified.
|
// are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
// +kubebuilder:validation:Optional
|
// +kubebuilder:validation:Optional
|
||||||
Type ImageVerificationType `json:"type,omitempty" yaml:"type,omitempty"`
|
Type ImageVerificationType `json:"type,omitempty" yaml:"type,omitempty"`
|
||||||
|
|
||||||
|
|
|
@ -4295,9 +4295,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -8715,9 +8716,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -12879,6 +12881,7 @@ spec:
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -17296,9 +17299,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
|
|
@ -4296,9 +4296,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -8717,9 +8718,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -12882,6 +12884,7 @@ spec:
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -17299,9 +17302,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
|
|
@ -4289,9 +4289,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -8709,9 +8710,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -12873,6 +12875,7 @@ spec:
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -17290,9 +17293,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
|
|
@ -4290,9 +4290,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -8711,9 +8712,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -12876,6 +12878,7 @@ spec:
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -17293,9 +17296,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
|
|
@ -4289,9 +4289,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -8709,9 +8710,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -12873,6 +12875,7 @@ spec:
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -17290,9 +17293,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
|
|
@ -4290,9 +4290,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -8711,9 +8712,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -12876,6 +12878,7 @@ spec:
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -17293,9 +17296,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
|
|
@ -9487,9 +9487,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -13907,9 +13908,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -18071,6 +18073,7 @@ spec:
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -22488,9 +22491,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -27189,9 +27193,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -31610,9 +31615,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -35775,6 +35781,7 @@ spec:
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
@ -40192,9 +40199,10 @@ spec:
|
||||||
type:
|
type:
|
||||||
description: |-
|
description: |-
|
||||||
Type specifies the method of signature validation. The allowed options
|
Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.
|
||||||
enum:
|
enum:
|
||||||
- Cosign
|
- Cosign
|
||||||
|
- SigstoreBundle
|
||||||
- Notary
|
- Notary
|
||||||
type: string
|
type: string
|
||||||
useCache:
|
useCache:
|
||||||
|
|
|
@ -2410,7 +2410,7 @@ ImageVerificationType
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Type specifies the method of signature validation. The allowed options
|
<p>Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.</p>
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -4743,7 +4743,7 @@ mutated to include the SHA digest retrieved during the registration.</p>
|
||||||
|
|
||||||
|
|
||||||
<p>Type specifies the method of signature validation. The allowed options
|
<p>Type specifies the method of signature validation. The allowed options
|
||||||
are Cosign and Notary. By default Cosign is used if a type is not specified.</p>
|
are Cosign, Sigstore Bundle and Notary. By default Cosign is used if a type is not specified.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
15
go.mod
15
go.mod
|
@ -23,7 +23,7 @@ require (
|
||||||
github.com/go-git/go-billy/v5 v5.5.0
|
github.com/go-git/go-billy/v5 v5.5.0
|
||||||
github.com/go-git/go-git/v5 v5.12.0
|
github.com/go-git/go-git/v5 v5.12.0
|
||||||
github.com/go-logr/logr v1.4.2
|
github.com/go-logr/logr v1.4.2
|
||||||
github.com/go-logr/zapr v1.3.0
|
github.com/go-logr/zerologr v1.2.3
|
||||||
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49
|
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49
|
||||||
github.com/google/go-containerregistry v0.20.2
|
github.com/google/go-containerregistry v0.20.2
|
||||||
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20240530172801-3764db238e3e
|
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20240530172801-3764db238e3e
|
||||||
|
@ -43,16 +43,20 @@ require (
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/prometheus/client_golang v1.19.0
|
github.com/prometheus/client_golang v1.19.0
|
||||||
github.com/robfig/cron v1.2.0
|
github.com/robfig/cron v1.2.0
|
||||||
|
github.com/rs/zerolog v1.33.0
|
||||||
github.com/sigstore/cosign/v2 v2.2.4
|
github.com/sigstore/cosign/v2 v2.2.4
|
||||||
github.com/sigstore/k8s-manifest-sigstore v0.5.4
|
github.com/sigstore/k8s-manifest-sigstore v0.5.4
|
||||||
|
github.com/sigstore/protobuf-specs v0.3.2 // indirect
|
||||||
github.com/sigstore/rekor v1.3.6
|
github.com/sigstore/rekor v1.3.6
|
||||||
github.com/sigstore/sigstore v1.8.4
|
github.com/sigstore/sigstore v1.8.4
|
||||||
|
github.com/sigstore/sigstore-go v0.4.0
|
||||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4
|
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4
|
||||||
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4
|
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4
|
||||||
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4
|
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4
|
||||||
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4
|
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
|
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 // indirect
|
||||||
github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea
|
github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0
|
||||||
go.opentelemetry.io/otel v1.26.0
|
go.opentelemetry.io/otel v1.26.0
|
||||||
|
@ -66,7 +70,7 @@ require (
|
||||||
go.opentelemetry.io/otel/trace v1.26.0
|
go.opentelemetry.io/otel/trace v1.26.0
|
||||||
go.uber.org/automaxprocs v1.5.3
|
go.uber.org/automaxprocs v1.5.3
|
||||||
go.uber.org/multierr v1.11.0
|
go.uber.org/multierr v1.11.0
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/crypto v0.26.0
|
golang.org/x/crypto v0.26.0
|
||||||
golang.org/x/text v0.17.0
|
golang.org/x/text v0.17.0
|
||||||
gomodules.xyz/jsonpatch/v2 v2.4.0
|
gomodules.xyz/jsonpatch/v2 v2.4.0
|
||||||
|
@ -94,11 +98,6 @@ require (
|
||||||
sigs.k8s.io/yaml v1.4.0
|
sigs.k8s.io/yaml v1.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/go-logr/zerologr v1.2.3 // indirect
|
|
||||||
github.com/rs/zerolog v1.33.0 // indirect
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.114.0 // indirect
|
cloud.google.com/go v0.114.0 // indirect
|
||||||
cloud.google.com/go/auth v0.5.1 // indirect
|
cloud.google.com/go/auth v0.5.1 // indirect
|
||||||
|
@ -232,7 +231,7 @@ require (
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/btree v1.1.2 // indirect
|
github.com/google/btree v1.1.2 // indirect
|
||||||
github.com/google/cel-go v0.20.1 // indirect
|
github.com/google/cel-go v0.20.1 // indirect
|
||||||
github.com/google/certificate-transparency-go v1.1.7 // indirect
|
github.com/google/certificate-transparency-go v1.1.8 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/google/go-github/v55 v55.0.0 // indirect
|
github.com/google/go-github/v55 v55.0.0 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
|
|
22
go.sum
22
go.sum
|
@ -436,8 +436,8 @@ github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||||
github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto=
|
github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto=
|
||||||
github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY=
|
github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY=
|
||||||
github.com/google/certificate-transparency-go v1.1.7 h1:IASD+NtgSTJLPdzkthwvAG1ZVbF2WtFg4IvoA68XGSw=
|
github.com/google/certificate-transparency-go v1.1.8 h1:LGYKkgZF7satzgTak9R4yzfJXEeYVAjV6/EAEJOf1to=
|
||||||
github.com/google/certificate-transparency-go v1.1.7/go.mod h1:FSSBo8fyMVgqptbfF6j5p/XNdgQftAhSmXcIxV9iphE=
|
github.com/google/certificate-transparency-go v1.1.8/go.mod h1:bV/o8r0TBKRf1X//iiiSgWrvII4d7/8OiA+3vG26gI8=
|
||||||
github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM=
|
github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM=
|
||||||
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||||
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU=
|
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU=
|
||||||
|
@ -788,10 +788,14 @@ github.com/sigstore/fulcio v1.4.3 h1:9JcUCZjjVhRF9fmhVuz6i1RyhCc/EGCD7MOl+iqCJLQ
|
||||||
github.com/sigstore/fulcio v1.4.3/go.mod h1:BQPWo7cfxmJwgaHlphUHUpFkp5+YxeJes82oo39m5og=
|
github.com/sigstore/fulcio v1.4.3/go.mod h1:BQPWo7cfxmJwgaHlphUHUpFkp5+YxeJes82oo39m5og=
|
||||||
github.com/sigstore/k8s-manifest-sigstore v0.5.4 h1:XPLs7Dz2OXkRdt4sgAoLxuyNSfkb/n5SwfnYb23YlRk=
|
github.com/sigstore/k8s-manifest-sigstore v0.5.4 h1:XPLs7Dz2OXkRdt4sgAoLxuyNSfkb/n5SwfnYb23YlRk=
|
||||||
github.com/sigstore/k8s-manifest-sigstore v0.5.4/go.mod h1:VN/nxjuAprSy1LrutFdhc5UsrQjij4DaCYV4Wklu5zo=
|
github.com/sigstore/k8s-manifest-sigstore v0.5.4/go.mod h1:VN/nxjuAprSy1LrutFdhc5UsrQjij4DaCYV4Wklu5zo=
|
||||||
|
github.com/sigstore/protobuf-specs v0.3.2 h1:nCVARCN+fHjlNCk3ThNXwrZRqIommIeNKWwQvORuRQo=
|
||||||
|
github.com/sigstore/protobuf-specs v0.3.2/go.mod h1:RZ0uOdJR4OB3tLQeAyWoJFbNCBFrPQdcokntde4zRBA=
|
||||||
github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8=
|
github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8=
|
||||||
github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc=
|
github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc=
|
||||||
github.com/sigstore/sigstore v1.8.4 h1:g4ICNpiENFnWxjmBzBDWUn62rNFeny/P77HUC8da32w=
|
github.com/sigstore/sigstore v1.8.4 h1:g4ICNpiENFnWxjmBzBDWUn62rNFeny/P77HUC8da32w=
|
||||||
github.com/sigstore/sigstore v1.8.4/go.mod h1:1jIKtkTFEeISen7en+ZPWdDHazqhxco/+v9CNjc7oNg=
|
github.com/sigstore/sigstore v1.8.4/go.mod h1:1jIKtkTFEeISen7en+ZPWdDHazqhxco/+v9CNjc7oNg=
|
||||||
|
github.com/sigstore/sigstore-go v0.4.0 h1:0BxofjPnd+1LzyiCgsFP0NviMg8l20ZMf4aitkvYEU8=
|
||||||
|
github.com/sigstore/sigstore-go v0.4.0/go.mod h1:KZQFwvDItf1sr5P8YhVIjjXBe1ZyeFuC4odn7/2Uie0=
|
||||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4 h1:okxaVlaTrQowE1FA4UQ3rw54f7BUjdnzERIxbZTBZuc=
|
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4 h1:okxaVlaTrQowE1FA4UQ3rw54f7BUjdnzERIxbZTBZuc=
|
||||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4/go.mod h1:jkcPErmnCECuSJajUaUq5pwCMOeBF19VzQo6bv4l1D0=
|
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4/go.mod h1:jkcPErmnCECuSJajUaUq5pwCMOeBF19VzQo6bv4l1D0=
|
||||||
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4 h1:1G6uLTZaqvu867DbgH7p75L6Y7Tu8LLnYJGZnWsTUu8=
|
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4 h1:1G6uLTZaqvu867DbgH7p75L6Y7Tu8LLnYJGZnWsTUu8=
|
||||||
|
@ -869,6 +873,8 @@ github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gt
|
||||||
github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
|
github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
|
||||||
github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
|
github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
|
||||||
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
|
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
|
||||||
|
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 h1:27XWhDZHPD+cufF6qSdYx6PgGQvD2jJ6pq9sDvR6VBk=
|
||||||
|
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63/go.mod h1:+gWwqe1pk4nvGeOKosGJqPgD+N/kbD9M0QVLL9TGIYU=
|
||||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
||||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
||||||
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
||||||
|
@ -928,12 +934,12 @@ go.etcd.io/etcd/client/v2 v2.305.12 h1:0m4ovXYo1CHaA/Mp3X/Fak5sRNIWf01wk/X1/G3sG
|
||||||
go.etcd.io/etcd/client/v2 v2.305.12/go.mod h1:aQ/yhsxMu+Oht1FOupSr60oBvcS9cKXHrzBpDsPTf9E=
|
go.etcd.io/etcd/client/v2 v2.305.12/go.mod h1:aQ/yhsxMu+Oht1FOupSr60oBvcS9cKXHrzBpDsPTf9E=
|
||||||
go.etcd.io/etcd/client/v3 v3.5.13 h1:o0fHTNJLeO0MyVbc7I3fsCf6nrOqn5d+diSarKnB2js=
|
go.etcd.io/etcd/client/v3 v3.5.13 h1:o0fHTNJLeO0MyVbc7I3fsCf6nrOqn5d+diSarKnB2js=
|
||||||
go.etcd.io/etcd/client/v3 v3.5.13/go.mod h1:cqiAeY8b5DEEcpxvgWKsbLIWNM/8Wy2xJSDMtioMcoI=
|
go.etcd.io/etcd/client/v3 v3.5.13/go.mod h1:cqiAeY8b5DEEcpxvgWKsbLIWNM/8Wy2xJSDMtioMcoI=
|
||||||
go.etcd.io/etcd/pkg/v3 v3.5.10 h1:WPR8K0e9kWl1gAhB5A7gEa5ZBTNkT9NdNWrR8Qpo1CM=
|
go.etcd.io/etcd/pkg/v3 v3.5.12 h1:OK2fZKI5hX/+BTK76gXSTyZMrbnARyX9S643GenNGb8=
|
||||||
go.etcd.io/etcd/pkg/v3 v3.5.10/go.mod h1:TKTuCKKcF1zxmfKWDkfz5qqYaE3JncKKZPFf8c1nFUs=
|
go.etcd.io/etcd/pkg/v3 v3.5.12/go.mod h1:UVwg/QIMoJncyeb/YxvJBJCE/NEwtHWashqc8A1nj/M=
|
||||||
go.etcd.io/etcd/raft/v3 v3.5.10 h1:cgNAYe7xrsrn/5kXMSaH8kM/Ky8mAdMqGOxyYwpP0LA=
|
go.etcd.io/etcd/raft/v3 v3.5.12 h1:7r22RufdDsq2z3STjoR7Msz6fYH8tmbkdheGfwJNRmU=
|
||||||
go.etcd.io/etcd/raft/v3 v3.5.10/go.mod h1:odD6kr8XQXTy9oQnyMPBOr0TVe+gT0neQhElQ6jbGRc=
|
go.etcd.io/etcd/raft/v3 v3.5.12/go.mod h1:ERQuZVe79PI6vcC3DlKBukDCLja/L7YMu29B74Iwj4U=
|
||||||
go.etcd.io/etcd/server/v3 v3.5.10 h1:4NOGyOwD5sUZ22PiWYKmfxqoeh72z6EhYjNosKGLmZg=
|
go.etcd.io/etcd/server/v3 v3.5.12 h1:EtMjsbfyfkwZuA2JlKOiBfuGkFCekv5H178qjXypbG8=
|
||||||
go.etcd.io/etcd/server/v3 v3.5.10/go.mod h1:gBplPHfs6YI0L+RpGkTQO7buDbHv5HJGG/Bst0/zIPo=
|
go.etcd.io/etcd/server/v3 v3.5.12/go.mod h1:axB0oCjMy+cemo5290/CutIjoxlfA6KVYKD1w0uue10=
|
||||||
go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc=
|
go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc=
|
||||||
go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
|
|
|
@ -47,6 +47,19 @@ func NewVerifier() images.ImageVerifier {
|
||||||
type cosignVerifier struct{}
|
type cosignVerifier struct{}
|
||||||
|
|
||||||
func (v *cosignVerifier) VerifySignature(ctx context.Context, opts images.Options) (*images.Response, error) {
|
func (v *cosignVerifier) VerifySignature(ctx context.Context, opts images.Options) (*images.Response, error) {
|
||||||
|
if opts.SigstoreBundle {
|
||||||
|
results, err := verifyBundleAndFetchAttestations(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(results) == 0 {
|
||||||
|
return nil, fmt.Errorf("sigstore bundle verification failed: no matching signatures found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &images.Response{Digest: results[0].Desc.Digest.String()}, nil
|
||||||
|
}
|
||||||
|
|
||||||
ref, err := name.ParseReference(opts.ImageRef)
|
ref, err := name.ParseReference(opts.ImageRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse image %s", opts.ImageRef)
|
return nil, fmt.Errorf("failed to parse image %s", opts.ImageRef)
|
||||||
|
@ -266,6 +279,22 @@ func loadCertChain(pem []byte) ([]*x509.Certificate, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *cosignVerifier) FetchAttestations(ctx context.Context, opts images.Options) (*images.Response, error) {
|
func (v *cosignVerifier) FetchAttestations(ctx context.Context, opts images.Options) (*images.Response, error) {
|
||||||
|
if opts.SigstoreBundle {
|
||||||
|
results, err := verifyBundleAndFetchAttestations(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(results) == 0 {
|
||||||
|
return nil, fmt.Errorf("sigstore bundle verification failed: no matching signatures found")
|
||||||
|
}
|
||||||
|
|
||||||
|
statements, err := decodeStatementsFromBundles(results)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &images.Response{Digest: results[0].Desc.Digest.String(), Statements: statements}, nil
|
||||||
|
}
|
||||||
cosignOpts, err := buildCosignOptions(ctx, opts)
|
cosignOpts, err := buildCosignOptions(ctx, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
254
pkg/cosign/sigstore.go
Normal file
254
pkg/cosign/sigstore.go
Normal file
|
@ -0,0 +1,254 @@
|
||||||
|
package cosign
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
|
"github.com/in-toto/in-toto-golang/in_toto"
|
||||||
|
"github.com/kyverno/kyverno/pkg/images"
|
||||||
|
"github.com/kyverno/kyverno/pkg/utils/data"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sigstore/sigstore-go/pkg/bundle"
|
||||||
|
"github.com/sigstore/sigstore-go/pkg/root"
|
||||||
|
"github.com/sigstore/sigstore-go/pkg/verify"
|
||||||
|
"github.com/sigstore/sigstore/pkg/tuf"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
maxLayerSize = int64(10 * 1000 * 1000) // 10 MB
|
||||||
|
attestationlimit = 50
|
||||||
|
)
|
||||||
|
|
||||||
|
type VerificationResult struct {
|
||||||
|
Bundle *Bundle
|
||||||
|
Result *verify.VerificationResult
|
||||||
|
Desc *v1.Descriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
type Bundle struct {
|
||||||
|
ProtoBundle *bundle.ProtobufBundle
|
||||||
|
DSSE_Envelope *in_toto.Statement
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyBundleAndFetchAttestations(ctx context.Context, opts images.Options) ([]*VerificationResult, error) {
|
||||||
|
ref, err := name.ParseReference(opts.ImageRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to parse image reference: %v", opts.ImageRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteOpts, err := opts.Client.Options(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to create remote opts: %v", opts.ImageRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
bundles, desc, err := fetchBundles(ref, attestationlimit, opts.Type, remoteOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to fetch bundles: %v", opts.ImageRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
policy, err := buildPolicy(desc, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to build policy: %v", opts.ImageRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyOpts := buildVerifyOptions(opts)
|
||||||
|
trustedMaterial, err := getTrustedRoot(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to get trusted root: %v", opts.ImageRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := verifyBundles(bundles, desc, trustedMaterial, policy, verifyOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to get verify bundles: %v", opts.ImageRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyBundles(bundles []*Bundle, desc *v1.Descriptor, trustedRoot *root.TrustedRoot, policy verify.PolicyBuilder, verifierOpts []verify.VerifierOption) ([]*VerificationResult, error) {
|
||||||
|
verifier, err := verify.NewSignedEntityVerifier(trustedRoot, verifierOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
verificationResults := make([]*VerificationResult, 0)
|
||||||
|
for _, bundle := range bundles {
|
||||||
|
result, err := verifier.Verify(bundle.ProtoBundle, policy)
|
||||||
|
if err == nil {
|
||||||
|
verificationResults = append(verificationResults, &VerificationResult{Bundle: bundle, Result: result, Desc: desc})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return verificationResults, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchBundles(ref name.Reference, limit int, predicateType string, remoteOpts []remote.Option) ([]*Bundle, *v1.Descriptor, error) {
|
||||||
|
bundles := make([]*Bundle, 0)
|
||||||
|
|
||||||
|
desc, err := remote.Head(ref, remoteOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
referrers, err := remote.Referrers(ref.Context().Digest(desc.Digest.String()), remoteOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
referrersDescs, err := referrers.IndexManifest()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(referrersDescs.Manifests) > limit {
|
||||||
|
return nil, nil, fmt.Errorf("failed to fetch referrers: to many referrers found, max limit is %d", limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, manifestDesc := range referrersDescs.Manifests {
|
||||||
|
if !strings.HasPrefix(manifestDesc.ArtifactType, "application/vnd.dev.sigstore.bundle") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
refImg, err := remote.Image(ref.Context().Digest(manifestDesc.Digest.String()), remoteOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to fetch referrer image: %w", err)
|
||||||
|
}
|
||||||
|
layers, err := refImg.Layers()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to fetch referrer layer: %w", err)
|
||||||
|
}
|
||||||
|
if len(layers) == 0 {
|
||||||
|
return nil, nil, fmt.Errorf("layers not found")
|
||||||
|
}
|
||||||
|
layer := layers[0]
|
||||||
|
layerSize, err := layer.Size()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if layerSize > maxLayerSize {
|
||||||
|
return nil, nil, fmt.Errorf("layer size %d exceeds %d", layerSize, maxLayerSize)
|
||||||
|
}
|
||||||
|
layerBytes, err := layer.Uncompressed()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to fetch referrer layer: %w", err)
|
||||||
|
}
|
||||||
|
bundleBytes, err := io.ReadAll(layerBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to fetch referrer layer: %w", err)
|
||||||
|
}
|
||||||
|
b := &bundle.ProtobufBundle{}
|
||||||
|
err = b.UnmarshalJSON(bundleBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to unmarshal bundle: %w", err)
|
||||||
|
}
|
||||||
|
bundles = append(bundles, &Bundle{ProtoBundle: b})
|
||||||
|
}
|
||||||
|
|
||||||
|
if predicateType != "" {
|
||||||
|
filteredBundles := make([]*Bundle, 0)
|
||||||
|
for _, b := range bundles {
|
||||||
|
dsseEnvelope := b.ProtoBundle.Bundle.GetDsseEnvelope()
|
||||||
|
if dsseEnvelope != nil {
|
||||||
|
if dsseEnvelope.PayloadType != "application/vnd.in-toto+json" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var intotoStatement in_toto.Statement
|
||||||
|
if err := json.Unmarshal(dsseEnvelope.Payload, &intotoStatement); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if intotoStatement.PredicateType == predicateType {
|
||||||
|
filteredBundles = append(filteredBundles, &Bundle{
|
||||||
|
ProtoBundle: b.ProtoBundle,
|
||||||
|
DSSE_Envelope: &intotoStatement,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredBundles, desc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return bundles, desc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildPolicy(desc *v1.Descriptor, opts images.Options) (verify.PolicyBuilder, error) {
|
||||||
|
digest, err := hex.DecodeString(desc.Digest.Hex)
|
||||||
|
if err != nil {
|
||||||
|
return verify.PolicyBuilder{}, err
|
||||||
|
}
|
||||||
|
artifactDigestVerificationOption := verify.WithArtifactDigest(desc.Digest.Algorithm, digest)
|
||||||
|
|
||||||
|
// TODO: Add full regexp support to sigstore and cosign
|
||||||
|
// Verify images only has subject field, and no subject regexp, subject cannot be passed to subject regexp
|
||||||
|
// because then string containing the subjects will also work. We should just add an issuer regexp
|
||||||
|
// Solve this in a separate PR,
|
||||||
|
// See: https://github.com/sigstore/cosign/blob/7c20052077a81d667526af879ec40168899dde1f/pkg/cosign/verify.go#L339-L356
|
||||||
|
subjectRegexp := ""
|
||||||
|
if strings.Contains(opts.Subject, "*") {
|
||||||
|
subjectRegexp = opts.Subject
|
||||||
|
opts.Subject = ""
|
||||||
|
}
|
||||||
|
id, err := verify.NewShortCertificateIdentity(opts.Issuer, opts.Subject, "", subjectRegexp)
|
||||||
|
if err != nil {
|
||||||
|
return verify.PolicyBuilder{}, err
|
||||||
|
}
|
||||||
|
return verify.NewPolicy(artifactDigestVerificationOption, verify.WithCertificateIdentity(id)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildVerifyOptions(opts images.Options) []verify.VerifierOption {
|
||||||
|
var verifierOptions []verify.VerifierOption
|
||||||
|
if !opts.IgnoreTlog {
|
||||||
|
verifierOptions = append(verifierOptions, verify.WithTransparencyLog(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !opts.IgnoreSCT {
|
||||||
|
verifierOptions = append(verifierOptions, verify.WithObserverTimestamps(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifierOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTrustedRoot(ctx context.Context) (*root.TrustedRoot, error) {
|
||||||
|
tufClient, err := tuf.NewFromEnv(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("initializing tuf: %w", err)
|
||||||
|
}
|
||||||
|
targetBytes, err := tufClient.GetTarget("trusted_root.json")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error getting targets: %w", err)
|
||||||
|
}
|
||||||
|
trustedRoot, err := root.NewTrustedRootFromJSON(targetBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error creating trusted root: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return trustedRoot, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeStatementsFromBundles(bundles []*VerificationResult) ([]map[string]interface{}, error) {
|
||||||
|
if len(bundles) == 0 {
|
||||||
|
return []map[string]interface{}{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var statement map[string]interface{}
|
||||||
|
var intotostatement in_toto.Statement
|
||||||
|
decodedStatements := make([]map[string]interface{}, len(bundles))
|
||||||
|
for i, b := range bundles {
|
||||||
|
intotostatement = *b.Bundle.DSSE_Envelope
|
||||||
|
statement, err = data.ToMap(intotostatement)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to decode statement: %v", intotostatement.Type)
|
||||||
|
}
|
||||||
|
statement["type"] = intotostatement.PredicateType
|
||||||
|
decodedStatements[i] = statement
|
||||||
|
}
|
||||||
|
return decodedStatements, nil
|
||||||
|
}
|
89
pkg/cosign/sigstore_test.go
Normal file
89
pkg/cosign/sigstore_test.go
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
package cosign
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
|
"github.com/kyverno/kyverno/pkg/images"
|
||||||
|
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||||
|
"gotest.tools/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSigstoreBundleSignatureVerification(t *testing.T) {
|
||||||
|
opts := images.Options{
|
||||||
|
SigstoreBundle: true,
|
||||||
|
ImageRef: "ghcr.io/vishal-chdhry/artifact-attestation-example:artifact-attestation",
|
||||||
|
Issuer: "https://token.actions.githubusercontent.com",
|
||||||
|
Subject: "https://github.com/vishal-chdhry/artifact-attestation-example/.github/workflows/build-attested-image.yaml@refs/heads/main",
|
||||||
|
}
|
||||||
|
|
||||||
|
rc, err := registryclient.New()
|
||||||
|
assert.NilError(t, err)
|
||||||
|
opts.Client = rc
|
||||||
|
|
||||||
|
verifier := &cosignVerifier{}
|
||||||
|
_, err = verifier.VerifySignature(context.TODO(), opts)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
opts.Subject = "invalid"
|
||||||
|
_, err = verifier.VerifySignature(context.TODO(), opts)
|
||||||
|
assert.ErrorContains(t, err, "sigstore bundle verification failed: no matching signatures found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSigstoreBundleSignatureResponse(t *testing.T) {
|
||||||
|
opts := images.Options{
|
||||||
|
SigstoreBundle: true,
|
||||||
|
ImageRef: "ghcr.io/vishal-chdhry/artifact-attestation-example:artifact-attestation",
|
||||||
|
Issuer: "https://token.actions.githubusercontent.com",
|
||||||
|
Subject: "https://github.com/vishal-chdhry/artifact-attestation-example/.github/workflows/build-attested-image.yaml@refs/heads/main",
|
||||||
|
}
|
||||||
|
|
||||||
|
rc, err := registryclient.New()
|
||||||
|
assert.NilError(t, err)
|
||||||
|
opts.Client = rc
|
||||||
|
|
||||||
|
verifier := &cosignVerifier{}
|
||||||
|
response, err := verifier.VerifySignature(context.TODO(), opts)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
ref, err := name.ParseReference(opts.ImageRef)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
desc, err := remote.Head(ref)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.Equal(t, desc.Digest.String(), response.Digest)
|
||||||
|
assert.Equal(t, len(response.Statements), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSigstoreBundleAttestation(t *testing.T) {
|
||||||
|
opts := images.Options{
|
||||||
|
SigstoreBundle: true,
|
||||||
|
ImageRef: "ghcr.io/vishal-chdhry/artifact-attestation-example:artifact-attestation",
|
||||||
|
Issuer: "https://token.actions.githubusercontent.com",
|
||||||
|
Subject: "https://github.com/vishal-chdhry/artifact-attestation-example/.github/workflows/build-attested-image.yaml@refs/heads/main",
|
||||||
|
Type: "https://slsa.dev/provenance/v1",
|
||||||
|
}
|
||||||
|
|
||||||
|
rc, err := registryclient.New()
|
||||||
|
assert.NilError(t, err)
|
||||||
|
opts.Client = rc
|
||||||
|
|
||||||
|
verifier := &cosignVerifier{}
|
||||||
|
response, err := verifier.FetchAttestations(context.TODO(), opts)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
ref, err := name.ParseReference(opts.ImageRef)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
desc, err := remote.Head(ref)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, desc.Digest.String(), response.Digest)
|
||||||
|
assert.Assert(t, len(response.Statements) > 0)
|
||||||
|
|
||||||
|
buildType, ok := response.Statements[0]["predicate"].(map[string]interface{})["buildDefinition"].(map[string]interface{})["buildType"].(string)
|
||||||
|
assert.Assert(t, ok)
|
||||||
|
assert.Equal(t, buildType, "https://actions.github.io/buildtypes/workflow/v1")
|
||||||
|
}
|
|
@ -556,6 +556,10 @@ func (iv *ImageVerifier) buildCosignVerifier(
|
||||||
Client: iv.rclient,
|
Client: iv.rclient,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if imageVerify.Type == kyvernov1.SigstoreBundle {
|
||||||
|
opts.SigstoreBundle = true
|
||||||
|
}
|
||||||
|
|
||||||
if imageVerify.Roots != "" {
|
if imageVerify.Roots != "" {
|
||||||
opts.Roots = imageVerify.Roots
|
opts.Roots = imageVerify.Roots
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ type Client interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
SigstoreBundle bool
|
||||||
ImageRef string
|
ImageRef string
|
||||||
Client Client
|
Client Client
|
||||||
FetchAttestations bool
|
FetchAttestations bool
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test verifies the predicate in sigstore bundle attached to an image using regex issuer
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: sigstore-attestation-verification-regexp
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: pod.yaml
|
||||||
|
- assert:
|
||||||
|
file: pod-assert.yaml
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: test-pod
|
||||||
|
namespace: default
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: test-pod
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: ghcr.io/vishal-chdhry/artifact-attestation-example:artifact-attestation
|
||||||
|
name: test-container
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: sigstore-attestation-verification-regexp
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,36 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
pod-policies.kyverno.io/autogen-controllers: none
|
||||||
|
name: sigstore-attestation-verification-regexp
|
||||||
|
spec:
|
||||||
|
background: false
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
webhookTimeoutSeconds: 30
|
||||||
|
rules:
|
||||||
|
- match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
name: sigstore-attestation-verification
|
||||||
|
verifyImages:
|
||||||
|
- imageReferences:
|
||||||
|
- "*"
|
||||||
|
type: SigstoreBundle
|
||||||
|
attestations:
|
||||||
|
- attestors:
|
||||||
|
- entries:
|
||||||
|
- keyless:
|
||||||
|
issuer: https://token.actions.githubusercontent.com
|
||||||
|
subject: https://github.com/vishal-chdhry/artifact-attestation-example/.github/workflows/*
|
||||||
|
rekor:
|
||||||
|
url: https://rekor.sigstore.dev
|
||||||
|
conditions:
|
||||||
|
- all:
|
||||||
|
- key: '{{ buildDefinition.buildType }}'
|
||||||
|
operator: Equals
|
||||||
|
value: https://actions.github.io/buildtypes/workflow/v1
|
||||||
|
type: https://slsa.dev/provenance/v1
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test verifies the predicate in sigstore bundle attached to an image
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: sigstore-attestation-verification
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: pod.yaml
|
||||||
|
- assert:
|
||||||
|
file: pod-assert.yaml
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: test-pod
|
||||||
|
namespace: default
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: test-pod
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: ghcr.io/vishal-chdhry/artifact-attestation-example:artifact-attestation
|
||||||
|
name: test-container
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: sigstore-attestation-verification
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
pod-policies.kyverno.io/autogen-controllers: none
|
||||||
|
name: sigstore-attestation-verification
|
||||||
|
spec:
|
||||||
|
background: false
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
webhookTimeoutSeconds: 30
|
||||||
|
rules:
|
||||||
|
- match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
name: sigstore-attestation-verification
|
||||||
|
verifyImages:
|
||||||
|
- imageReferences:
|
||||||
|
- "*"
|
||||||
|
type: SigstoreBundle
|
||||||
|
attestations:
|
||||||
|
- attestors:
|
||||||
|
- entries:
|
||||||
|
- keyless:
|
||||||
|
issuer: https://token.actions.githubusercontent.com
|
||||||
|
subject: https://github.com/vishal-chdhry/artifact-attestation-example/.github/workflows/build-attested-image.yaml@refs/heads/main
|
||||||
|
rekor:
|
||||||
|
url: https://rekor.sigstore.dev
|
||||||
|
conditions:
|
||||||
|
- all:
|
||||||
|
- key: '{{ buildDefinition.buildType }}'
|
||||||
|
operator: Equals
|
||||||
|
value: https://actions.github.io/buildtypes/workflow/v1
|
||||||
|
type: https://slsa.dev/provenance/v1
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test verifies sigstore bundle attached to an image.
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: sigstore-image-verification
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: pod.yaml
|
||||||
|
- assert:
|
||||||
|
file: pod-assert.yaml
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: test-pod
|
||||||
|
namespace: default
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: test-pod
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: ghcr.io/vishal-chdhry/artifact-attestation-example:artifact-attestation
|
||||||
|
name: test-container
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: sigstore-image-verification
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
pod-policies.kyverno.io/autogen-controllers: none
|
||||||
|
name: sigstore-image-verification
|
||||||
|
spec:
|
||||||
|
background: false
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
webhookTimeoutSeconds: 30
|
||||||
|
rules:
|
||||||
|
- match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
name: sigstore-image-verification
|
||||||
|
verifyImages:
|
||||||
|
- imageReferences:
|
||||||
|
- "*"
|
||||||
|
type: SigstoreBundle
|
||||||
|
attestors:
|
||||||
|
- entries:
|
||||||
|
- keyless:
|
||||||
|
issuer: https://token.actions.githubusercontent.com
|
||||||
|
subject: https://github.com/vishal-chdhry/artifact-attestation-example/.github/workflows/build-attested-image.yaml@refs/heads/main
|
||||||
|
rekor:
|
||||||
|
url: https://rekor.sigstore.dev
|
||||||
|
|
Loading…
Add table
Reference in a new issue