Skip to content

Commit 36cf786

Browse files
committed
Support different verification options per image
Different images will require different verification options. This commit adds configuration that allows you to define different 'verifiers' for specific image references, or image reference patterns. At the moment it supports verification by public key, or the existing options, but should be expanded to include all supported options. Also modifies the response from the provider to include an error per-image checked, rather than returning any error as a 'system' error. I've also removed the _invalid suffix from the key returned in the response when there's an error. The presence of the 'error' field indicates this better, I think. Signed-off-by: Rob Best <rob.best@jetstack.io>
1 parent f26799b commit 36cf786

File tree

7 files changed

+638
-285
lines changed

7 files changed

+638
-285
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ RUN go mod download
2424

2525
COPY . .
2626

27-
RUN go build -o provider provider.go
27+
RUN go build -o provider .
2828

2929
FROM $BASEIMAGE
3030

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,32 @@ $ cosign sign --key cosign.key devopps/signed:latest
4444
```
4545

4646
So, once you are ready, let's apply these manifests one by one. It should allow deploying Pod for valid.yaml, and deny for the other one.
47+
48+
## Configuration
49+
50+
The provider can be configured with a configuration file passed with the
51+
`-config-file=<file>` flag.
52+
53+
The verification options for specific image references can be configured by
54+
defining verifiers.
55+
56+
If a matching verifier can't be found then it will return an error for that image
57+
in the response.
58+
59+
```yaml
60+
verifiers:
61+
# Verify images in the my-project GCR registry with GCP KMS
62+
- image: "eu.gcr.io/my-project/*"
63+
options:
64+
key: "gcpkms://projects/my-project/locations/global/keyRings/my-keyring/cryptoKeys/my-key"
65+
66+
# Verify images from my-registry with cosign.pub
67+
- image: "my-registry:12345/*"
68+
options:
69+
key: "/cosign.pub"
70+
71+
# Verify any other image with the rekor server
72+
- image: "*"
73+
options:
74+
rekorURL: "https://rekor.sigstore.dev"
75+
```

config.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"gopkg.in/yaml.v3"
8+
)
9+
10+
var (
11+
// DefaultOptions are the default verification options
12+
DefaultOptions = &CheckOptions{
13+
RekorURL: "https://rekor.sigstore.dev",
14+
}
15+
16+
// DefaultConfig is the configuration used when none is provided
17+
DefaultConfig = &Config{
18+
Verifiers: []Verifier{
19+
{
20+
Options: DefaultOptions,
21+
},
22+
},
23+
}
24+
)
25+
26+
// LoadConfig loads configuration from a file. If a file isn't provided then it
27+
// returns the default configuration.
28+
func LoadConfig(confFile string) (*Config, error) {
29+
if confFile == "" {
30+
return DefaultConfig, nil
31+
}
32+
33+
var c *Config
34+
35+
yamlReader, err := os.Open(confFile)
36+
if err != nil {
37+
return c, fmt.Errorf("error reading config file: %s", err)
38+
}
39+
defer yamlReader.Close()
40+
decoder := yaml.NewDecoder(yamlReader)
41+
decoder.KnownFields(true)
42+
43+
if err = decoder.Decode(&c); err != nil {
44+
return c, fmt.Errorf("error parsing config file: %s", err)
45+
}
46+
47+
return c, nil
48+
}
49+
50+
// Config configures the provider
51+
type Config struct {
52+
// Verifiers is a list of verifiers. The validator will iterate over
53+
// this list until it finds a verifier that matches the image its
54+
// validating.
55+
Verifiers []Verifier `yaml:"verifiers"`
56+
}
57+
58+
// Verifier verifies an image
59+
type Verifier struct {
60+
// Image is an image reference, either to a specific image or a pattern.
61+
// Supports '*' and '?' in the pattern string.
62+
Image string `yaml:"image,omitempty"`
63+
64+
// Options defines verification options
65+
Options *CheckOptions `yaml:"options,omitempty"`
66+
}
67+
68+
// UnmarshalYAML sets default options for the verifier config when they aren't
69+
// provided
70+
func (v *Verifier) UnmarshalYAML(unmarshal func(interface{}) error) error {
71+
type rawVerifier Verifier
72+
var raw rawVerifier
73+
if err := unmarshal(&raw); err != nil {
74+
return err
75+
}
76+
77+
if raw.Options == nil {
78+
raw.Options = DefaultOptions
79+
}
80+
81+
*v = Verifier(raw)
82+
83+
return nil
84+
}
85+
86+
// CheckOptions are the options used to verify the signature of an image
87+
type CheckOptions struct {
88+
// Key is a path to a public key file, KMS URI or Kubernetes Secret
89+
Key string `yaml:"key,omitempty"`
90+
91+
// RekorURL is the address of a rekor STL server
92+
RekorURL string `yaml:"rekorURL,omitempty"`
93+
}

0 commit comments

Comments
 (0)