Read TUF config from flags and add to helm chart

The values in the local helm chart are for the dev root
This commit is contained in:
Jonny Stoten
2024-06-24 16:53:54 +01:00
parent e0f660b3cc
commit e76057db3e
6 changed files with 136 additions and 42 deletions

View File

@@ -15,11 +15,13 @@ import (
"k8s.io/klog/v2"
)
func Mutate() http.Handler {
return http.HandlerFunc(mutate)
type mutateHandler struct{}
func NewMutateHandler() (http.Handler, error) {
return &mutateHandler{}, nil
}
func mutate(w http.ResponseWriter, req *http.Request) {
func (h *mutateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
defer func() {
if r := recover(); r != nil {
klog.Error(string(debug.Stack()))

View File

@@ -1,17 +0,0 @@
package handler
import (
"github.com/docker/attest/pkg/tuf"
"github.com/open-policy-agent/gatekeeper-external-data-provider/internal/embed"
)
func createTufClient(outputPath string) (*tuf.TufClient, error) {
// using oci tuf metadata and targets
metadataURI := "registry-1.docker.io/docker/tuf-metadata:latest"
targetsURI := "registry-1.docker.io/docker/tuf-targets"
// example using http tuf metadata and targets
// metadataURI := "https://docker.github.io/tuf-staging/metadata"
// targetsURI := "https://docker.github.io/tuf-staging/targets"
return tuf.NewTufClient(embed.StagingRoot, outputPath, metadataURI, targetsURI, tuf.NewVersionChecker())
}

View File

@@ -5,14 +5,15 @@ import (
"fmt"
"io"
"net/http"
"path/filepath"
"runtime/debug"
"github.com/docker/attest/pkg/attest"
"github.com/docker/attest/pkg/oci"
"github.com/docker/attest/pkg/policy"
"github.com/docker/attest/pkg/tuf"
intoto "github.com/in-toto/in-toto-golang/in_toto"
"github.com/open-policy-agent/frameworks/constraint/pkg/externaldata"
"github.com/open-policy-agent/gatekeeper-external-data-provider/internal/embed"
"github.com/open-policy-agent/gatekeeper-external-data-provider/pkg/utils"
"k8s.io/klog/v2"
)
@@ -24,11 +25,50 @@ type ValidationResult struct {
Violations []policy.Violation `json:"violations"`
}
func Validate() http.Handler {
return http.HandlerFunc(validate)
type ValidateHandlerOptions struct {
TUFRoot string
TUFOutputPath string
TUFMetadataURL string
TUFTargetsURL string
PolicyDir string
PolicyCacheDir string
}
func validate(w http.ResponseWriter, req *http.Request) {
type validateHandler struct {
opts *ValidateHandlerOptions
}
func NewValidateHandler(opts *ValidateHandlerOptions) (http.Handler, error) {
handler := &validateHandler{opts: opts}
// a TUF client can only be used once, so we need to create a new one for each request.
// we create this one up front to ensure that the TUF root is valid and to pre-load the metadata.
// TODO: this pre-loading works for the root, targets, snapshot, and timestamp roles, but not for delegated roles.
_, err := handler.createTUFClient()
if err != nil {
return nil, err
}
klog.Infof("validate handler initialized with %s TUF root", opts.TUFRoot)
return handler, nil
}
func (h *validateHandler) createTUFClient() (*tuf.TufClient, error) {
var rootBytes []byte
switch h.opts.TUFRoot {
case "dev":
rootBytes = embed.DevRoot
case "staging":
rootBytes = embed.StagingRoot
default:
return nil, fmt.Errorf("invalid tuf root: %s", h.opts.TUFRoot)
}
return tuf.NewTufClient(rootBytes, h.opts.TUFOutputPath, h.opts.TUFMetadataURL, h.opts.TUFTargetsURL, tuf.NewVersionChecker())
}
func (h *validateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
defer func() {
if r := recover(); r != nil {
klog.Error(string(debug.Stack()))
@@ -36,6 +76,10 @@ func validate(w http.ResponseWriter, req *http.Request) {
}
}()
ctx := req.Context()
debug := true
ctx = policy.WithPolicyEvaluator(ctx, policy.NewRegoEvaluator(debug))
// read request body
requestBody, err := io.ReadAll(req.Body)
if err != nil {
@@ -53,16 +97,19 @@ func validate(w http.ResponseWriter, req *http.Request) {
return
}
results := make([]externaldata.Item, 0)
// create a tuf client
tufOutputPath := filepath.Join("/tuf_temp", ".docker", "tuf")
tufClient, err := createTufClient(tufOutputPath)
tufClient, err := h.createTUFClient()
if err != nil {
utils.SendResponse(nil, err.Error(), w)
utils.SendResponse(nil, fmt.Sprintf("unable to create TUF client: %v", err), w)
return
}
policyOpts := &policy.PolicyOptions{
TufClient: tufClient,
LocalTargetsDir: h.opts.PolicyCacheDir,
LocalPolicyDir: h.opts.PolicyDir,
}
results := make([]externaldata.Item, 0)
for _, key := range providerRequest.Request.Keys {
platform := "linux/amd64"
src, err := oci.ParseImageSpec(key, oci.WithPlatform(platform))
@@ -71,16 +118,7 @@ func validate(w http.ResponseWriter, req *http.Request) {
return
}
opts := &policy.PolicyOptions{
TufClient: tufClient,
LocalTargetsDir: filepath.Join("/tuf_temp", ".docker", "policy"), // location to store policy files downloaded from TUF
LocalPolicyDir: "", // overrides TUF policy for local policy files if set
}
ctx := req.Context()
debug := true
ctx = policy.WithPolicyEvaluator(ctx, policy.NewRegoEvaluator(debug))
result, err := attest.Verify(ctx, src, opts)
result, err := attest.Verify(ctx, src, policyOpts)
if err != nil {
utils.SendResponse(nil, err.Error(), w)
return