Repository: sigstore/rekor
Pull request #1410 (2023-03-29 19:56:26)

add new method to test insertability of proposed entries into log
#### Summary

Given the schema definitions for entry types, there is a fair bit of embedded logic that ensures that entry proposals have the correct mix of properties and not others. For code readability, this PR proposes an intermediate step towards an updated API that is a start towards addressing #1305 by adding a new method to the `EntryImpl` interface called `Insertable`, which ensures that the unmarshalled entry has the appropriate fields specified.

- [x] add unit tests for each type 

codecov[bot]: ## [Codecov](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore) Report
> Merging [#1410](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore) (a73a7e6) into [main](https://codecov.io/gh/sigstore/rekor/commit/4a6592612dc015f24d0700b6d274b3663d128ad8?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore) (4a65926) will **decrease** coverage by `22.15%`.
> The diff coverage is `0.00%`.

```diff
@@             Coverage Diff             @@
##             main    #1410       +/-   ##
===========================================
- Coverage   64.35%   42.20%   -22.15%     
===========================================
  Files          82       74        -8     
  Lines        7874     7599      -275     
===========================================
- Hits         5067     3207     -1860     
- Misses       2159     4055     +1896     
+ Partials      648      337      -311     
```

| Flag | Coverage Δ | |
|---|---|---|
| e2etests | `?` | |
| unittests | `42.20% <0.00%> (-1.03%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore) | Coverage Δ | |
|---|---|---|
| [pkg/types/alpine/v0.0.1/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL2FscGluZS92MC4wLjEvZW50cnkuZ28=) | `52.29% <0.00%> (-20.62%)` | :arrow_down: |
| [pkg/types/cose/v0.0.1/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL2Nvc2UvdjAuMC4xL2VudHJ5Lmdv) | `50.59% <0.00%> (-4.39%)` | :arrow_down: |
| [pkg/types/entries.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL2VudHJpZXMuZ28=) | `4.61% <0.00%> (-47.93%)` | :arrow_down: |
| [pkg/types/hashedrekord/v0.0.1/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL2hhc2hlZHJla29yZC92MC4wLjEvZW50cnkuZ28=) | `48.36% <0.00%> (-24.20%)` | :arrow_down: |
| [pkg/types/helm/v0.0.1/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL2hlbG0vdjAuMC4xL2VudHJ5Lmdv) | `46.00% <0.00%> (-3.18%)` | :arrow_down: |
| [pkg/types/intoto/v0.0.1/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL2ludG90by92MC4wLjEvZW50cnkuZ28=) | `48.63% <0.00%> (-16.81%)` | :arrow_down: |
| [pkg/types/intoto/v0.0.2/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL2ludG90by92MC4wLjIvZW50cnkuZ28=) | `46.26% <0.00%> (-19.97%)` | :arrow_down: |
| [pkg/types/jar/v0.0.1/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL2phci92MC4wLjEvZW50cnkuZ28=) | `36.93% <0.00%> (-19.61%)` | :arrow_down: |
| [pkg/types/rekord/v0.0.1/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL3Jla29yZC92MC4wLjEvZW50cnkuZ28=) | `49.26% <0.00%> (-18.34%)` | :arrow_down: |
| [pkg/types/rfc3161/v0.0.1/entry.go](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore#diff-cGtnL3R5cGVzL3JmYzMxNjEvdjAuMC4xL2VudHJ5Lmdv) | `36.87% <0.00%> (-26.28%)` | :arrow_down: |
| ... and [3 more](https://codecov.io/gh/sigstore/rekor/pull/1410?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore) | |

... and [45 files with indirect coverage changes](https://codecov.io/gh/sigstore/rekor/pull/1410/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore)

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sigstore)


Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 56aa88f..ae237fd 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -50,7 +50,7 @@ jobs:
       - uses: ko-build/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa # v0.6
 
       - name: Set up Cloud SDK
-        uses: google-github-actions/auth@e8df18b60c5dd38ba618c121b779307266153fbf # v1.1.0
+        uses: google-github-actions/auth@35b0e87d162680511bf346c299f71c9c5c379033 # v1.1.1
         with:
           workload_identity_provider: 'projects/498091336538/locations/global/workloadIdentityPools/githubactions/providers/sigstore-rekor'
           service_account: 'github-actions-rekor@projectsigstore.iam.gserviceaccount.com'
diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml
index 263e2eb..fbfaf54 100644
--- a/.github/workflows/verify.yml
+++ b/.github/workflows/verify.yml
@@ -59,4 +59,4 @@ jobs:
         uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5 # v3.4.0
         timeout-minutes: 5
         with:
-          version: v1.51
+          version: v1.52
diff --git a/Dockerfile b/Dockerfile
index 3ad1fe3..cec63c5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM golang:1.20.4@sha256:31a8f92b17829b3ccddf0add184f18203acfd79ccc1bcb5c43803ab1c4836cca AS builder
+FROM golang:1.20.4@sha256:685a22e459f9516f27d975c5cc6accc11223ee81fdfbbae60e39cc3b87357306 AS builder
 ENV APP_ROOT=/opt/app-root
 ENV GOPATH=$APP_ROOT
 
@@ -31,7 +31,7 @@ RUN CGO_ENABLED=0 go build -gcflags "all=-N -l" -ldflags "${SERVER_LDFLAGS}" -o
 RUN go test -c -ldflags "${SERVER_LDFLAGS}" -cover -covermode=count -coverpkg=./... -o rekor-server_test ./cmd/rekor-server
 
 # Multi-Stage production build
-FROM golang:1.20.4@sha256:31a8f92b17829b3ccddf0add184f18203acfd79ccc1bcb5c43803ab1c4836cca as deploy
+FROM golang:1.20.4@sha256:685a22e459f9516f27d975c5cc6accc11223ee81fdfbbae60e39cc3b87357306 as deploy
 
 # Retrieve the binary from the previous stage
 COPY --from=builder /opt/app-root/src/rekor-server /usr/local/bin/rekor-server
diff --git a/cmd/rekor-cli/app/pflags.go b/cmd/rekor-cli/app/pflags.go
index ad56b43..1f147ca 100644
--- a/cmd/rekor-cli/app/pflags.go
+++ b/cmd/rekor-cli/app/pflags.go
@@ -25,7 +25,6 @@ import (
 
 	"github.com/sigstore/rekor/pkg/pki"
 	"github.com/sigstore/rekor/pkg/sharding"
-	"github.com/sigstore/rekor/pkg/util"
 
 	"github.com/spf13/pflag"
 
@@ -224,17 +223,17 @@ func isURL(v string) bool {
 // [sha1:]<40 hexadecimal characters>
 // where [sha256:] and [sha1:] are optional
 func validateSHAValue(v string) error {
-	err := util.ValidateSHA1Value(v)
+	err := validateSHA1Value(v)
 	if err == nil {
 		return nil
 	}
 
-	err = util.ValidateSHA256Value(v)
+	err = validateSHA256Value(v)
 	if err == nil {
 		return nil
 	}
 
-	err = util.ValidateSHA512Value(v)
+	err = validateSHA512Value(v)
 	if err == nil {
 		return nil
 	}
diff --git a/cmd/rekor-cli/app/state/state.go b/cmd/rekor-cli/app/state/state.go
index 21c0088..1985b81 100644
--- a/cmd/rekor-cli/app/state/state.go
+++ b/cmd/rekor-cli/app/state/state.go
@@ -47,10 +47,7 @@ func Dump(key string, sth *util.SignedCheckpoint) error {
 	if err != nil {
 		return err
 	}
-	if err := os.WriteFile(statePath, b, 0600); err != nil {
-		return err
-	}
-	return nil
+	return os.WriteFile(statePath, b, 0600)
 }
 
 func loadStateFile() persistedState {
diff --git a/cmd/rekor-cli/app/upload.go b/cmd/rekor-cli/app/upload.go
index aedc6da..040ab4e 100644
--- a/cmd/rekor-cli/app/upload.go
+++ b/cmd/rekor-cli/app/upload.go
@@ -61,10 +61,7 @@ var uploadCmd = &cobra.Command{
 		if err := viper.BindPFlags(cmd.Flags()); err != nil {
 			return err
 		}
-		if err := validateArtifactPFlags(false, false); err != nil {
-			return err
-		}
-		return nil
+		return validateArtifactPFlags(false, false)
 	},
 	Long: `This command takes the public key, signature and URL of the release artifact and uploads it to the rekor server.`,
 	Run: format.WrapCmd(func(args []string) (interface{}, error) {
diff --git a/pkg/util/validate.go b/cmd/rekor-cli/app/validate.go
similarity index 93%
rename from pkg/util/validate.go
rename to cmd/rekor-cli/app/validate.go
index f8f015f..9ff9325 100644
--- a/pkg/util/validate.go
+++ b/cmd/rekor-cli/app/validate.go
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package util
+package app
 
 import (
 	"strings"
@@ -24,7 +24,7 @@ import (
 // validateSHA512Value ensures that the supplied string matches the
 // following format: [sha512:]<128 hexadecimal characters>
 // where [sha512:] is optional
-func ValidateSHA512Value(v string) error {
+func validateSHA512Value(v string) error {
 	var prefix, hash string
 
 	split := strings.SplitN(v, ":", 2)
@@ -48,7 +48,7 @@ func ValidateSHA512Value(v string) error {
 // validateSHA256Value ensures that the supplied string matches the following format:
 // [sha256:]<64 hexadecimal characters>
 // where [sha256:] is optional
-func ValidateSHA256Value(v string) error {
+func validateSHA256Value(v string) error {
 	var prefix, hash string
 
 	split := strings.SplitN(v, ":", 2)
@@ -69,7 +69,7 @@ func ValidateSHA256Value(v string) error {
 	return validate.Struct(s)
 }
 
-func ValidateSHA1Value(v string) error {
+func validateSHA1Value(v string) error {
 	var prefix, hash string
 
 	split := strings.SplitN(v, ":", 2)
diff --git a/cmd/rekor-cli/app/verify.go b/cmd/rekor-cli/app/verify.go
index 1d4d86f..cffd81b 100644
--- a/cmd/rekor-cli/app/verify.go
+++ b/cmd/rekor-cli/app/verify.go
@@ -85,10 +85,7 @@ var verifyCmd = &cobra.Command{
 		if err := viper.BindPFlags(cmd.Flags()); err != nil {
 			return fmt.Errorf("error initializing cmd line args: %s", err)
 		}
-		if err := validateArtifactPFlags(true, true); err != nil {
-			return err
-		}
-		return nil
+		return validateArtifactPFlags(true, true)
 	},
 	Run: format.WrapCmd(func(args []string) (interface{}, error) {
 		ctx := context.Background()
diff --git a/cmd/rekor-server/app/watch.go b/cmd/rekor-server/app/watch.go
deleted file mode 100644
index 563a29e..0000000
--- a/cmd/rekor-server/app/watch.go
+++ /dev/null
@@ -1,178 +0,0 @@
-//
-// Copyright 2021 The Sigstore Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package app
-
-import (
-	"context"
-	"crypto"
-	"crypto/x509"
-	"encoding/json"
-	"encoding/pem"
-	"errors"
-	"flag"
-	"fmt"
-	"os"
-	"time"
-
-	_ "gocloud.dev/blob/fileblob" // fileblob
-	_ "gocloud.dev/blob/gcsblob"
-
-	"github.com/spf13/cobra"
-	"github.com/spf13/viper"
-	"gocloud.dev/blob"
-
-	"github.com/sigstore/rekor/pkg/client"
-	genclient "github.com/sigstore/rekor/pkg/generated/client"
-	"github.com/sigstore/rekor/pkg/log"
-	"github.com/sigstore/rekor/pkg/util"
-	"github.com/sigstore/sigstore/pkg/signature"
-)
-
-const rekorSthBucketEnv = "REKOR_STH_BUCKET"
-
-// watchCmd represents the serve command
-var watchCmd = &cobra.Command{
-	Use:   "watch",
-	Short: "Start a process to watch and record STH's from Rekor",
-	Long:  `Start a process to watch and record STH's from Rekor`,
-	PreRun: func(cmd *cobra.Command, args []string) {
-		// these are bound here so that they are not overwritten by other commands
-		if err := viper.BindPFlags(cmd.Flags()); err != nil {
-			log.Logger.Fatal("Error initializing cmd line args: ", err)
-		}
-	},
-	RunE: func(cmd *cobra.Command, args []string) error {
-
-		// Setup the logger to dev/prod
-		log.ConfigureLogger(viper.GetString("log_type"))
-
-		// workaround for https://github.com/sigstore/rekor/issues/68
-		// from https://github.com/golang/glog/commit/fca8c8854093a154ff1eb580aae10276ad6b1b5f
-		_ = flag.CommandLine.Parse([]string{})
-
-		host := viper.GetString("rekor_server.address")
-		port := viper.GetUint("port")
-		interval := viper.GetDuration("interval")
-		url := fmt.Sprintf("http://%s:%d", host, port)
-		c, err := client.GetRekorClient(url)
-		if err != nil {
-			return err
-		}
-
-		keyResp, err := c.Pubkey.GetPublicKey(nil)
-		if err != nil {
-			return err
-		}
-		publicKey := keyResp.Payload
-		block, _ := pem.Decode([]byte(publicKey))
-		if block == nil {
-			return errors.New("failed to decode public key of server")
-		}
-
-		pub, err := x509.ParsePKIXPublicKey(block.Bytes)
-		if err != nil {
-			return err
-		}
-
-		ctx := context.Background()
-		bucketURL := os.Getenv(rekorSthBucketEnv)
-		if bucketURL == "" {
-			log.CliLogger.Fatalf("%s env var must be set", rekorSthBucketEnv)
-		}
-		bucket, err := blob.OpenBucket(ctx, bucketURL)
-		if err != nil {
-			return err
-		}
-		defer bucket.Close()
-		tick := time.NewTicker(interval)
-		var last *SignedAndUnsignedLogRoot
-
-		for {
-			<-tick.C
-			log.Logger.Info("performing check")
-			lr, err := doCheck(c, pub)
-			if err != nil {
-				log.Logger.Warnf("error verifiying tree: %s", err)
-				continue
-			}
-			log.Logger.Infof("Found and verified state at %d", lr.VerifiedLogRoot.Size)
-			if last != nil && last.VerifiedLogRoot.Size == lr.VerifiedLogRoot.Size {
-				log.Logger.Infof("Last tree size is the same as the current one: %d %d",
-					last.VerifiedLogRoot.Size, lr.VerifiedLogRoot.Size)
-				// If it's the same, it shouldn't have changed but we'll still upload anyway
-				// in case that failed.
-			}
-
-			if err := uploadToBlobStorage(ctx, bucket, lr); err != nil {
-				log.Logger.Warnf("error uploading result: %s", err)
-				continue
-			}
-			last = lr
-		}
-	},
-}
-
-func init() {
-	watchCmd.Flags().Duration("interval", 1*time.Minute, "Polling interval")
-	rootCmd.AddCommand(watchCmd)
-}
-
-func doCheck(c *genclient.Rekor, pub crypto.PublicKey) (*SignedAndUnsignedLogRoot, error) {
-	li, err := c.Tlog.GetLogInfo(nil)
-	if err != nil {
-		return nil, fmt.Errorf("getting log info: %w", err)
-	}
-	sth := util.SignedCheckpoint{}
-	if err := sth.UnmarshalText([]byte(*li.Payload.SignedTreeHead)); err != nil {
-		return nil, fmt.Errorf("unmarshalling tree head: %w", err)
-	}
-
-	verifier, err := signature.LoadVerifier(pub, crypto.SHA256)
-	if err != nil {
-		return nil, err
-	}
-
-	if !sth.Verify(verifier) {
-		return nil, fmt.Errorf("signed tree head failed verification: %w", err)
-	}
-
-	return &SignedAndUnsignedLogRoot{
-		VerifiedLogRoot: &sth,
-	}, nil
-}
-
-func uploadToBlobStorage(ctx context.Context, bucket *blob.Bucket, lr *SignedAndUnsignedLogRoot) error {
-	b, err := json.Marshal(lr)
-	if err != nil {
-		return err
-	}
-
-	objName := fmt.Sprintf("sth-%d.json", lr.VerifiedLogRoot.Size)
-	w, err := bucket.NewWriter(ctx, objName, nil)
-	if err != nil {
-		return err
-	}
-	defer w.Close()
-	if _, err := w.Write(b); err != nil {
-		return err
-	}
-	return nil
-}
-
-// For JSON marshalling
-type SignedAndUnsignedLogRoot struct {
-	VerifiedLogRoot *util.SignedCheckpoint
-}
diff --git a/config/watcher.yaml b/config/watcher.yaml
deleted file mode 100644
index 659ad09..0000000
--- a/config/watcher.yaml
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Copyright 2021 The Sigstore Authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  namespace: rekor-system
-  name: rekor-watcher
-  labels:
-    app: rekor-watcher
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: rekor-watcher
-  template:
-    metadata:
-      labels:
-        app: rekor-watcher
-      annotations:
-        prometheus.io/scrape: "true"
-        prometheus.io/path: /metrics
-        prometheus.io/port: "2112"
-    spec:
-      containers:
-      - name: rekor-watcher
-        image: ko://github.com/sigstore/rekor/cmd/rekor-server
-        command: ["/ko-app/rekor-server"]
-        ports:
-        - containerPort: 3000
-        - containerPort: 2112 # metrics
-        args: [
-          "watch",
-          "--rekor_server.address=rekor-server",
-          "--port=80",
-          "--log_type=prod",
-        ]
-        env:
-        - name: REKOR_STH_BUCKET
-          value: "gs://rekor-sth"
-        resources:
-          requests:
-            memory: "1G"
-            cpu: ".5"
-        securityContext:
-          readOnlyRootFilesystem: true
-          runAsNonRoot: true
-          capabilities:
-            drop:
-            - all
diff --git a/go.mod b/go.mod
index 4b27de6..0981cb6 100644
--- a/go.mod
+++ b/go.mod
@@ -18,7 +18,7 @@ require (
 	github.com/go-playground/validator/v10 v10.13.0
 	github.com/google/go-cmp v0.5.9
 	github.com/google/rpmpack v0.0.0-20210518075352-dc539ef4f2ea
-	github.com/google/trillian v1.5.1
+	github.com/google/trillian v1.5.2
 	github.com/in-toto/in-toto-golang v0.9.0
 	github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b
 	github.com/mitchellh/go-homedir v1.1.0
@@ -39,9 +39,9 @@ require (
 	go.uber.org/goleak v1.2.1
 	go.uber.org/zap v1.24.0
 	gocloud.dev v0.29.0
-	golang.org/x/crypto v0.8.0
+	golang.org/x/crypto v0.9.0
 	golang.org/x/mod v0.10.0
-	golang.org/x/net v0.9.0
+	golang.org/x/net v0.10.0
 	golang.org/x/sync v0.2.0
 	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
 	google.golang.org/grpc v1.55.0
@@ -57,7 +57,7 @@ require (
 	github.com/hashicorp/go-cleanhttp v0.5.2
 	github.com/hashicorp/go-retryablehttp v0.7.2
 	github.com/redis/go-redis/v9 v9.0.4
-	golang.org/x/exp v0.0.0-20230124195608-d38c7dcee874
+	golang.org/x/exp v0.0.0-20230321023759-10a507213a29
 )
 
 require (
@@ -71,14 +71,14 @@ require (
 	github.com/jellydator/ttlcache/v3 v3.0.1 // indirect
 	go.opentelemetry.io/otel v1.14.0 // indirect
 	go.opentelemetry.io/otel/trace v1.14.0 // indirect
-	k8s.io/klog/v2 v2.80.1 // indirect
+	k8s.io/klog/v2 v2.100.1 // indirect
 )
 
 require (
 	cloud.google.com/go v0.110.0 // indirect
 	cloud.google.com/go/compute v1.19.0 // indirect
 	cloud.google.com/go/iam v0.13.0 // indirect
-	cloud.google.com/go/kms v1.10.1 // indirect
+	cloud.google.com/go/kms v1.10.2 // indirect
 	cloud.google.com/go/storage v1.29.0 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cavaliercoder/badio v0.0.0-20160213150051-ce5280129e9e // indirect
@@ -115,7 +115,7 @@ require (
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opentracing/opentracing-go v1.2.0 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
-	github.com/prometheus/client_model v0.3.0 // indirect
+	github.com/prometheus/client_model v0.4.0 // indirect
 	github.com/prometheus/common v0.42.0 // indirect
 	github.com/prometheus/procfs v0.9.0 // indirect
 	github.com/shibumi/go-pathspec v1.3.0 // indirect
@@ -129,7 +129,7 @@ require (
 	github.com/x448/float16 v0.8.4 // indirect
 	go.mongodb.org/mongo-driver v1.11.3 // indirect
 	go.opencensus.io v0.24.0 // indirect
-	go.step.sm/crypto v0.29.3
+	go.step.sm/crypto v0.30.0
 	go.uber.org/atomic v1.10.0 // indirect
 	go.uber.org/multierr v1.9.0 // indirect
 	golang.org/x/oauth2 v0.7.0 // indirect
diff --git a/go.sum b/go.sum
index b396f3f..b5d0f6a 100644
--- a/go.sum
+++ b/go.sum
@@ -230,8 +230,8 @@ cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxs
 cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg=
 cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0=
 cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg=
-cloud.google.com/go/kms v1.10.1 h1:7hm1bRqGCA1GBRQUrp831TwJ9TWhP+tvLuP497CQS2g=
-cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI=
+cloud.google.com/go/kms v1.10.2 h1:8UePKEypK3SQ6g+4mn/s/VgE5L7XOh+FwGGRUqvY3Hw=
+cloud.google.com/go/kms v1.10.2/go.mod h1:9mX3Q6pdroWzL20pbK6RaOdBbXBEhMNgK4Pfz2bweb4=
 cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
 cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
 cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE=
@@ -559,7 +559,7 @@ github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4
 github.com/aws/aws-sdk-go v1.44.156/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 github.com/aws/aws-sdk-go v1.44.187/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 github.com/aws/aws-sdk-go v1.44.200/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
-github.com/aws/aws-sdk-go v1.44.257 h1:HwelXYZZ8c34uFFhgVw3ybu2gB5fkk8KLj2idTvzZb8=
+github.com/aws/aws-sdk-go v1.44.259 h1:7yDn1dcv4DZFMKpu+2exIH5O6ipNj9qXrKfdMUaIJwY=
 github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
 github.com/aws/aws-sdk-go-v2 v1.17.4/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
 github.com/aws/aws-sdk-go-v2 v1.18.0 h1:882kkTpSFhdgYRKVZ/VCgf7sd0ru57p2JCxz4/oN5RY=
@@ -1025,8 +1025,8 @@ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn
 github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ=
 github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4=
 github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
-github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
 github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
@@ -1199,8 +1199,8 @@ github.com/google/rpmpack v0.0.0-20210518075352-dc539ef4f2ea/go.mod h1:+y9lKiqDh
 github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE=
 github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
 github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
-github.com/google/trillian v1.5.1 h1:2p1l13f0eWd7eOShwarwIxutYYnGzY/5S+xYewQIPkU=
-github.com/google/trillian v1.5.1/go.mod h1:EcDttN8nf+EoAiyLigBAp9ebncZI6rhJPyxZ+dQ6HSo=
+github.com/google/trillian v1.5.2 h1:roGP6G8aaAch7vP08+oitPkvmZzxjTfIkguozqJ04Ok=
+github.com/google/trillian v1.5.2/go.mod h1:H8vOoa2dxd3xCdMzOOwt9kIz/3MSoJhcqLJGG8iRwbg=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -1479,8 +1479,8 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
 github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
 github.com/linode/linodego v1.4.0/go.mod h1:PVsRxSlOiJyvG4/scTszpmZDTdgS+to3X6eS8pRrWI8=
 github.com/linode/linodego v1.12.0/go.mod h1:NJlzvlNtdMRRkXb0oN6UWzUkj6t+IBsyveHgZ5Ppjyk=
 github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
@@ -1722,8 +1722,9 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
 github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
+github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
+github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
 github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -2048,8 +2049,8 @@ go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg
 go.opentelemetry.io/proto/otlp v0.12.1/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
 go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
 go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
-go.step.sm/crypto v0.29.3 h1:lFCsFQQGic1VZIa0B/87iMCDy67+LW8eEl119GTyeWI=
-go.step.sm/crypto v0.29.3/go.mod h1:0lYeIyQMJbFJ27L4BOGaq2gnuTgOShf+Ju/cTsMULq4=
+go.step.sm/crypto v0.30.0 h1:EzqPTvW1g6kxEnfIf/exDW+MhHGeEhtoNMhQX7P/UwI=
+go.step.sm/crypto v0.30.0/go.mod h1:6jFFgUoafyHvb6rNq3NJrBByof4SCzj1n8ThyXuMVAM=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@@ -2126,8 +2127,8 @@ golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0
 golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
 golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
-golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
-golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
+golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
+golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -2142,8 +2143,9 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
-golang.org/x/exp v0.0.0-20230124195608-d38c7dcee874 h1:kWC3b7j6Fu09SnEBr7P4PuQyM0R6sqyH9R+EjIvT1nQ=
 golang.org/x/exp v0.0.0-20230124195608-d38c7dcee874/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
+golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
+golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -2267,8 +2269,8 @@ golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmL
 golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
 golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -2995,8 +2997,9 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
 k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
 k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
 k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
 k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
+k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
 k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
 k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
 k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
diff --git a/hack/tools/go.mod b/hack/tools/go.mod
index eda997a..a4b3418 100644
--- a/hack/tools/go.mod
+++ b/hack/tools/go.mod
@@ -5,35 +5,35 @@ go 1.20
 require (
 	github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230329111138-12e09aba5ebd
 	github.com/go-swagger/go-swagger v0.30.4
-	github.com/google/trillian v1.5.1
+	github.com/google/trillian v1.5.2
 	github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad
 )
 
 require (
 	bitbucket.org/creachadair/shell v0.0.7 // indirect
-	cloud.google.com/go v0.107.0 // indirect
-	cloud.google.com/go/compute v1.13.0 // indirect
-	cloud.google.com/go/compute/metadata v0.2.2 // indirect
-	cloud.google.com/go/monitoring v1.8.0 // indirect
-	cloud.google.com/go/spanner v1.42.0 // indirect
-	cloud.google.com/go/trace v1.4.0 // indirect
-	contrib.go.opencensus.io/exporter/stackdriver v0.13.12 // indirect
+	cloud.google.com/go v0.110.0 // indirect
+	cloud.google.com/go/compute v1.19.0 // indirect
+	cloud.google.com/go/compute/metadata v0.2.3 // indirect
+	cloud.google.com/go/monitoring v1.13.0 // indirect
+	cloud.google.com/go/spanner v1.45.1 // indirect
+	cloud.google.com/go/trace v1.9.0 // indirect
+	contrib.go.opencensus.io/exporter/stackdriver v0.13.14 // indirect
 	github.com/Masterminds/goutils v1.1.1 // indirect
 	github.com/Masterminds/semver/v3 v3.2.0 // indirect
 	github.com/Masterminds/sprig/v3 v3.2.3 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
-	github.com/aws/aws-sdk-go v1.37.0 // indirect
+	github.com/aws/aws-sdk-go v1.43.31 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
-	github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
-	github.com/cespare/xxhash/v2 v2.1.2 // indirect
-	github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect
-	github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect
-	github.com/cockroachdb/cockroach-go/v2 v2.2.19 // indirect
+	github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
+	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
+	github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b // indirect
+	github.com/cockroachdb/cockroach-go/v2 v2.3.3 // indirect
 	github.com/coreos/go-semver v0.3.0 // indirect
 	github.com/coreos/go-systemd/v22 v22.3.2 // indirect
 	github.com/cyphar/filepath-securejoin v0.2.3 // indirect
-	github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect
-	github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect
+	github.com/envoyproxy/go-control-plane v0.10.3 // indirect
+	github.com/envoyproxy/protoc-gen-validate v0.9.1 // indirect
 	github.com/felixge/httpsnoop v1.0.3 // indirect
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/go-logr/logr v1.2.3 // indirect
@@ -48,17 +48,18 @@ require (
 	github.com/go-openapi/strfmt v0.21.3 // indirect
 	github.com/go-openapi/swag v0.22.3 // indirect
 	github.com/go-openapi/validate v0.22.0 // indirect
-	github.com/go-sql-driver/mysql v1.7.0 // indirect
+	github.com/go-sql-driver/mysql v1.7.1 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/mock v1.6.0 // indirect
-	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/google/go-cmp v0.5.9 // indirect
+	github.com/google/s2a-go v0.1.3 // indirect
 	github.com/google/uuid v1.3.0 // indirect
-	github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
-	github.com/googleapis/gax-go/v2 v2.7.0 // indirect
+	github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
+	github.com/googleapis/gax-go/v2 v2.8.0 // indirect
 	github.com/gorilla/handlers v1.5.1 // indirect
-	github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
+	github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.3.3 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
@@ -75,10 +76,10 @@ require (
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/kr/pretty v0.3.1 // indirect
 	github.com/kr/text v0.2.0 // indirect
-	github.com/lib/pq v1.10.7 // indirect
+	github.com/lib/pq v1.10.9 // indirect
 	github.com/magiconair/properties v1.8.6 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
-	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/mitchellh/reflectwalk v1.0.2 // indirect
@@ -86,11 +87,10 @@ require (
 	github.com/pelletier/go-toml v1.9.5 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.5 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
-	github.com/prometheus/client_golang v1.14.0 // indirect
-	github.com/prometheus/client_model v0.3.0 // indirect
-	github.com/prometheus/common v0.37.0 // indirect
-	github.com/prometheus/procfs v0.8.0 // indirect
-	github.com/prometheus/prometheus v2.5.0+incompatible // indirect
+	github.com/prometheus/client_golang v1.15.1 // indirect
+	github.com/prometheus/client_model v0.4.0 // indirect
+	github.com/prometheus/common v0.42.0 // indirect
+	github.com/prometheus/procfs v0.9.0 // indirect
 	github.com/rogpeppe/go-internal v1.9.0 // indirect
 	github.com/shopspring/decimal v1.3.1 // indirect
 	github.com/spf13/afero v1.9.2 // indirect
@@ -100,31 +100,31 @@ require (
 	github.com/spf13/viper v1.14.0 // indirect
 	github.com/subosito/gotenv v1.4.1 // indirect
 	github.com/toqueteos/webbrowser v1.2.0 // indirect
-	github.com/transparency-dev/merkle v0.0.1 // indirect
-	go.etcd.io/etcd/api/v3 v3.5.6 // indirect
-	go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect
-	go.etcd.io/etcd/client/v3 v3.5.6 // indirect
+	github.com/transparency-dev/merkle v0.0.2 // indirect
+	go.etcd.io/etcd/api/v3 v3.5.8 // indirect
+	go.etcd.io/etcd/client/pkg/v3 v3.5.8 // indirect
+	go.etcd.io/etcd/client/v3 v3.5.8 // indirect
 	go.mongodb.org/mongo-driver v1.11.1 // indirect
 	go.opencensus.io v0.24.0 // indirect
-	go.uber.org/atomic v1.9.0 // indirect
+	go.uber.org/atomic v1.10.0 // indirect
 	go.uber.org/multierr v1.8.0 // indirect
 	go.uber.org/zap v1.21.0 // indirect
-	golang.org/x/crypto v0.5.0 // indirect
-	golang.org/x/mod v0.7.0 // indirect
-	golang.org/x/net v0.7.0 // indirect
-	golang.org/x/oauth2 v0.4.0 // indirect
-	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/sys v0.5.0 // indirect
-	golang.org/x/text v0.7.0 // indirect
-	golang.org/x/tools v0.5.0 // indirect
+	golang.org/x/crypto v0.8.0 // indirect
+	golang.org/x/mod v0.10.0 // indirect
+	golang.org/x/net v0.9.0 // indirect
+	golang.org/x/oauth2 v0.7.0 // indirect
+	golang.org/x/sync v0.2.0 // indirect
+	golang.org/x/sys v0.8.0 // indirect
+	golang.org/x/text v0.9.0 // indirect
+	golang.org/x/tools v0.8.0 // indirect
 	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
-	google.golang.org/api v0.104.0 // indirect
+	google.golang.org/api v0.121.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/genproto v0.0.0-20221206210731-b1a01be3a5f6 // indirect
-	google.golang.org/grpc v1.51.0 // indirect
-	google.golang.org/protobuf v1.28.1 // indirect
+	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
+	google.golang.org/grpc v1.54.0 // indirect
+	google.golang.org/protobuf v1.30.0 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/klog/v2 v2.80.1 // indirect
+	k8s.io/klog/v2 v2.100.1 // indirect
 )
diff --git a/hack/tools/go.sum b/hack/tools/go.sum
index 84fc695..1be1920 100644
--- a/hack/tools/go.sum
+++ b/hack/tools/go.sum
@@ -19,52 +19,40 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
 cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
 cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
 cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
-cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
-cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
-cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
-cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
-cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
-cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
-cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
-cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
-cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
-cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
-cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww=
-cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
+cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
+cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
 cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.13.0 h1:AYrLkB8NPdDRslNp4Jxmzrhdr03fUAIDbiGFjLWowoU=
-cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE=
-cloud.google.com/go/compute/metadata v0.2.2 h1:aWKAjYaBaOSrpKl57+jnS/3fJRQnxL7TvR/u1VVbt6k=
-cloud.google.com/go/compute/metadata v0.2.2/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
+cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ=
+cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=
+cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
+cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/iam v0.8.0 h1:E2osAkZzxI/+8pZcxVLcDtAQx/u+hZXVryUaYQ5O0Kk=
-cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs=
-cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4=
-cloud.google.com/go/monitoring v1.8.0 h1:c9riaGSPQ4dUKWB+M1Fl0N+iLxstMbCktdEwYSPGDvA=
-cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4=
+cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
+cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
+cloud.google.com/go/monitoring v1.13.0 h1:2qsrgXGVoRXpP7otZ14eE1I568zAa92sJSDPyOJvwjM=
+cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
 cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
 cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/spanner v1.42.0 h1:W6RIkN4X0htp+GRNWK1rhXYYcjb5znZDuyIO2CWkoM0=
-cloud.google.com/go/spanner v1.42.0/go.mod h1:KEfcH3c7wMqO6bTZqY1/BDS5DZfC1k3U0QZTlnlvW/0=
+cloud.google.com/go/spanner v1.45.1 h1:vHFqBMuPdTCwA8b9+IyQbGppQoqx7xJfcSa81d7gtAk=
+cloud.google.com/go/spanner v1.45.1/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
-cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=
-cloud.google.com/go/trace v1.4.0 h1:qO9eLn2esajC9sxpqp1YKX37nXC3L4BfGnPS0Cx9dYo=
-cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y=
-contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY=
-contrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ=
+cloud.google.com/go/trace v1.9.0 h1:olxC0QHC59zgJVALtgqfD9tGk0lfeCP5/AGXL3Px/no=
+cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk=
+contrib.go.opencensus.io/exporter/stackdriver v0.13.14 h1:zBakwHardp9Jcb8sQHcHpXy/0+JIb1M8KjigCJzx7+4=
+contrib.go.opencensus.io/exporter/stackdriver v0.13.14/go.mod h1:5pSSGY0Bhuk7waTHuDf4aQ8D2DrhgETRo9fy6k3Xlzc=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230329111138-12e09aba5ebd h1:1tbEqR4NyQLgiod7vLXSswHteGetAVZrMGCqrJxLKRs=
 github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230329111138-12e09aba5ebd/go.mod h1:0vOOKsOMKPThRu9lQMAxcQ8D60f8U+wHXl07SyUw0+U=
@@ -80,31 +68,25 @@ github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBa
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
 github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
 github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk=
-github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
+github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0=
+github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
 github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
 github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
+github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=
 github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
+github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
-github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -112,18 +94,20 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI=
 github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
+github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
+github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
 github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 h1:KwaoQzs/WeUxxJqiJsZ4euOly1Az/IgZXXSxlD/UBNk=
-github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b h1:ACGZRIr7HsgBKHsueQ1yM4WaVaXh21ynwqsF8M8tXhA=
+github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
 github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
-github.com/cockroachdb/cockroach-go/v2 v2.2.19 h1:YIHyz17jZumBeXPuoZKq/0nrITsqDoDD8/KQt3/xiyc=
-github.com/cockroachdb/cockroach-go/v2 v2.2.19/go.mod h1:mzlIDDBALQfEjv/7DU12fb2AfQ/MUYTlychcMpWp9QI=
+github.com/cockroachdb/cockroach-go/v2 v2.3.3 h1:fNmtG6XhoA1DhdDCIu66YyGSsNb1szj4CaAsbDxRmy4=
+github.com/cockroachdb/cockroach-go/v2 v2.3.3/go.mod h1:1wNJ45eSXW9AnOc3skntW9ZUZz6gxrQK3cOj3rK+BC8=
 github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
 github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -137,21 +121,20 @@ github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
-github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
-github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0=
-github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
+github.com/envoyproxy/go-control-plane v0.10.3 h1:xdCVXxEe0Y3FQith+0cj2irwZudqGYvecuLB1HtdexY=
+github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v0.6.2 h1:JiO+kJTpmYGjEodY7O1Zk8oZcNz1+f30UtwtXoFUPzE=
-github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
+github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
+github.com/envoyproxy/protoc-gen-validate v0.9.1 h1:PS7VIOgmSVhWUEeZwTe7z7zouA22Cr590PzXKbZHOVY=
+github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
 github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
 github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@@ -162,14 +145,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
-github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
 github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -210,9 +187,8 @@ github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/
 github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
 github.com/go-openapi/validate v0.22.0 h1:b0QecH6VslW/TxtpKgzpO1SNG7GU2FsaqKdP1E2T50Y=
 github.com/go-openapi/validate v0.22.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
-github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
-github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
+github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-swagger/go-swagger v0.30.4 h1:cPrWLSXY6ZdcgfRicOj0lANg72TkTHz6uv/OlUdzO5U=
 github.com/go-swagger/go-swagger v0.30.4/go.mod h1:YM5D5kR9c1ft3ynMXvDk2uo/7UZHKFEqKXcAL9f4Phc=
@@ -243,15 +219,14 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
 github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
-github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
 github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
 github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
 github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -264,7 +239,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
 github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
-github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
 github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
 github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -282,11 +256,10 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
@@ -302,13 +275,12 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
 github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -319,36 +291,32 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
 github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/trillian v1.5.1 h1:2p1l13f0eWd7eOShwarwIxutYYnGzY/5S+xYewQIPkU=
-github.com/google/trillian v1.5.1/go.mod h1:EcDttN8nf+EoAiyLigBAp9ebncZI6rhJPyxZ+dQ6HSo=
+github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE=
+github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
+github.com/google/trillian v1.5.2 h1:roGP6G8aaAch7vP08+oitPkvmZzxjTfIkguozqJ04Ok=
+github.com/google/trillian v1.5.2/go.mod h1:H8vOoa2dxd3xCdMzOOwt9kIz/3MSoJhcqLJGG8iRwbg=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs=
-github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
+github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
+github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
-github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
-github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
-github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
+github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc=
+github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
 github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
 github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
-github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
-github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
+github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
+github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
-github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -372,7 +340,6 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU
 github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
 github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
 github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
-github.com/jackc/pgconn v1.12.0/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono=
 github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8=
 github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono=
 github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
@@ -404,7 +371,6 @@ github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08
 github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
 github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
 github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
-github.com/jackc/pgx/v4 v4.16.0/go.mod h1:N0A9sFdWzkw/Jy1lwoiB64F2+ugFZi987zRxcPez/wI=
 github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y=
 github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ=
 github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
@@ -414,27 +380,17 @@ github.com/jackc/puddle v1.2.1 h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw=
 github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
 github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
 github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
-github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
-github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
-github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
 github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
-github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
 github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
 github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -442,9 +398,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
 github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@@ -457,10 +411,9 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
-github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
+github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
+github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
 github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
 github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -475,9 +428,8 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
 github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
-github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
+github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
 github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
 github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
 github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@@ -488,16 +440,9 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
 github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
 github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
-github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
@@ -516,35 +461,16 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ
 github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
-github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
-github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
+github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
-github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
-github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
-github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
-github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
-github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
-github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg=
-github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
+github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
+github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
+github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
+github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
+github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
+github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -559,11 +485,9 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz
 github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
 github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
 github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@@ -604,8 +528,8 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
 github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
 github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
 github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
-github.com/transparency-dev/merkle v0.0.1 h1:T9/9gYB8uZl7VOJIhdwjALeRWlxUxSfDEysjfmx+L9E=
-github.com/transparency-dev/merkle v0.0.1/go.mod h1:B8FIw5LTq6DaULoHsVFRzYIUDkl8yuSwCdZnOZGKL/A=
+github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=
+github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A=
 github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad h1:W0LEBv82YCGEtcmPA3uNZBI33/qF//HAAs3MawDjRa0=
 github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=
 github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
@@ -622,17 +546,17 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
-go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
-go.etcd.io/etcd/api/v3 v3.5.6 h1:Cy2qx3npLcYqTKqGJzMypnMv2tiRyifZJ17BlWIWA7A=
-go.etcd.io/etcd/api/v3 v3.5.6/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8=
-go.etcd.io/etcd/client/pkg/v3 v3.5.6 h1:TXQWYceBKqLp4sa87rcPs11SXxUA/mHwH975v+BDvLU=
-go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ=
-go.etcd.io/etcd/client/v2 v2.305.6 h1:fIDR0p4KMjw01MJMfUIDWdQbjo06PD6CeYM5z4EHLi0=
-go.etcd.io/etcd/client/v3 v3.5.6 h1:coLs69PWCXE9G4FKquzNaSHrRyMCAXwF+IX1tAPVO8E=
-go.etcd.io/etcd/client/v3 v3.5.6/go.mod h1:f6GRinRMCsFVv9Ht42EyY7nfsVGwrNO0WEoS2pRKzQk=
-go.etcd.io/etcd/pkg/v3 v3.5.6 h1:k1GZrGrfMHy5/cg2bxNGsmLTFisatyhDYCFLRuaavWg=
-go.etcd.io/etcd/raft/v3 v3.5.6 h1:tOmx6Ym6rn2GpZOrvTGJZciJHek6RnC3U/zNInzIN50=
-go.etcd.io/etcd/server/v3 v3.5.6 h1:RXuwaB8AMiV62TqcqIt4O4bG8NWjsxOkDJVT3MZI5Ds=
+go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
+go.etcd.io/etcd/api/v3 v3.5.8 h1:Zf44zJszoU7zRV0X/nStPenegNXoFDWcB/MwrJbA+L4=
+go.etcd.io/etcd/api/v3 v3.5.8/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k=
+go.etcd.io/etcd/client/pkg/v3 v3.5.8 h1:tPp9YRn/UBFAHdhOQUII9eUs7aOK35eulpMhX4YBd+M=
+go.etcd.io/etcd/client/pkg/v3 v3.5.8/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4=
+go.etcd.io/etcd/client/v2 v2.305.8 h1:IGp9Ozt8awy3qRTXSIYJd/o/cr4oUyrm9MF1RJ2dr/c=
+go.etcd.io/etcd/client/v3 v3.5.8 h1:B6ngTKZSWWowHEoaucOKHQR/AtZKaoHLiUpWxOLG4l4=
+go.etcd.io/etcd/client/v3 v3.5.8/go.mod h1:idZYIPVkttBJBiRigkB5EM0MmEyx8jcl18zCV3F5noc=
+go.etcd.io/etcd/pkg/v3 v3.5.8 h1:hz6w5Cb4p7dbt642m8Y35Ts9yWPWUCymc3v4Z/aiGEU=
+go.etcd.io/etcd/raft/v3 v3.5.8 h1:wM4IAfiY1+vrCAkUicIOzkyjpV9MawnAul2KvxeMgy4=
+go.etcd.io/etcd/server/v3 v3.5.8 h1:eK9fU6Pd6IJD1k0u4zAq1NZsSsEOOimlP3kIkpcQrho=
 go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
 go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
 go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
@@ -644,24 +568,26 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
 go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0 h1:Wx7nFnvCaissIUZxPkBqDz2963Z+Cl+PkYbDKzTxDqQ=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0 h1:Ky1MObd188aGbgb5OgNnwGuEEwI9MVIcc7rBW6zk5Ak=
 go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1 h1:ofMbch7i29qIUf7VtF+r0HRF6ac0SBaPSziSsKp7wkk=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1 h1:CFMFNoz+CGprjFAFy+RJFrfEe4GBia3RRm2a4fREvCA=
+go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.1 h1:T1FtMXHM2YPIUrYxSbTIAYDCvUZVpNdl7hDMDnp09cE=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.6.1 h1:EvIC2jmn1+24OABwtw2Lng5yxy5eYJ8nf461UaHXTms=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.6.1 h1:G45R6KdPgxe9UaZJMF4VUnsYgZpOHCSgl7FiOEV6570=
 go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs=
 go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
-go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4=
+go.opentelemetry.io/proto/otlp v0.15.0 h1:h0bKrvdrT/9sBwEJ6iWUqT/N/xPcS66bL4u3isneJ6w=
+go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
-go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
+go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
 go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
 go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -674,7 +600,7 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E
 go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
-go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
+go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
 go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
 go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -693,11 +619,11 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
-golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
+golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
+golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -735,11 +661,10 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
-golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
+golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -747,7 +672,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -771,21 +695,16 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
-golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -795,16 +714,9 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
-golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
+golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -818,11 +730,10 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
+golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -841,7 +752,6 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -855,8 +765,6 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -864,39 +772,23 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -910,13 +802,14 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
+golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -940,6 +833,7 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -976,13 +870,10 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4=
-golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
+golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
+golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
 golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1010,20 +901,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
 google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
 google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
-google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
-google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
-google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
-google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
-google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
-google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
-google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
-google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
-google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
-google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E=
-google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
-google.golang.org/api v0.104.0 h1:KBfmLRqdZEbwQleFlSLnzpQJwhjpmNOk4cKQIBDZ9mg=
-google.golang.org/api v0.104.0/go.mod h1:JCspTXJbBxa5ySXw4UgUqVer7DfVxbvc/CTUFqAED5U=
+google.golang.org/api v0.121.0 h1:8Oopoo8Vavxx6gt+sgs8s8/X60WBAtKQq6JqnkF+xow=
+google.golang.org/api v0.121.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1069,34 +948,11 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6D
 google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
-google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
-google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
-google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
-google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
-google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
-google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
-google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20221206210731-b1a01be3a5f6 h1:AGXp12e/9rItf6/4QymU7WsAUwCf+ICW75cuR91nJIc=
-google.golang.org/genproto v0.0.0-20221206210731-b1a01be3a5f6/go.mod h1:1dOng4TWOomJrDGhpXjfCD35wQC6jnC7HpRmOFRqEV0=
+google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -1115,17 +971,11 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv
 google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
-google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
 google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
-google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
-google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
-google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
+google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
+google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
+google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1139,12 +989,11 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
-google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
+google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
@@ -1152,11 +1001,8 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
@@ -1167,9 +1013,6 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gorm.io/driver/postgres v1.3.5/go.mod h1:EGCWefLFQSVFrHGy4J8EtiHCWX5Q8t0yz2Jt9aKkGzU=
-gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
-gorm.io/gorm v1.23.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -1177,10 +1020,9 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
-k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
+k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
 sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
-sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
diff --git a/pkg/api/api.go b/pkg/api/api.go
index 32dd155..bfec95c 100644
--- a/pkg/api/api.go
+++ b/pkg/api/api.go
@@ -34,7 +34,7 @@ import (
 	"github.com/sigstore/rekor/pkg/sharding"
 	"github.com/sigstore/rekor/pkg/signer"
 	"github.com/sigstore/rekor/pkg/storage"
-	"github.com/sigstore/rekor/pkg/util"
+	"github.com/sigstore/rekor/pkg/trillianclient"
 	"github.com/sigstore/sigstore/pkg/cryptoutils"
 	"github.com/sigstore/sigstore/pkg/signature"
 	"github.com/sigstore/sigstore/pkg/signature/options"
@@ -83,7 +83,7 @@ func NewAPI(treeID uint) (*API, error) {
 	tid := int64(treeID)
 	if tid == 0 {
 		log.Logger.Info("No tree ID specified, attempting to create a new tree")
-		t, err := util.CreateAndInitTree(ctx, logAdminClient, logClient)
+		t, err := trillianclient.CreateAndInitTree(ctx, logAdminClient, logClient)
 		if err != nil {
 			return nil, fmt.Errorf("create and init tree: %w", err)
 		}
diff --git a/pkg/api/entries.go b/pkg/api/entries.go
index 4abc5db..1f5bc26 100644
--- a/pkg/api/entries.go
+++ b/pkg/api/entries.go
@@ -40,6 +40,7 @@ import (
 	"github.com/sigstore/rekor/pkg/generated/restapi/operations/entries"
 	"github.com/sigstore/rekor/pkg/log"
 	"github.com/sigstore/rekor/pkg/sharding"
+	"github.com/sigstore/rekor/pkg/trillianclient"
 	"github.com/sigstore/rekor/pkg/types"
 	"github.com/sigstore/rekor/pkg/util"
 	"github.com/sigstore/sigstore/pkg/signature"
@@ -67,7 +68,7 @@ func signEntry(ctx context.Context, signer signature.Signer, entry models.LogEnt
 }
 
 // logEntryFromLeaf creates a signed LogEntry struct from trillian structs
-func logEntryFromLeaf(ctx context.Context, signer signature.Signer, tc util.TrillianClient, leaf *trillian.LogLeaf,
+func logEntryFromLeaf(ctx context.Context, signer signature.Signer, _ trillianclient.TrillianClient, leaf *trillian.LogLeaf,
 	signedLogRoot *trillian.SignedLogRoot, proof *trillian.Proof, tid int64, ranges sharding.LogRanges) (models.LogEntry, error) {
 
 	log.ContextLogger(ctx).Debugf("log entry from leaf %d", leaf.GetLeafIndex())
@@ -186,7 +187,7 @@ func createLogEntry(params entries.CreateLogEntryParams) (models.LogEntry, middl
 		return nil, handleRekorAPIError(params, http.StatusInternalServerError, err, failedToGenerateCanonicalEntry)
 	}
 
-	tc := util.NewTrillianClient(ctx, api.logClient, api.logID)
+	tc := trillianclient.NewTrillianClient(ctx, api.logClient, api.logID)
 
 	resp := tc.AddLeaf(leaf)
 	// this represents overall GRPC response state (not the results of insertion into the log)
@@ -405,7 +406,7 @@ func SearchLogQueryHandler(params entries.SearchLogQueryParams) middleware.Respo
 		for i, hash := range searchHashes {
 			var results map[int64]*trillian.GetEntryAndProofResponse
 			for _, shard := range api.logRanges.AllShards() {
-				tcs := util.NewTrillianClient(httpReqCtx, api.logClient, shard)
+				tcs := trillianclient.NewTrillianClient(httpReqCtx, api.logClient, shard)
 				resp := tcs.GetLeafAndProofByHash(hash)
 				switch resp.Status {
 				case codes.OK:
@@ -431,7 +432,7 @@ func SearchLogQueryHandler(params entries.SearchLogQueryParams) middleware.Respo
 				if leafResp == nil {
 					continue
 				}
-				tcs := util.NewTrillianClient(httpReqCtx, api.logClient, shard)
+				tcs := trillianclient.NewTrillianClient(httpReqCtx, api.logClient, shard)
 				logEntry, err := logEntryFromLeaf(httpReqCtx, api.signer, tcs, leafResp.Leaf, leafResp.SignedLogRoot, leafResp.Proof, shard, api.logRanges)
 				if err != nil {
 					return handleRekorAPIError(params, http.StatusInternalServerError, err, err.Error())
@@ -461,7 +462,7 @@ func retrieveLogEntryByIndex(ctx context.Context, logIndex int) (models.LogEntry
 	log.ContextLogger(ctx).Infof("Retrieving log entry by index %d", logIndex)
 
 	tid, resolvedIndex := api.logRanges.ResolveVirtualIndex(logIndex)
-	tc := util.NewTrillianClient(ctx, api.logClient, tid)
+	tc := trillianclient.NewTrillianClient(ctx, api.logClient, tid)
 	log.ContextLogger(ctx).Debugf("Retrieving resolved index %v from TreeID %v", resolvedIndex, tid)
 
 	resp := tc.GetLeafAndProofByIndex(resolvedIndex)
@@ -525,7 +526,7 @@ func retrieveUUIDFromTree(ctx context.Context, uuid string, tid int64) (models.L
 		return models.LogEntry{}, types.ValidationError(err)
 	}
 
-	tc := util.NewTrillianClient(ctx, api.logClient, tid)
+	tc := trillianclient.NewTrillianClient(ctx, api.logClient, tid)
 	log.ContextLogger(ctx).Debugf("Attempting to retrieve UUID %v from TreeID %v", uuid, tid)
 
 	resp := tc.GetLeafAndProofByHash(hashValue)
@@ -553,7 +554,7 @@ func retrieveUUIDFromTree(ctx context.Context, uuid string, tid int64) (models.L
 
 // handlers for APIs that may be disabled in a given instance
 
-func CreateLogEntryNotImplementedHandler(params entries.CreateLogEntryParams) middleware.Responder {
+func CreateLogEntryNotImplementedHandler(_ entries.CreateLogEntryParams) middleware.Responder {
 	err := &models.Error{
 		Code:    http.StatusNotImplemented,
 		Message: "Create Entry API not enabled in this Rekor instance",
@@ -562,7 +563,7 @@ func CreateLogEntryNotImplementedHandler(params entries.CreateLogEntryParams) mi
 	return entries.NewCreateLogEntryDefault(http.StatusNotImplemented).WithPayload(err)
 }
 
-func GetLogEntryByIndexNotImplementedHandler(params entries.GetLogEntryByIndexParams) middleware.Responder {
+func GetLogEntryByIndexNotImplementedHandler(_ entries.GetLogEntryByIndexParams) middleware.Responder {
 	err := &models.Error{
 		Code:    http.StatusNotImplemented,
 		Message: "Get Log Entry by Index API not enabled in this Rekor instance",
@@ -571,7 +572,7 @@ func GetLogEntryByIndexNotImplementedHandler(params entries.GetLogEntryByIndexPa
 	return entries.NewGetLogEntryByIndexDefault(http.StatusNotImplemented).WithPayload(err)
 }
 
-func GetLogEntryByUUIDNotImplementedHandler(params entries.GetLogEntryByUUIDParams) middleware.Responder {
+func GetLogEntryByUUIDNotImplementedHandler(_ entries.GetLogEntryByUUIDParams) middleware.Responder {
 	err := &models.Error{
 		Code:    http.StatusNotImplemented,
 		Message: "Get Log Entry by UUID API not enabled in this Rekor instance",
@@ -580,7 +581,7 @@ func GetLogEntryByUUIDNotImplementedHandler(params entries.GetLogEntryByUUIDPara
 	return entries.NewGetLogEntryByUUIDDefault(http.StatusNotImplemented).WithPayload(err)
 }
 
-func SearchLogQueryNotImplementedHandler(params entries.SearchLogQueryParams) middleware.Responder {
+func SearchLogQueryNotImplementedHandler(_ entries.SearchLogQueryParams) middleware.Responder {
 	err := &models.Error{
 		Code:    http.StatusNotImplemented,
 		Message: "Search Log Query API not enabled in this Rekor instance",
diff --git a/pkg/api/index.go b/pkg/api/index.go
index 7286425..69f695a 100644
--- a/pkg/api/index.go
+++ b/pkg/api/index.go
@@ -89,7 +89,7 @@ func SearchIndexHandler(params index.SearchIndexParams) middleware.Responder {
 	return index.NewSearchIndexOK().WithPayload(result.Values())
 }
 
-func SearchIndexNotImplementedHandler(params index.SearchIndexParams) middleware.Responder {
+func SearchIndexNotImplementedHandler(_ index.SearchIndexParams) middleware.Responder {
 	err := models.Error{
 		Code:    http.StatusNotImplemented,
 		Message: "Search Index API not enabled in this Rekor instance",
diff --git a/pkg/api/public_key.go b/pkg/api/public_key.go
index e7e6b0f..b4ff916 100644
--- a/pkg/api/public_key.go
+++ b/pkg/api/public_key.go
@@ -36,7 +36,7 @@ func GetPublicKeyHandler(params pubkey.GetPublicKeyParams) middleware.Responder
 
 // handlers for APIs that may be disabled in a given instance
 
-func GetPublicKeyNotImplementedHandler(params pubkey.GetPublicKeyParams) middleware.Responder {
+func GetPublicKeyNotImplementedHandler(_ pubkey.GetPublicKeyParams) middleware.Responder {
 	err := &models.Error{
 		Code:    http.StatusNotImplemented,
 		Message: "Get Public Key API not enabled in this Rekor instance",
diff --git a/pkg/api/tlog.go b/pkg/api/tlog.go
index 4419a95..9310999 100644
--- a/pkg/api/tlog.go
+++ b/pkg/api/tlog.go
@@ -31,12 +31,13 @@ import (
 	"github.com/sigstore/rekor/pkg/generated/models"
 	"github.com/sigstore/rekor/pkg/generated/restapi/operations/tlog"
 	"github.com/sigstore/rekor/pkg/log"
+	"github.com/sigstore/rekor/pkg/trillianclient"
 	"github.com/sigstore/rekor/pkg/util"
 )
 
 // GetLogInfoHandler returns the current size of the tree and the STH
 func GetLogInfoHandler(params tlog.GetLogInfoParams) middleware.Responder {
-	tc := util.NewTrillianClient(params.HTTPRequest.Context(), api.logClient, api.logID)
+	tc := trillianclient.NewTrillianClient(params.HTTPRequest.Context(), api.logClient, api.logID)
 
 	// for each inactive shard, get the loginfo
 	var inactiveShards []*models.InactiveShardLogInfo
@@ -92,13 +93,13 @@ func GetLogProofHandler(params tlog.GetLogProofParams) middleware.Responder {
 	if *params.FirstSize > params.LastSize {
 		return handleRekorAPIError(params, http.StatusBadRequest, nil, fmt.Sprintf(firstSizeLessThanLastSize, *params.FirstSize, params.LastSize))
 	}
-	tc := util.NewTrillianClient(params.HTTPRequest.Context(), api.logClient, api.logID)
+	tc := trillianclient.NewTrillianClient(params.HTTPRequest.Context(), api.logClient, api.logID)
 	if treeID := swag.StringValue(params.TreeID); treeID != "" {
 		id, err := strconv.Atoi(treeID)
 		if err != nil {
 			log.Logger.Infof("Unable to convert %s to string, skipping initializing client with Tree ID: %v", treeID, err)
 		} else {
-			tc = util.NewTrillianClient(params.HTTPRequest.Context(), api.logClient, int64(id))
+			tc = trillianclient.NewTrillianClient(params.HTTPRequest.Context(), api.logClient, int64(id))
 		}
 	}
 
@@ -136,7 +137,7 @@ func GetLogProofHandler(params tlog.GetLogProofParams) middleware.Responder {
 }
 
 func inactiveShardLogInfo(ctx context.Context, tid int64) (*models.InactiveShardLogInfo, error) {
-	tc := util.NewTrillianClient(ctx, api.logClient, tid)
+	tc := trillianclient.NewTrillianClient(ctx, api.logClient, tid)
 	resp := tc.GetLatest(0)
 	if resp.Status != codes.OK {
 		return nil, fmt.Errorf("resp code is %d", resp.Status)
@@ -167,7 +168,7 @@ func inactiveShardLogInfo(ctx context.Context, tid int64) (*models.InactiveShard
 
 // handlers for APIs that may be disabled in a given instance
 
-func GetLogInfoNotImplementedHandler(params tlog.GetLogInfoParams) middleware.Responder {
+func GetLogInfoNotImplementedHandler(_ tlog.GetLogInfoParams) middleware.Responder {
 	err := &models.Error{
 		Code:    http.StatusNotImplemented,
 		Message: "Get Log Info API not enabled in this Rekor instance",
@@ -176,7 +177,7 @@ func GetLogInfoNotImplementedHandler(params tlog.GetLogInfoParams) middleware.Re
 	return tlog.NewGetLogInfoDefault(http.StatusNotImplemented).WithPayload(err)
 }
 
-func GetLogProofNotImplementedHandler(params tlog.GetLogProofParams) middleware.Responder {
+func GetLogProofNotImplementedHandler(_ tlog.GetLogProofParams) middleware.Responder {
 	err := &models.Error{
 		Code:    http.StatusNotImplemented,
 		Message: "Get Log Proof API not enabled in this Rekor instance",
diff --git a/pkg/fuzz/fuzz_utils.go b/pkg/fuzz/fuzz_utils.go
index 15f274c..feb38f0 100644
--- a/pkg/fuzz/fuzz_utils.go
+++ b/pkg/fuzz/fuzz_utils.go
@@ -139,7 +139,7 @@ func setArtifactFields(ff *fuzz.ConsumeFuzzer, props *types.ArtifactProperties)
 }
 
 // creates a file on disk and returns the url of it.
-func createAbsFile(ff *fuzz.ConsumeFuzzer, fileName string, fileContents []byte) (*url.URL, error) {
+func createAbsFile(_ *fuzz.ConsumeFuzzer, fileName string, fileContents []byte) (*url.URL, error) {
 	file, err := os.Create(fileName)
 	if err != nil {
 		return nil, err
diff --git a/pkg/generated/models/intoto_v002_schema.go b/pkg/generated/models/intoto_v002_schema.go
index 3297e5a..b630f15 100644
--- a/pkg/generated/models/intoto_v002_schema.go
+++ b/pkg/generated/models/intoto_v002_schema.go
@@ -450,7 +450,6 @@ type IntotoV002SchemaContentEnvelopeSignaturesItems0 struct {
 	Keyid string `json:"keyid,omitempty"`
 
 	// public key that corresponds to this signature
-	// Read Only: true
 	// Format: byte
 	PublicKey strfmt.Base64 `json:"publicKey,omitempty"`
 
@@ -464,26 +463,8 @@ func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) Validate(formats strfm
 	return nil
 }
 
-// ContextValidate validate this intoto v002 schema content envelope signatures items0 based on the context it is used
+// ContextValidate validates this intoto v002 schema content envelope signatures items0 based on context it is used
 func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
-	var res []error
-
-	if err := m.contextValidatePublicKey(ctx, formats); err != nil {
-		res = append(res, err)
-	}
-
-	if len(res) > 0 {
-		return errors.CompositeValidationError(res...)
-	}
-	return nil
-}
-
-func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) contextValidatePublicKey(ctx context.Context, formats strfmt.Registry) error {
-
-	if err := validate.ReadOnly(ctx, "publicKey", "body", strfmt.Base64(m.PublicKey)); err != nil {
-		return err
-	}
-
 	return nil
 }
 
diff --git a/pkg/generated/models/tuf_v001_schema.go b/pkg/generated/models/tuf_v001_schema.go
index f8bf4b0..db5d8a3 100644
--- a/pkg/generated/models/tuf_v001_schema.go
+++ b/pkg/generated/models/tuf_v001_schema.go
@@ -195,11 +195,30 @@ func (m *TUFV001Schema) UnmarshalBinary(b []byte) error {
 type TUFV001SchemaMetadata struct {
 
 	// Specifies the metadata inline within the document
-	Content interface{} `json:"content,omitempty"`
+	// Required: true
+	Content interface{} `json:"content"`
 }
 
 // Validate validates this TUF v001 schema metadata
 func (m *TUFV001SchemaMetadata) Validate(formats strfmt.Registry) error {
+	var res []error
+
+	if err := m.validateContent(formats); err != nil {
+		res = append(res, err)
+	}
+
+	if len(res) > 0 {
+		return errors.CompositeValidationError(res...)
+	}
+	return nil
+}
+
+func (m *TUFV001SchemaMetadata) validateContent(formats strfmt.Registry) error {
+
+	if m.Content == nil {
+		return errors.Required("metadata"+"."+"content", "body", nil)
+	}
+
 	return nil
 }
 
diff --git a/pkg/generated/restapi/configure_rekor_server.go b/pkg/generated/restapi/configure_rekor_server.go
index 2041f07..3f4bd5d 100644
--- a/pkg/generated/restapi/configure_rekor_server.go
+++ b/pkg/generated/restapi/configure_rekor_server.go
@@ -65,7 +65,7 @@ type apiToRecord struct {
 	path   *string // Path to record in metrics, if any.
 }
 
-func configureFlags(api *operations.RekorServerAPI) {
+func configureFlags(_ *operations.RekorServerAPI) {
 	// api.CommandLineOptionsGroups = []swag.CommandLineOptionsGroup{ ... }
 }
 
@@ -162,7 +162,7 @@ func configureAPI(api *operations.RekorServerAPI) http.Handler {
 }
 
 // The TLS configuration before HTTPS server starts.
-func configureTLS(tlsConfig *tls.Config) {
+func configureTLS(_ *tls.Config) {
 	// Make all necessary changes to the TLS configuration here.
 }
 
@@ -170,7 +170,7 @@ func configureTLS(tlsConfig *tls.Config) {
 // If you need to modify a config, store server instance to stop it individually later, this is the place.
 // This function can be called multiple times, depending on the number of serving schemes.
 // scheme value will be set accordingly: "http", "https" or "unix"
-func configureServer(s *http.Server, scheme, addr string) {
+func configureServer(_ *http.Server, _, _ string) {
 }
 
 // The middleware configuration is for the handler executors. These do not apply to the swagger.json document.
@@ -209,7 +209,7 @@ type zapLogEntry struct {
 	r *http.Request
 }
 
-func (z *zapLogEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{}) {
+func (z *zapLogEntry) Write(status, bytes int, _ http.Header, elapsed time.Duration, extra interface{}) {
 	var fields []interface{}
 
 	// follows https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry as a convention
diff --git a/pkg/generated/restapi/embedded_spec.go b/pkg/generated/restapi/embedded_spec.go
index 9466b1f..02b719b 100644
--- a/pkg/generated/restapi/embedded_spec.go
+++ b/pkg/generated/restapi/embedded_spec.go
@@ -2042,8 +2042,7 @@ func init() {
         "publicKey": {
           "description": "public key that corresponds to this signature",
           "type": "string",
-          "format": "byte",
-          "readOnly": true
+          "format": "byte"
         },
         "sig": {
           "description": "signature of the payload",
@@ -2665,7 +2664,7 @@ func init() {
       "description": "TUF metadata",
       "type": "object",
       "required": [
-        "metadata"
+        "content"
       ],
       "properties": {
         "content": {
@@ -3852,7 +3851,7 @@ func init() {
           "description": "TUF metadata",
           "type": "object",
           "required": [
-            "metadata"
+            "content"
           ],
           "properties": {
             "content": {
diff --git a/pkg/pki/minisign/minisign.go b/pkg/pki/minisign/minisign.go
index 928dfdb..0bcb02f 100644
--- a/pkg/pki/minisign/minisign.go
+++ b/pkg/pki/minisign/minisign.go
@@ -114,7 +114,7 @@ func (s Signature) Verify(r io.Reader, k interface{}, opts ...sigsig.VerifyOptio
 		r = bytes.NewReader(h.Sum(nil))
 	}
 
-	return verifier.VerifySignature(bytes.NewReader(s.signature.Signature[:]), r)
+	return verifier.VerifySignature(bytes.NewReader(s.signature.Signature[:]), r, opts...)
 }
 
 // PublicKey Public Key that follows the minisign standard; supports signify and minisign public keys
diff --git a/pkg/pki/pgp/pgp.go b/pkg/pki/pgp/pgp.go
index fce63ff..aee7fa1 100644
--- a/pkg/pki/pgp/pgp.go
+++ b/pkg/pki/pgp/pgp.go
@@ -134,7 +134,7 @@ func (s Signature) CanonicalValue() ([]byte, error) {
 }
 
 // Verify implements the pki.Signature interface
-func (s Signature) Verify(r io.Reader, k interface{}, opts ...sigsig.VerifyOption) error {
+func (s Signature) Verify(r io.Reader, k interface{}, _ ...sigsig.VerifyOption) error {
 	if len(s.signature) == 0 {
 		return fmt.Errorf("PGP signature has not been initialized")
 	}
diff --git a/pkg/pki/pkcs7/pkcs7.go b/pkg/pki/pkcs7/pkcs7.go
index 6fd5757..8694844 100644
--- a/pkg/pki/pkcs7/pkcs7.go
+++ b/pkg/pki/pkcs7/pkcs7.go
@@ -106,7 +106,7 @@ func (s Signature) CanonicalValue() ([]byte, error) {
 }
 
 // Verify implements the pki.Signature interface
-func (s Signature) Verify(r io.Reader, k interface{}, opts ...sigsig.VerifyOption) error {
+func (s Signature) Verify(r io.Reader, _ interface{}, _ ...sigsig.VerifyOption) error {
 	if len(*s.raw) == 0 {
 		return fmt.Errorf("PKCS7 signature has not been initialized")
 	}
diff --git a/pkg/pki/ssh/ssh.go b/pkg/pki/ssh/ssh.go
index a55a0ef..30f84ba 100644
--- a/pkg/pki/ssh/ssh.go
+++ b/pkg/pki/ssh/ssh.go
@@ -51,7 +51,7 @@ func (s Signature) CanonicalValue() ([]byte, error) {
 }
 
 // Verify implements the pki.Signature interface
-func (s Signature) Verify(r io.Reader, k interface{}, opts ...sigsig.VerifyOption) error {
+func (s Signature) Verify(r io.Reader, k interface{}, _ ...sigsig.VerifyOption) error {
 	if s.signature == nil {
 		return fmt.Errorf("ssh signature has not been initialized")
 	}
diff --git a/pkg/pki/tuf/tuf.go b/pkg/pki/tuf/tuf.go
index 0a0cf49..7da68e2 100644
--- a/pkg/pki/tuf/tuf.go
+++ b/pkg/pki/tuf/tuf.go
@@ -78,7 +78,7 @@ func (s Signature) CanonicalValue() ([]byte, error) {
 }
 
 // Verify implements the pki.Signature interface
-func (s Signature) Verify(_ io.Reader, k interface{}, opts ...sigsig.VerifyOption) error {
+func (s Signature) Verify(_ io.Reader, k interface{}, _ ...sigsig.VerifyOption) error {
 	key, ok := k.(*PublicKey)
 	if !ok {
 		return fmt.Errorf("invalid public key type for: %v", k)
diff --git a/pkg/util/trillian_client.go b/pkg/trillianclient/trillian_client.go
similarity index 99%
rename from pkg/util/trillian_client.go
rename to pkg/trillianclient/trillian_client.go
index e1d0d5d..facd6bd 100644
--- a/pkg/util/trillian_client.go
+++ b/pkg/trillianclient/trillian_client.go
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package util
+package trillianclient
 
 import (
 	"context"
diff --git a/pkg/types/alpine/v0.0.1/entry.go b/pkg/types/alpine/v0.0.1/entry.go
index 827dd76..98d31da 100644
--- a/pkg/types/alpine/v0.0.1/entry.go
+++ b/pkg/types/alpine/v0.0.1/entry.go
@@ -357,3 +357,19 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	}
 	return x509.NewPublicKey(bytes.NewReader(*v.AlpineModel.PublicKey.Content))
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.AlpineModel.Package == nil {
+		return false, fmt.Errorf("missing package entry")
+	}
+	if len(v.AlpineModel.Package.Content) == 0 {
+		return false, fmt.Errorf("missing package content")
+	}
+	if v.AlpineModel.PublicKey == nil {
+		return false, fmt.Errorf("missing public key")
+	}
+	if v.AlpineModel.PublicKey.Content == nil || len(*v.AlpineModel.PublicKey.Content) == 0 {
+		return false, fmt.Errorf("missing public key content")
+	}
+	return true, nil
+}
diff --git a/pkg/types/cose/v0.0.1/entry.go b/pkg/types/cose/v0.0.1/entry.go
index 5311026..b7c12a9 100644
--- a/pkg/types/cose/v0.0.1/entry.go
+++ b/pkg/types/cose/v0.0.1/entry.go
@@ -188,7 +188,7 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error {
 	return v.validate()
 }
 
-func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) {
+func (v *V001Entry) Canonicalize(_ context.Context) ([]byte, error) {
 	if v.keyObj == nil {
 		return nil, errors.New("cannot canonicalze empty key")
 	}
@@ -354,3 +354,26 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	}
 	return x509.NewPublicKey(bytes.NewReader(*v.CoseObj.PublicKey))
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if len(v.CoseObj.Message) == 0 {
+		return false, errors.New("missing COSE Sign1 message")
+	}
+	if v.CoseObj.PublicKey == nil || len(*v.CoseObj.PublicKey) == 0 {
+		return false, errors.New("missing public key")
+	}
+	if v.CoseObj.Data == nil {
+		return false, errors.New("missing COSE data property")
+	}
+	if len(v.envelopeHash) == 0 {
+		return false, errors.New("envelope hash has not been computed")
+	}
+	if v.keyObj == nil {
+		return false, errors.New("public key has not been parsed")
+	}
+	if v.sign1Msg == nil {
+		return false, errors.New("signature has not been validated")
+	}
+
+	return true, nil
+}
diff --git a/pkg/types/entries.go b/pkg/types/entries.go
index 760f0d8..9309b4c 100644
--- a/pkg/types/entries.go
+++ b/pkg/types/entries.go
@@ -38,6 +38,7 @@ type EntryImpl interface {
 	Unmarshal(e models.ProposedEntry) error           // unmarshal the abstract entry into the specific struct for this versioned type
 	CreateFromArtifactProperties(context.Context, ArtifactProperties) (models.ProposedEntry, error)
 	Verifier() (pki.PublicKey, error)
+	Insertable() (bool, error) // denotes whether the entry that was unmarshalled has the writeOnly fields required to validate and insert into the log
 }
 
 // EntryWithAttestationImpl specifies the behavior of a versioned type that also stores attestations
@@ -82,6 +83,12 @@ func CreateVersionedEntry(pe models.ProposedEntry) (EntryImpl, error) {
 		if !tf.(func() TypeImpl)().IsSupportedVersion(ei.APIVersion()) {
 			return nil, fmt.Errorf("entry kind '%v' does not support inserting entries of version '%v'", kind, ei.APIVersion())
 		}
+	} else {
+		return nil, fmt.Errorf("unknown kind '%v' specified", kind)
+	}
+
+	if ok, err := ei.Insertable(); !ok {
+		return nil, fmt.Errorf("entry not insertable into log: %w", err)
 	}
 
 	return ei, nil
diff --git a/pkg/types/hashedrekord/v0.0.1/entry.go b/pkg/types/hashedrekord/v0.0.1/entry.go
index a386d8a..82f54fe 100644
--- a/pkg/types/hashedrekord/v0.0.1/entry.go
+++ b/pkg/types/hashedrekord/v0.0.1/entry.go
@@ -104,7 +104,7 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error {
 	return err
 }
 
-func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) {
+func (v *V001Entry) Canonicalize(_ context.Context) ([]byte, error) {
 	sigObj, keyObj, err := v.validate()
 	if err != nil {
 		return nil, types.ValidationError(err)
@@ -189,7 +189,7 @@ func (v *V001Entry) validate() (pki.Signature, pki.PublicKey, error) {
 	return sigObj, keyObj, nil
 }
 
-func (v V001Entry) CreateFromArtifactProperties(ctx context.Context, props types.ArtifactProperties) (models.ProposedEntry, error) {
+func (v V001Entry) CreateFromArtifactProperties(_ context.Context, props types.ArtifactProperties) (models.ProposedEntry, error) {
 	returnVal := models.Hashedrekord{}
 	re := V001Entry{}
 
@@ -252,3 +252,31 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	}
 	return x509.NewPublicKey(bytes.NewReader(v.HashedRekordObj.Signature.PublicKey.Content))
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.HashedRekordObj.Signature == nil {
+		return false, errors.New("missing signature property")
+	}
+	if len(v.HashedRekordObj.Signature.Content) == 0 {
+		return false, errors.New("missing signature content")
+	}
+	if v.HashedRekordObj.Signature.PublicKey == nil {
+		return false, errors.New("missing publicKey property")
+	}
+	if len(v.HashedRekordObj.Signature.PublicKey.Content) == 0 {
+		return false, errors.New("missing publicKey content")
+	}
+	if v.HashedRekordObj.Data == nil {
+		return false, errors.New("missing data property")
+	}
+	if v.HashedRekordObj.Data.Hash == nil {
+		return false, errors.New("missing hash property")
+	}
+	if v.HashedRekordObj.Data.Hash.Algorithm == nil {
+		return false, errors.New("missing hash algorithm")
+	}
+	if v.HashedRekordObj.Data.Hash.Value == nil {
+		return false, errors.New("missing hash value")
+	}
+	return true, nil
+}
diff --git a/pkg/types/helm/v0.0.1/entry.go b/pkg/types/helm/v0.0.1/entry.go
index e76e752..dfb05c2 100644
--- a/pkg/types/helm/v0.0.1/entry.go
+++ b/pkg/types/helm/v0.0.1/entry.go
@@ -355,3 +355,23 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	}
 	return pgp.NewPublicKey(bytes.NewReader(*v.HelmObj.PublicKey.Content))
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.HelmObj.PublicKey == nil {
+		return false, errors.New("missing public key property")
+	}
+	if v.HelmObj.PublicKey.Content == nil || len(*v.HelmObj.PublicKey.Content) == 0 {
+		return false, errors.New("missing public key content")
+	}
+
+	if v.HelmObj.Chart == nil {
+		return false, errors.New("missing chart property")
+	}
+	if v.HelmObj.Chart.Provenance == nil {
+		return false, errors.New("missing provenance property")
+	}
+	if len(v.HelmObj.Chart.Provenance.Content) == 0 {
+		return false, errors.New("missing provenance content")
+	}
+	return true, nil
+}
diff --git a/pkg/types/intoto/v0.0.1/entry.go b/pkg/types/intoto/v0.0.1/entry.go
index 8b84dec..66af807 100644
--- a/pkg/types/intoto/v0.0.1/entry.go
+++ b/pkg/types/intoto/v0.0.1/entry.go
@@ -183,7 +183,7 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error {
 	return v.validate()
 }
 
-func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) {
+func (v *V001Entry) Canonicalize(_ context.Context) ([]byte, error) {
 	if v.keyObj == nil {
 		return nil, errors.New("cannot canonicalize empty key")
 	}
@@ -356,3 +356,24 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	}
 	return x509.NewPublicKey(bytes.NewReader(*v.IntotoObj.PublicKey))
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.IntotoObj.Content == nil {
+		return false, errors.New("missing content property")
+	}
+	if len(v.IntotoObj.Content.Envelope) == 0 {
+		return false, errors.New("missing envelope content")
+	}
+
+	if v.IntotoObj.PublicKey == nil || len(*v.IntotoObj.PublicKey) == 0 {
+		return false, errors.New("missing publicKey content")
+	}
+
+	if v.keyObj == nil {
+		return false, errors.New("failed to parse public key")
+	}
+	if v.env.Payload == "" || v.env.PayloadType == "" || len(v.env.Signatures) == 0 {
+		return false, errors.New("invalid DSSE envelope")
+	}
+	return true, nil
+}
diff --git a/pkg/types/intoto/v0.0.2/entry.go b/pkg/types/intoto/v0.0.2/entry.go
index 083e937..513812d 100644
--- a/pkg/types/intoto/v0.0.2/entry.go
+++ b/pkg/types/intoto/v0.0.2/entry.go
@@ -211,7 +211,7 @@ func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error {
 	return nil
 }
 
-func (v *V002Entry) Canonicalize(ctx context.Context) ([]byte, error) {
+func (v *V002Entry) Canonicalize(_ context.Context) ([]byte, error) {
 	if err := v.IntotoObj.Validate(strfmt.Default); err != nil {
 		return nil, err
 	}
@@ -460,3 +460,37 @@ func (v V002Entry) Verifier() (pki.PublicKey, error) {
 
 	return x509.NewPublicKey(bytes.NewReader(v.IntotoObj.Content.Envelope.Signatures[0].PublicKey))
 }
+
+func (v V002Entry) Insertable() (bool, error) {
+	if v.IntotoObj.Content == nil {
+		return false, errors.New("missing content property")
+	}
+	if v.IntotoObj.Content.Envelope == nil {
+		return false, errors.New("missing envelope property")
+	}
+	if len(v.IntotoObj.Content.Envelope.Payload) == 0 {
+		return false, errors.New("missing envelope content")
+	}
+
+	if v.IntotoObj.Content.Envelope.PayloadType == nil || len(*v.IntotoObj.Content.Envelope.PayloadType) == 0 {
+		return false, errors.New("missing payloadType content")
+	}
+
+	if len(v.IntotoObj.Content.Envelope.Signatures) == 0 {
+		return false, errors.New("missing signatures content")
+	}
+	for _, sig := range v.IntotoObj.Content.Envelope.Signatures {
+		if len(sig.Sig) == 0 {
+			return false, errors.New("missing signature content")
+		}
+		if len(sig.PublicKey) == 0 {
+			return false, errors.New("missing publicKey content")
+		}
+	}
+
+	if v.env.Payload == "" || v.env.PayloadType == "" || len(v.env.Signatures) == 0 {
+		return false, errors.New("invalid DSSE envelope")
+	}
+
+	return true, nil
+}
diff --git a/pkg/types/intoto/v0.0.2/intoto_v0_0_2_schema.json b/pkg/types/intoto/v0.0.2/intoto_v0_0_2_schema.json
index f614ccf..9153b0a 100644
--- a/pkg/types/intoto/v0.0.2/intoto_v0_0_2_schema.json
+++ b/pkg/types/intoto/v0.0.2/intoto_v0_0_2_schema.json
@@ -42,8 +42,7 @@
                                     "publicKey": {
                                         "description": "public key that corresponds to this signature",
                                         "type": "string",
-                                        "format": "byte",
-                                        "readOnly": true
+                                        "format": "byte"
                                     }
                                 }
                             }
diff --git a/pkg/types/jar/v0.0.1/entry.go b/pkg/types/jar/v0.0.1/entry.go
index ab85ccd..60faa25 100644
--- a/pkg/types/jar/v0.0.1/entry.go
+++ b/pkg/types/jar/v0.0.1/entry.go
@@ -110,7 +110,7 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error {
 	return v.validate()
 }
 
-func (v *V001Entry) fetchExternalEntities(ctx context.Context) (*pkcs7.PublicKey, *pkcs7.Signature, error) {
+func (v *V001Entry) fetchExternalEntities(_ context.Context) (*pkcs7.PublicKey, *pkcs7.Signature, error) {
 	if err := v.validate(); err != nil {
 		return nil, nil, types.ValidationError(err)
 	}
@@ -344,3 +344,14 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	}
 	return x509.NewPublicKey(bytes.NewReader(*v.JARModel.Signature.PublicKey.Content))
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.JARModel.Archive == nil {
+		return false, errors.New("missing archive property")
+	}
+	if len(v.JARModel.Archive.Content) == 0 {
+		return false, errors.New("missing archive content")
+	}
+
+	return true, nil
+}
diff --git a/pkg/types/rekord/v0.0.1/entry.go b/pkg/types/rekord/v0.0.1/entry.go
index b2853c8..dd124e1 100644
--- a/pkg/types/rekord/v0.0.1/entry.go
+++ b/pkg/types/rekord/v0.0.1/entry.go
@@ -443,3 +443,30 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 		return nil, fmt.Errorf("unexpected format of public key: %s", f)
 	}
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.RekordObj.Signature == nil {
+		return false, errors.New("missing signature property")
+	}
+	if v.RekordObj.Signature.Content == nil || len(*v.RekordObj.Signature.Content) == 0 {
+		return false, errors.New("missing signature content")
+	}
+	if v.RekordObj.Signature.PublicKey == nil {
+		return false, errors.New("missing publicKey property")
+	}
+	if v.RekordObj.Signature.PublicKey.Content == nil || len(*v.RekordObj.Signature.PublicKey.Content) == 0 {
+		return false, errors.New("missing publicKey content")
+	}
+	if v.RekordObj.Signature.Format == nil || len(*v.RekordObj.Signature.Format) == 0 {
+		return false, errors.New("missing signature format")
+	}
+
+	if v.RekordObj.Data == nil {
+		return false, errors.New("missing data property")
+	}
+	if len(v.RekordObj.Data.Content) == 0 {
+		return false, errors.New("missing data content")
+	}
+
+	return true, nil
+}
diff --git a/pkg/types/rfc3161/v0.0.1/entry.go b/pkg/types/rfc3161/v0.0.1/entry.go
index eed8bfa..35a21e0 100644
--- a/pkg/types/rfc3161/v0.0.1/entry.go
+++ b/pkg/types/rfc3161/v0.0.1/entry.go
@@ -118,7 +118,7 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error {
 	return nil
 }
 
-func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) {
+func (v *V001Entry) Canonicalize(_ context.Context) ([]byte, error) {
 	if v.tsrContent == nil {
 		return nil, errors.New("tsr content must be set before canonicalizing")
 	}
@@ -210,3 +210,19 @@ func (v V001Entry) CreateFromArtifactProperties(_ context.Context, props types.A
 func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	return nil, errors.New("Verifier() does not support rfc3161 entry type")
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.Rfc3161Obj.Tsr == nil {
+		return false, errors.New("missing tsr property")
+	}
+
+	if v.Rfc3161Obj.Tsr.Content == nil || len(*v.Rfc3161Obj.Tsr.Content) == 0 {
+		return false, errors.New("missing tsr content")
+	}
+
+	if v.tsrContent == nil || len(*v.tsrContent) == 0 {
+		return false, errors.New("timestamp response has not been parsed")
+	}
+
+	return true, nil
+}
diff --git a/pkg/types/rpm/v0.0.1/entry.go b/pkg/types/rpm/v0.0.1/entry.go
index 79e5e3a..a10b60c 100644
--- a/pkg/types/rpm/v0.0.1/entry.go
+++ b/pkg/types/rpm/v0.0.1/entry.go
@@ -377,3 +377,20 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	}
 	return pgp.NewPublicKey(bytes.NewReader(*v.RPMModel.PublicKey.Content))
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.RPMModel.PublicKey == nil {
+		return false, errors.New("missing publicKey property")
+	}
+	if v.RPMModel.PublicKey.Content == nil || len(*v.RPMModel.PublicKey.Content) == 0 {
+		return false, errors.New("missing publicKey content")
+	}
+
+	if v.RPMModel.Package == nil {
+		return false, errors.New("missing package property")
+	}
+	if len(v.RPMModel.Package.Content) == 0 {
+		return false, errors.New("missing package content")
+	}
+	return true, nil
+}
diff --git a/pkg/types/tuf/v0.0.1/entry.go b/pkg/types/tuf/v0.0.1/entry.go
index 7e4e5f9..ec471c9 100644
--- a/pkg/types/tuf/v0.0.1/entry.go
+++ b/pkg/types/tuf/v0.0.1/entry.go
@@ -379,3 +379,20 @@ func (v V001Entry) Verifier() (pki.PublicKey, error) {
 	}
 	return ptuf.NewPublicKey(bytes.NewReader(keyBytes))
 }
+
+func (v V001Entry) Insertable() (bool, error) {
+	if v.TufObj.Metadata == nil {
+		return false, errors.New("missing metadata property")
+	}
+	if v.TufObj.Metadata.Content == nil {
+		return false, errors.New("missing metadata content")
+	}
+
+	if v.TufObj.Root == nil {
+		return false, errors.New("missing root property")
+	}
+	if v.TufObj.Root.Content == nil {
+		return false, errors.New("missing root content")
+	}
+	return true, nil
+}
diff --git a/pkg/types/tuf/v0.0.1/tuf_v0_0_1_schema.json b/pkg/types/tuf/v0.0.1/tuf_v0_0_1_schema.json
index f1a6cd3..5d2dc21 100644
--- a/pkg/types/tuf/v0.0.1/tuf_v0_0_1_schema.json
+++ b/pkg/types/tuf/v0.0.1/tuf_v0_0_1_schema.json
@@ -20,7 +20,7 @@
                     "additionalProperties": true
                 }
             },
-            "required": [ "metadata" ]
+            "required": [ "content" ]
         },
         "root" : {
             "description": "root metadata containing about the public keys used to sign the manifest",
diff --git a/pkg/util/pubkey.go b/pkg/util/pubkey.go
deleted file mode 100644
index 06c49ca..0000000
--- a/pkg/util/pubkey.go
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Copyright 2021 The Sigstore Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package util
-
-import (
-	"context"
-	"crypto/ecdsa"
-	"errors"
-
-	"github.com/sigstore/rekor/pkg/generated/client"
-	"github.com/sigstore/rekor/pkg/generated/client/pubkey"
-	"github.com/sigstore/sigstore/pkg/cryptoutils"
-)
-
-func PublicKey(ctx context.Context, c *client.Rekor) (*ecdsa.PublicKey, error) {
-	resp, err := c.Pubkey.GetPublicKey(&pubkey.GetPublicKeyParams{Context: ctx})
-	if err != nil {
-		return nil, err
-	}
-
-	// marshal the pubkey
-	pubKey, err := cryptoutils.UnmarshalPEMToPublicKey([]byte(resp.GetPayload()))
-	if err != nil {
-		return nil, err
-	}
-	ed, ok := pubKey.(*ecdsa.PublicKey)
-	if !ok {
-		return nil, errors.New("public key retrieved from Rekor is not an ECDSA key")
-	}
-	return ed, nil
-}
diff --git a/pkg/util/timestamp_note.go b/pkg/util/timestamp_note.go
deleted file mode 100644
index d2f44c2..0000000
--- a/pkg/util/timestamp_note.go
+++ /dev/null
@@ -1,171 +0,0 @@
-//
-// Copyright 2021 The Sigstore Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package util
-
-import (
-	"bytes"
-	"encoding/base64"
-	"errors"
-	"fmt"
-	"net/url"
-	"strconv"
-	"strings"
-	"time"
-)
-
-// Signed note based timestamp responses
-
-type TimestampNote struct {
-	// Origin is the unique identifier/version string
-	Origin string
-	// MessageImprint is the hash of the message to timestamp, of the form sha256:<sha>
-	MessageImprint string
-	// Nonce is a short random  bytes to prove response freshness
-	Nonce []byte
-	// Time is the timestamp to imprint on the message
-	Time time.Time
-	// Radius is the time in microseconds used to indicate certainty
-	Radius int64
-	// CertChainRef is a reference URL to the valid timestamping cert chain used to sign the response
-	CertChainRef *url.URL
-	// OtherContent is any additional data to be included in the signed payload; each element is assumed to be one line
-	OtherContent []string
-}
-
-// String returns the String representation of the TimestampNote
-func (t TimestampNote) String() string {
-	var b strings.Builder
-	time, _ := t.Time.MarshalText()
-	fmt.Fprintf(&b, "%s\n%s\n%s\n%s\n%d\n%s\n", t.Origin, t.MessageImprint, base64.StdEncoding.EncodeToString(t.Nonce),
-		time, t.Radius, t.CertChainRef)
-	for _, line := range t.OtherContent {
-		fmt.Fprintf(&b, "%s\n", line)
-	}
-	return b.String()
-}
-
-// MarshalText returns the common format representation of this TimestampNote.
-func (t TimestampNote) MarshalText() ([]byte, error) {
-	return []byte(t.String()), nil
-}
-
-// UnmarshalText parses the common formatted timestamp note data and stores the result
-// in the TimestampNote.
-//
-// The supplied data is expected to begin with the following 6 lines of text,
-// each followed by a newline:
-// <ecosystem/version string>
-// <message hash of the format sha256:$SHA>
-// <base64 representation of the nonce>
-// <RFC 3339 representation of the time>
-// <decimal representation of radius>
-// <cert chain URI>
-// <optional non-empty line of other content>...
-// <optional non-empty line of other content>...
-//
-// This will discard any content found after the checkpoint (including signatures)
-func (t *TimestampNote) UnmarshalText(data []byte) error {
-	l := bytes.Split(data, []byte("\n"))
-	if len(l) < 7 {
-		return errors.New("invalid timestamp note - too few newlines")
-	}
-	origin := string(l[0])
-	if len(origin) == 0 {
-		return errors.New("invalid timestamp note - empty ecosystem")
-	}
-	h := string(l[1])
-	if err := ValidateSHA256Value(h); err != nil {
-		return fmt.Errorf("invalid timestamp note - invalid message hash: %w", err)
-	}
-
-	nonce, err := base64.StdEncoding.DecodeString(string(l[2]))
-	if err != nil {
-		return fmt.Errorf("invalid timestamp note - invalid nonce: %w", err)
-	}
-	var timestamp time.Time
-	if err := timestamp.UnmarshalText(l[3]); err != nil {
-		return fmt.Errorf("invalid timestamp note - invalid time: %w", err)
-	}
-	r, err := strconv.ParseInt(string(l[4]), 10, 64)
-	if err != nil {
-		return fmt.Errorf("invalid timestamp note - invalid radius: %w", err)
-	}
-	u, err := url.Parse(string(l[5]))
-	if err != nil {
-		return fmt.Errorf("invalid timestamp note - invalid URI: %w", err)
-
-	}
-	*t = TimestampNote{
-		Origin:         origin,
-		MessageImprint: h,
-		Nonce:          nonce,
-		Time:           timestamp,
-		Radius:         r,
-		CertChainRef:   u,
-	}
-	if len(l) >= 8 {
-		for _, line := range l[6:] {
-			if len(line) == 0 {
-				break
-			}
-			t.OtherContent = append(t.OtherContent, string(line))
-		}
-	}
-	return nil
-}
-
-type SignedTimestampNote struct {
-	TimestampNote
-	SignedNote
-}
-
-func CreateSignedTimestampNote(t TimestampNote) (*SignedTimestampNote, error) {
-	text, err := t.MarshalText()
-	if err != nil {
-		return nil, err
-	}
-	return &SignedTimestampNote{
-		TimestampNote: t,
-		SignedNote:    SignedNote{Note: string(text)},
-	}, nil
-}
-
-func SignedTimestampNoteValidator(strToValidate string) bool {
-	s := SignedNote{}
-	if err := s.UnmarshalText([]byte(strToValidate)); err != nil {
-		return false
-	}
-	c := &TimestampNote{}
-	return c.UnmarshalText([]byte(s.Note)) == nil
-}
-
-func TimestampNoteValidator(strToValidate string) bool {
-	c := &TimestampNote{}
-	return c.UnmarshalText([]byte(strToValidate)) == nil
-}
-
-func (r *SignedTimestampNote) UnmarshalText(data []byte) error {
-	s := SignedNote{}
-	if err := s.UnmarshalText([]byte(data)); err != nil {
-		return fmt.Errorf("unmarshalling signed note: %w", err)
-	}
-	t := TimestampNote{}
-	if err := t.UnmarshalText([]byte(s.Note)); err != nil {
-		return fmt.Errorf("unmarshalling timestamp note: %w", err)
-	}
-	*r = SignedTimestampNote{TimestampNote: t, SignedNote: s}
-	return nil
-}
diff --git a/pkg/util/util.go b/pkg/util/util.go
index fa0e823..78c1a0f 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -32,8 +32,6 @@ import (
 	"time"
 
 	"golang.org/x/crypto/openpgp"
-
-	"github.com/sigstore/rekor/pkg/generated/models"
 )
 
 var (
@@ -377,19 +375,6 @@ func CreateArtifact(t *testing.T, artifactPath string) string {
 	return artifact
 }
 
-func extractLogEntry(t *testing.T, le models.LogEntry) models.LogEntryAnon {
-	t.Helper()
-
-	if len(le) != 1 {
-		t.Fatal("expected length to be 1, is actually", len(le))
-	}
-	for _, v := range le {
-		return v
-	}
-	// this should never happen
-	return models.LogEntryAnon{}
-}
-
 func write(t *testing.T, data string, path string) {
 	t.Helper()
 	if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil {


Test patch:
diff --git a/pkg/util/validate_test.go b/cmd/rekor-cli/app/validate_test.go
similarity index 96%
rename from pkg/util/validate_test.go
rename to cmd/rekor-cli/app/validate_test.go
index efe34cc..6332515 100644
--- a/pkg/util/validate_test.go
+++ b/cmd/rekor-cli/app/validate_test.go
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package util
+package app
 
 import (
 	"testing"
@@ -54,7 +54,7 @@ func TestSHA1(t *testing.T) {
 	}
 
 	for _, tr := range tests {
-		err := ValidateSHA1Value(tr.value)
+		err := validateSHA1Value(tr.value)
 		if tr.expectFail == (err == nil) {
 			t.Errorf("Failure validating '%s': %s", tr.value, err)
 		}
@@ -96,7 +96,7 @@ func TestSHA256(t *testing.T) {
 	}
 
 	for _, tr := range tests {
-		err := ValidateSHA256Value(tr.value)
+		err := validateSHA256Value(tr.value)
 		if tr.expectFail == (err == nil) {
 			t.Errorf("Failure validating '%s': %s", tr.value, err)
 		}
@@ -138,7 +138,7 @@ func TestSHA512(t *testing.T) {
 	}
 
 	for _, tr := range tests {
-		err := ValidateSHA512Value(tr.value)
+		err := validateSHA512Value(tr.value)
 		if tr.expectFail == (err == nil) {
 			t.Errorf("Failure validating '%s': %s", tr.value, err)
 		}
diff --git a/cmd/rekor-cli/main_test.go b/cmd/rekor-cli/main_test.go
index 6a11ccb..fd89027 100644
--- a/cmd/rekor-cli/main_test.go
+++ b/cmd/rekor-cli/main_test.go
@@ -21,6 +21,6 @@ import (
 	"github.com/sigstore/rekor/cmd/rekor-cli/app"
 )
 
-func TestCover(t *testing.T) {
+func TestCover(_ *testing.T) {
 	app.Execute()
 }
diff --git a/cmd/rekor-server/main_test.go b/cmd/rekor-server/main_test.go
index 8fa9c4e..5c151b8 100644
--- a/cmd/rekor-server/main_test.go
+++ b/cmd/rekor-server/main_test.go
@@ -21,6 +21,6 @@ import (
 	"github.com/sigstore/rekor/cmd/rekor-server/app"
 )
 
-func TestCover(t *testing.T) {
+func TestCover(_ *testing.T) {
 	app.Execute()
 }
diff --git a/pkg/pki/minisign/minisign_test.go b/pkg/pki/minisign/minisign_test.go
index 4487b47..c91db02 100644
--- a/pkg/pki/minisign/minisign_test.go
+++ b/pkg/pki/minisign/minisign_test.go
@@ -122,7 +122,7 @@ func TestReadSignature(t *testing.T) {
 type BadReader struct {
 }
 
-func (br BadReader) Read(p []byte) (n int, err error) {
+func (br BadReader) Read(_ []byte) (n int, err error) {
 	return 0, errors.New("test error")
 }
 
diff --git a/pkg/pki/pgp/pgp_test.go b/pkg/pki/pgp/pgp_test.go
index 60ed66c..20362f7 100644
--- a/pkg/pki/pgp/pgp_test.go
+++ b/pkg/pki/pgp/pgp_test.go
@@ -94,7 +94,7 @@ func TestReadSignature(t *testing.T) {
 type BadReader struct {
 }
 
-func (br BadReader) Read(p []byte) (n int, err error) {
+func (br BadReader) Read(_ []byte) (n int, err error) {
 	return 0, errors.New("test error")
 }
 
diff --git a/pkg/types/alpine/alpine_test.go b/pkg/types/alpine/alpine_test.go
index 3d0e10e..a961968 100644
--- a/pkg/types/alpine/alpine_test.go
+++ b/pkg/types/alpine/alpine_test.go
@@ -39,7 +39,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
@@ -47,6 +47,10 @@ func (u UnmarshalFailsTester) Verifier() (pki.PublicKey, error) {
 	return nil, nil
 }
 
+func (u UnmarshalFailsTester) Insertable() (bool, error) {
+	return false, nil
+}
+
 func TestAlpineType(t *testing.T) {
 	// empty to start
 	if VersionMap.Count() != 0 {
diff --git a/pkg/types/alpine/v0.0.1/entry_test.go b/pkg/types/alpine/v0.0.1/entry_test.go
index abd6a25..f6c6cc8 100644
--- a/pkg/types/alpine/v0.0.1/entry_test.go
+++ b/pkg/types/alpine/v0.0.1/entry_test.go
@@ -151,6 +151,12 @@ func TestCrossFieldValidation(t *testing.T) {
 			t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
 		}
 
+		if tc.expectUnmarshalSuccess {
+			if ok, err := v.Insertable(); !ok || err != nil {
+				t.Errorf("unexpected result in calling Insertable on valid proposed entry: %v", err)
+			}
+		}
+
 		b, err := v.Canonicalize(context.TODO())
 		if (err == nil) != tc.expectCanonicalizeSuccess {
 			t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
@@ -164,9 +170,13 @@ func TestCrossFieldValidation(t *testing.T) {
 			if err != nil {
 				t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
 			}
-			if _, err := types.UnmarshalEntry(pe); err != nil {
+			ei, err := types.UnmarshalEntry(pe)
+			if err != nil {
 				t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
 			}
+			if ok, err := ei.Insertable(); ok || err == nil {
+				t.Errorf("unexpected success calling Insertable on entry created from canonicalized content")
+			}
 		}
 
 		verifier, err := v.Verifier()
@@ -187,3 +197,114 @@ func TestCrossFieldValidation(t *testing.T) {
 		}
 	}
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	pub := strfmt.Base64([]byte("pub"))
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				AlpineModel: models.AlpineV001Schema{
+					Package: &models.AlpineV001SchemaPackage{
+						Content: strfmt.Base64("package"),
+					},
+					PublicKey: &models.AlpineV001SchemaPublicKey{
+						Content: &pub,
+					},
+				},
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing key content",
+			entry: V001Entry{
+				AlpineModel: models.AlpineV001Schema{
+					Package: &models.AlpineV001SchemaPackage{
+						Content: strfmt.Base64("package"),
+					},
+					PublicKey: &models.AlpineV001SchemaPublicKey{
+						//Content: &pub,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing public key",
+			entry: V001Entry{
+				AlpineModel: models.AlpineV001Schema{
+					Package: &models.AlpineV001SchemaPackage{
+						Content: strfmt.Base64("package"),
+					},
+					/*
+						PublicKey: &models.AlpineV001SchemaPublicKey{
+							Content: &pub,
+						},
+					*/
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing package content",
+			entry: V001Entry{
+				AlpineModel: models.AlpineV001Schema{
+					Package: &models.AlpineV001SchemaPackage{
+						//Content: strfmt.Base64("package"),
+					},
+					PublicKey: &models.AlpineV001SchemaPublicKey{
+						Content: &pub,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing package",
+			entry: V001Entry{
+				AlpineModel: models.AlpineV001Schema{
+					/*
+						Package: &models.AlpineV001SchemaPackage{
+							Content: strfmt.Base64("package"),
+						},
+					*/
+					PublicKey: &models.AlpineV001SchemaPublicKey{
+						Content: &pub,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "empty model",
+			entry: V001Entry{
+				AlpineModel: models.AlpineV001Schema{
+					/*
+						Package: &models.AlpineV001SchemaPackage{
+							Content: strfmt.Base64("package"),
+						},
+						PublicKey: &models.AlpineV001SchemaPublicKey{
+							Content: &pub,
+						},
+					*/
+				},
+			},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/cose/cose_test.go b/pkg/types/cose/cose_test.go
index 2a0cfb1..080253a 100644
--- a/pkg/types/cose/cose_test.go
+++ b/pkg/types/cose/cose_test.go
@@ -40,7 +40,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
@@ -48,6 +48,10 @@ func (u UnmarshalFailsTester) Verifier() (pki.PublicKey, error) {
 	return nil, nil
 }
 
+func (u UnmarshalFailsTester) Insertable() (bool, error) {
+	return false, nil
+}
+
 func TestCOSEType(t *testing.T) {
 	// empty to start
 	if VersionMap.Count() != 0 {
diff --git a/pkg/types/cose/v0.0.1/entry_test.go b/pkg/types/cose/v0.0.1/entry_test.go
index 582e423..34af5cf 100644
--- a/pkg/types/cose/v0.0.1/entry_test.go
+++ b/pkg/types/cose/v0.0.1/entry_test.go
@@ -17,6 +17,7 @@ package cose
 
 import (
 	"bytes"
+	"context"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
@@ -30,6 +31,7 @@ import (
 	"reflect"
 	"testing"
 
+	"github.com/go-openapi/runtime"
 	"github.com/go-openapi/strfmt"
 	"github.com/sigstore/rekor/pkg/generated/models"
 	sigx509 "github.com/sigstore/rekor/pkg/pki/x509"
@@ -270,12 +272,39 @@ func TestV001Entry_Unmarshal(t *testing.T) {
 				t.Errorf("V001Entry.Unmarshal() error = %v, wantErr %v", err, tt.wantErr)
 			}
 
+			if !tt.wantErr {
+				if ok, err := v.Insertable(); !ok || err != nil {
+					t.Errorf("unexpected error calling Insertable on valid proposed entry: %v", err)
+				}
+			}
+
 			verifier, err := v.Verifier()
 			if !tt.wantVerifierErr {
 				if err != nil {
 					s, _ := verifier.CanonicalValue()
 					t.Errorf("%v: unexpected error for %v, got %v", tt.name, string(s), err)
 				}
+
+				if !tt.wantErr {
+					b, err := v.Canonicalize(context.Background())
+					if err != nil {
+						t.Errorf("unexpected error canonicalizing %v", tt.name)
+					}
+					if len(b) != 0 {
+						pe, err := models.UnmarshalProposedEntry(bytes.NewReader(b), runtime.JSONConsumer())
+						if err != nil {
+							t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tt.name, err)
+						}
+						ei, err := types.UnmarshalEntry(pe)
+						if err != nil {
+							t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tt.name, err)
+						}
+						if ok, err := ei.Insertable(); ok || err == nil {
+							t.Errorf("entry created from canonicalized entry should not also be insertable")
+						}
+					}
+				}
+
 				pubV, _ := verifier.CanonicalValue()
 				if !reflect.DeepEqual(pubV, pub) && !reflect.DeepEqual(pubV, pemBytes) {
 					t.Errorf("verifier and public keys do not match: %v, %v", string(pubV), string(pub))
@@ -690,3 +719,202 @@ func mustContain(t *testing.T, want string, l []string) {
 	}
 	t.Fatalf("list %v does not contain %s", l, want)
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatal(err)
+	}
+	der, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
+	if err != nil {
+		t.Fatal(err)
+	}
+	pub := pem.EncodeToMemory(&pem.Block{
+		Bytes: der,
+		Type:  "PUBLIC KEY",
+	})
+	keyObj, err := sigx509.NewPublicKey(bytes.NewReader(pub))
+	if err != nil {
+		t.Fatal(err)
+	}
+	pubKey := strfmt.Base64(pub)
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				CoseObj: models.CoseV001Schema{
+					Data: &models.CoseV001SchemaData{
+						Aad: strfmt.Base64([]byte("aad")),
+					},
+					Message:   strfmt.Base64([]byte("message")),
+					PublicKey: &pubKey,
+				},
+				keyObj:       keyObj,
+				sign1Msg:     &gocose.Sign1Message{},
+				envelopeHash: []byte("hash"),
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "no aad",
+			entry: V001Entry{
+				CoseObj: models.CoseV001Schema{
+					Data:      &models.CoseV001SchemaData{},
+					Message:   strfmt.Base64([]byte("message")),
+					PublicKey: &pubKey,
+				},
+				keyObj:       keyObj,
+				sign1Msg:     &gocose.Sign1Message{},
+				envelopeHash: []byte("hash"),
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing hash",
+			entry: V001Entry{
+				CoseObj: models.CoseV001Schema{
+					Data:      &models.CoseV001SchemaData{},
+					Message:   strfmt.Base64([]byte("message")),
+					PublicKey: &pubKey,
+				},
+				keyObj:   keyObj,
+				sign1Msg: &gocose.Sign1Message{},
+				//envelopeHash: []byte("hash"),
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "unparsed message",
+			entry: V001Entry{
+				CoseObj: models.CoseV001Schema{
+					Data: &models.CoseV001SchemaData{
+						Aad: strfmt.Base64([]byte("aad")),
+					},
+					Message:   strfmt.Base64([]byte("message")),
+					PublicKey: &pubKey,
+				},
+				keyObj: keyObj,
+				//sign1Msg:     &gocose.Sign1Message{},
+				envelopeHash: []byte("hash"),
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "unparsed public key",
+			entry: V001Entry{
+				CoseObj: models.CoseV001Schema{
+					Data: &models.CoseV001SchemaData{
+						Aad: strfmt.Base64([]byte("aad")),
+					},
+					Message:   strfmt.Base64([]byte("message")),
+					PublicKey: &pubKey,
+				},
+				//keyObj:       keyObj,
+				sign1Msg:     &gocose.Sign1Message{},
+				envelopeHash: []byte("hash"),
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing public key",
+			entry: V001Entry{
+				CoseObj: models.CoseV001Schema{
+					Data: &models.CoseV001SchemaData{
+						Aad: strfmt.Base64([]byte("aad")),
+					},
+					Message: strfmt.Base64([]byte("message")),
+					//PublicKey: &pubKey,
+				},
+				keyObj:       keyObj,
+				sign1Msg:     &gocose.Sign1Message{},
+				envelopeHash: []byte("hash"),
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing unparsed message",
+			entry: V001Entry{
+				CoseObj: models.CoseV001Schema{
+					Data: &models.CoseV001SchemaData{
+						Aad: strfmt.Base64([]byte("aad")),
+					},
+					//Message:   strfmt.Base64([]byte("message")),
+					PublicKey: &pubKey,
+				},
+				keyObj:       keyObj,
+				sign1Msg:     &gocose.Sign1Message{},
+				envelopeHash: []byte("hash"),
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing data",
+			entry: V001Entry{
+				CoseObj: models.CoseV001Schema{
+					/*
+						Data: &models.CoseV001SchemaData{
+							Aad: strfmt.Base64([]byte("aad")),
+						},
+					*/
+					Message:   strfmt.Base64([]byte("message")),
+					PublicKey: &pubKey,
+				},
+				keyObj:       keyObj,
+				sign1Msg:     &gocose.Sign1Message{},
+				envelopeHash: []byte("hash"),
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing cose obj",
+			entry: V001Entry{
+				/*
+					CoseObj: models.CoseV001Schema{
+						Data: &models.CoseV001SchemaData{
+							Aad: strfmt.Base64([]byte("aad")),
+						},
+						Message:   strfmt.Base64([]byte("message")),
+						PublicKey: &pubKey,
+					},
+				*/
+				keyObj:       keyObj,
+				sign1Msg:     &gocose.Sign1Message{},
+				envelopeHash: []byte("hash"),
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "empty obj",
+			entry:    V001Entry{
+				/*
+					CoseObj: models.CoseV001Schema{
+						Data: &models.CoseV001SchemaData{
+							Aad: strfmt.Base64([]byte("aad")),
+						},
+						Message:   strfmt.Base64([]byte("message")),
+						PublicKey: &pubKey,
+					},
+					keyObj:       keyObj,
+					sign1Msg:     &gocose.Sign1Message{},
+					envelopeHash: []byte("hash"),
+				*/
+			},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/hashedrekord/hashedrekord_test.go b/pkg/types/hashedrekord/hashedrekord_test.go
index 213e13b..e033954 100644
--- a/pkg/types/hashedrekord/hashedrekord_test.go
+++ b/pkg/types/hashedrekord/hashedrekord_test.go
@@ -39,7 +39,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
diff --git a/pkg/types/hashedrekord/v0.0.1/entry_test.go b/pkg/types/hashedrekord/v0.0.1/entry_test.go
index e78ae21..ba9a528 100644
--- a/pkg/types/hashedrekord/v0.0.1/entry_test.go
+++ b/pkg/types/hashedrekord/v0.0.1/entry_test.go
@@ -284,6 +284,13 @@ func TestCrossFieldValidation(t *testing.T) {
 			t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
 		}
 
+		if tc.expectUnmarshalSuccess {
+			ok, err := v.Insertable()
+			if !ok || err != nil {
+				t.Errorf("unexpected failure in testing insertable on valid entry: %v", err)
+			}
+		}
+
 		b, err := v.Canonicalize(context.TODO())
 		if (err == nil) != tc.expectCanonicalizeSuccess {
 			t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
@@ -297,9 +304,15 @@ func TestCrossFieldValidation(t *testing.T) {
 			if err != nil {
 				t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
 			}
-			if _, err := types.UnmarshalEntry(pe); err != nil {
+			ei, err := types.UnmarshalEntry(pe)
+			if err != nil {
 				t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
 			}
+			// hashedrekord is one of two types (rfc3161, hashedrekord) in that what is persisted is also insertable
+			ok, err := ei.Insertable()
+			if !ok || err != nil {
+				t.Errorf("unexpected failure in testing insertable on entry created from canonicalized content: %v", err)
+			}
 		}
 
 		verifier, err := v.Verifier()
@@ -443,3 +456,203 @@ func testKeyAndCert(t *testing.T) ([]byte, []byte, *ecdsa.PrivateKey) {
 
 	return pub, certPem, priv
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{
+						Hash: &models.HashedrekordV001SchemaDataHash{
+							Algorithm: swag.String(models.HashedrekordV001SchemaDataHashAlgorithmSha256),
+							Value:     swag.String("deadbeef"),
+						},
+					},
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content: strfmt.Base64("sig"),
+						PublicKey: &models.HashedrekordV001SchemaSignaturePublicKey{
+							Content: strfmt.Base64("key"),
+						},
+					},
+				},
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing key",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{
+						Hash: &models.HashedrekordV001SchemaDataHash{
+							Algorithm: swag.String(models.HashedrekordV001SchemaDataHashAlgorithmSha256),
+							Value:     swag.String("deadbeef"),
+						},
+					},
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content: strfmt.Base64("sig"),
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing key content",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{
+						Hash: &models.HashedrekordV001SchemaDataHash{
+							Algorithm: swag.String(models.HashedrekordV001SchemaDataHashAlgorithmSha256),
+							Value:     swag.String("deadbeef"),
+						},
+					},
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content:   strfmt.Base64("sig"),
+						PublicKey: &models.HashedrekordV001SchemaSignaturePublicKey{},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing key content",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{
+						Hash: &models.HashedrekordV001SchemaDataHash{
+							Algorithm: swag.String(models.HashedrekordV001SchemaDataHashAlgorithmSha256),
+							Value:     swag.String("deadbeef"),
+						},
+					},
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content:   strfmt.Base64("sig"),
+						PublicKey: nil,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing sig content",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{
+						Hash: &models.HashedrekordV001SchemaDataHash{
+							Algorithm: swag.String(models.HashedrekordV001SchemaDataHashAlgorithmSha256),
+							Value:     swag.String("deadbeef"),
+						},
+					},
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content: nil,
+						PublicKey: &models.HashedrekordV001SchemaSignaturePublicKey{
+							Content: strfmt.Base64("key"),
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing hash value",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{
+						Hash: &models.HashedrekordV001SchemaDataHash{
+							Algorithm: swag.String(models.HashedrekordV001SchemaDataHashAlgorithmSha256),
+						},
+					},
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content: strfmt.Base64("sig"),
+						PublicKey: &models.HashedrekordV001SchemaSignaturePublicKey{
+							Content: strfmt.Base64("key"),
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing hash algorithm",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{
+						Hash: &models.HashedrekordV001SchemaDataHash{
+							Value: swag.String("deadbeef"),
+						},
+					},
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content: strfmt.Base64("sig"),
+						PublicKey: &models.HashedrekordV001SchemaSignaturePublicKey{
+							Content: strfmt.Base64("key"),
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing hash object",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{},
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content: strfmt.Base64("sig"),
+						PublicKey: &models.HashedrekordV001SchemaSignaturePublicKey{
+							Content: strfmt.Base64("key"),
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing data object",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Signature: &models.HashedrekordV001SchemaSignature{
+						Content: strfmt.Base64("sig"),
+						PublicKey: &models.HashedrekordV001SchemaSignaturePublicKey{
+							Content: strfmt.Base64("key"),
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing sig object",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{
+					Data: &models.HashedrekordV001SchemaData{
+						Hash: &models.HashedrekordV001SchemaDataHash{
+							Algorithm: swag.String(models.HashedrekordV001SchemaDataHashAlgorithmSha256),
+							Value:     swag.String("deadbeef"),
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "empty object",
+			entry: V001Entry{
+				HashedRekordObj: models.HashedrekordV001Schema{},
+			},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/helm/helm_test.go b/pkg/types/helm/helm_test.go
index a8d2fda..db9d7a7 100644
--- a/pkg/types/helm/helm_test.go
+++ b/pkg/types/helm/helm_test.go
@@ -39,7 +39,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
diff --git a/pkg/types/helm/v0.0.1/entry_test.go b/pkg/types/helm/v0.0.1/entry_test.go
index eabde47..36a4cf3 100644
--- a/pkg/types/helm/v0.0.1/entry_test.go
+++ b/pkg/types/helm/v0.0.1/entry_test.go
@@ -182,6 +182,13 @@ func TestCrossFieldValidation(t *testing.T) {
 				t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
 			}
 
+			if tc.expectUnmarshalSuccess {
+				ok, err := v.Insertable()
+				if !ok || err != nil {
+					t.Errorf("unexpected error calling Insertable on valid proposed entry: %v", err)
+				}
+			}
+
 			b, err := v.Canonicalize(context.TODO())
 			if (err == nil) != tc.expectCanonicalizeSuccess {
 				t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
@@ -195,9 +202,13 @@ func TestCrossFieldValidation(t *testing.T) {
 				if err != nil {
 					t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
 				}
-				if _, err := types.UnmarshalEntry(pe); err != nil {
+				ei, err := types.UnmarshalEntry(pe)
+				if err != nil {
 					t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
 				}
+				if ok, err := ei.Insertable(); ok || err == nil {
+					t.Errorf("unexpected success calling Insertable on entry created from canonicalized content")
+				}
 			}
 
 			verifier, err := v.Verifier()
@@ -220,3 +231,131 @@ func TestCrossFieldValidation(t *testing.T) {
 		})
 	}
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	pubKey := strfmt.Base64([]byte("pubKey"))
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				HelmObj: models.HelmV001Schema{
+					Chart: &models.HelmV001SchemaChart{
+						Provenance: &models.HelmV001SchemaChartProvenance{
+							Content: strfmt.Base64([]byte("content")),
+						},
+					},
+					PublicKey: &models.HelmV001SchemaPublicKey{
+						Content: &pubKey,
+					},
+				},
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing key content",
+			entry: V001Entry{
+				HelmObj: models.HelmV001Schema{
+					Chart: &models.HelmV001SchemaChart{
+						Provenance: &models.HelmV001SchemaChartProvenance{
+							Content: strfmt.Base64([]byte("content")),
+						},
+					},
+					PublicKey: &models.HelmV001SchemaPublicKey{
+						//Content: &pubKey,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing key",
+			entry: V001Entry{
+				HelmObj: models.HelmV001Schema{
+					Chart: &models.HelmV001SchemaChart{
+						Provenance: &models.HelmV001SchemaChartProvenance{
+							Content: strfmt.Base64([]byte("content")),
+						},
+					},
+					/*
+						PublicKey: &models.HelmV001SchemaPublicKey{
+							Content: &pubKey,
+						},
+					*/
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing provenance content",
+			entry: V001Entry{
+				HelmObj: models.HelmV001Schema{
+					Chart: &models.HelmV001SchemaChart{
+						Provenance: &models.HelmV001SchemaChartProvenance{
+							//Content: strfmt.Base64([]byte("content")),
+						},
+					},
+					PublicKey: &models.HelmV001SchemaPublicKey{
+						Content: &pubKey,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing provenance obj",
+			entry: V001Entry{
+				HelmObj: models.HelmV001Schema{
+					Chart: &models.HelmV001SchemaChart{
+						/*
+							Provenance: &models.HelmV001SchemaChartProvenance{
+								Content: strfmt.Base64([]byte("content")),
+							},
+						*/
+					},
+					PublicKey: &models.HelmV001SchemaPublicKey{
+						Content: &pubKey,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing chart obj",
+			entry: V001Entry{
+				HelmObj: models.HelmV001Schema{
+					/*
+						Chart: &models.HelmV001SchemaChart{
+							Provenance: &models.HelmV001SchemaChartProvenance{
+								Content: strfmt.Base64([]byte("content")),
+							},
+						},
+					*/
+					PublicKey: &models.HelmV001SchemaPublicKey{
+						Content: &pubKey,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc:      "empty obj",
+			entry:         V001Entry{},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/intoto/intoto_test.go b/pkg/types/intoto/intoto_test.go
index 7feeb2a..af4c90f 100644
--- a/pkg/types/intoto/intoto_test.go
+++ b/pkg/types/intoto/intoto_test.go
@@ -39,7 +39,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
diff --git a/pkg/types/intoto/v0.0.1/entry_test.go b/pkg/types/intoto/v0.0.1/entry_test.go
index d63c033..d48b2b4 100644
--- a/pkg/types/intoto/v0.0.1/entry_test.go
+++ b/pkg/types/intoto/v0.0.1/entry_test.go
@@ -46,6 +46,7 @@ import (
 	slsa "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2"
 	"github.com/secure-systems-lab/go-securesystemslib/dsse"
 	"github.com/sigstore/rekor/pkg/generated/models"
+	pkix509 "github.com/sigstore/rekor/pkg/pki/x509"
 	"github.com/sigstore/rekor/pkg/types"
 	"github.com/sigstore/sigstore/pkg/signature"
 	dsse_signer "github.com/sigstore/sigstore/pkg/signature/dsse"
@@ -277,6 +278,13 @@ func TestV001Entry_Unmarshal(t *testing.T) {
 				if err := v.Unmarshal(it); err != nil {
 					return err
 				}
+
+				if !tt.wantErr {
+					if ok, err := v.Insertable(); !ok || err != nil {
+						t.Errorf("unexpected error calling Insertable on valid proposed entry: %v", err)
+					}
+				}
+
 				if v.IntotoObj.Content.Hash == nil || v.IntotoObj.Content.Hash.Algorithm != tt.it.Content.Hash.Algorithm || v.IntotoObj.Content.Hash.Value != tt.it.Content.Hash.Value {
 					return errors.New("missing envelope hash in validated object")
 				}
@@ -310,6 +318,11 @@ func TestV001Entry_Unmarshal(t *testing.T) {
 				if err != nil {
 					t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tt.name, err)
 				}
+
+				if ok, err := canonicalEntry.Insertable(); ok || err == nil {
+					t.Errorf("unexpected success calling Insertable on entry created from canonicalized content")
+				}
+
 				canonicalV001 := canonicalEntry.(*V001Entry)
 				fmt.Printf("%v", canonicalV001.IntotoObj.Content)
 				if *canonicalV001.IntotoObj.Content.Hash.Value != *tt.it.Content.Hash.Value {
@@ -438,3 +451,136 @@ func TestV001Entry_IndexKeys(t *testing.T) {
 		})
 	}
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatal(err)
+	}
+	der, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
+	if err != nil {
+		t.Fatal(err)
+	}
+	pub := pem.EncodeToMemory(&pem.Block{
+		Bytes: der,
+		Type:  "PUBLIC KEY",
+	})
+	keyObj, err := pkix509.NewPublicKey(bytes.NewReader(pub))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	envStr := envelope(t, key, "payload", "payloadType")
+	env := dsse.Envelope{}
+
+	if err := json.Unmarshal([]byte(envStr), &env); err != nil {
+		t.Fatal(err)
+	}
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				IntotoObj: models.IntotoV001Schema{
+					Content: &models.IntotoV001SchemaContent{
+						Envelope: "envelope",
+					},
+					PublicKey: p(pub),
+				},
+				keyObj: keyObj,
+				env:    env,
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing parsed keyObj",
+			entry: V001Entry{
+				IntotoObj: models.IntotoV001Schema{
+					Content: &models.IntotoV001SchemaContent{
+						Envelope: "envelope",
+					},
+					PublicKey: p(pub),
+				},
+				env: env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing parsed DSSE envelope",
+			entry: V001Entry{
+				IntotoObj: models.IntotoV001Schema{
+					Content: &models.IntotoV001SchemaContent{
+						Envelope: "envelope",
+					},
+					PublicKey: p(pub),
+				},
+				keyObj: keyObj,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing content",
+			entry: V001Entry{
+				IntotoObj: models.IntotoV001Schema{
+					PublicKey: p(pub),
+				},
+				keyObj: keyObj,
+				env:    env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing envelope string",
+			entry: V001Entry{
+				IntotoObj: models.IntotoV001Schema{
+					Content:   &models.IntotoV001SchemaContent{},
+					PublicKey: p(pub),
+				},
+				keyObj: keyObj,
+				env:    env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing unparsed public key",
+			entry: V001Entry{
+				IntotoObj: models.IntotoV001Schema{
+					Content: &models.IntotoV001SchemaContent{
+						Envelope: "envelope",
+					},
+				},
+				keyObj: keyObj,
+				env:    env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "empty parsed DSSE envelope",
+			entry: V001Entry{
+				IntotoObj: models.IntotoV001Schema{
+					Content: &models.IntotoV001SchemaContent{
+						Envelope: "envelope",
+					},
+					PublicKey: p(pub),
+				},
+				keyObj: keyObj,
+				env:    dsse.Envelope{},
+			},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/intoto/v0.0.2/entry_test.go b/pkg/types/intoto/v0.0.2/entry_test.go
index 556339e..9098d3a 100644
--- a/pkg/types/intoto/v0.0.2/entry_test.go
+++ b/pkg/types/intoto/v0.0.2/entry_test.go
@@ -286,6 +286,13 @@ func TestV002Entry_Unmarshal(t *testing.T) {
 				if err := v.Unmarshal(it); err != nil {
 					return err
 				}
+
+				if !tt.wantErr {
+					if ok, err := v.Insertable(); !ok || err != nil {
+						t.Errorf("unexpected error calling insertable on valid proposed entry: %v", err)
+					}
+				}
+
 				want := []string{}
 				for _, sig := range v.IntotoObj.Content.Envelope.Signatures {
 					keyHash := sha256.Sum256(sig.PublicKey)
@@ -325,6 +332,9 @@ func TestV002Entry_Unmarshal(t *testing.T) {
 				if err != nil {
 					t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tt.name, err)
 				}
+				if ok, err := canonicalEntry.Insertable(); ok || err == nil {
+					t.Errorf("unexpected success calling Insertable on entry created from canonicalized content")
+				}
 				canonicalV002 := canonicalEntry.(*V002Entry)
 				fmt.Printf("%v", canonicalV002.IntotoObj.Content)
 				if *canonicalV002.IntotoObj.Content.Hash.Value != *tt.it.Content.Hash.Value {
@@ -489,3 +499,225 @@ func TestV002Entry_IndexKeys(t *testing.T) {
 		})
 	}
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V002Entry
+		expectSuccess bool
+	}
+
+	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	env := envelope(t, key, []byte("payload"))
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					Content: &models.IntotoV002SchemaContent{
+						Envelope: &models.IntotoV002SchemaContentEnvelope{
+							Payload:     strfmt.Base64("payload"),
+							PayloadType: swag.String("payloadType"),
+							Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+								{
+									PublicKey: strfmt.Base64([]byte("key")),
+									Sig:       strfmt.Base64([]byte("sig")),
+								},
+							},
+						},
+					},
+				},
+				env: *env,
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "valid entry but hasn't been parsed",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					Content: &models.IntotoV002SchemaContent{
+						Envelope: &models.IntotoV002SchemaContentEnvelope{
+							Payload:     strfmt.Base64("payload"),
+							PayloadType: swag.String("payloadType"),
+							Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+								{
+									PublicKey: strfmt.Base64([]byte("key")),
+									Sig:       strfmt.Base64([]byte("sig")),
+								},
+							},
+						},
+					},
+				},
+				env: dsse.Envelope{},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing sig",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					Content: &models.IntotoV002SchemaContent{
+						Envelope: &models.IntotoV002SchemaContentEnvelope{
+							Payload:     strfmt.Base64("payload"),
+							PayloadType: swag.String("payloadType"),
+							Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+								{
+									PublicKey: strfmt.Base64([]byte("key")),
+									//Sig:       strfmt.Base64([]byte("sig")),
+								},
+							},
+						},
+					},
+				},
+				env: *env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing key",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					Content: &models.IntotoV002SchemaContent{
+						Envelope: &models.IntotoV002SchemaContentEnvelope{
+							Payload:     strfmt.Base64("payload"),
+							PayloadType: swag.String("payloadType"),
+							Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+								{
+									//PublicKey: strfmt.Base64([]byte("key")),
+									Sig: strfmt.Base64([]byte("sig")),
+								},
+							},
+						},
+					},
+				},
+				env: *env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "empty signatures",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					Content: &models.IntotoV002SchemaContent{
+						Envelope: &models.IntotoV002SchemaContentEnvelope{
+							Payload:     strfmt.Base64("payload"),
+							PayloadType: swag.String("payloadType"),
+							Signatures:  []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{},
+							/*
+								Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+									{
+										PublicKey: strfmt.Base64([]byte("key")),
+										Sig:       strfmt.Base64([]byte("sig")),
+									},
+								},
+							*/
+						},
+					},
+				},
+				env: *env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing payloadType",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					Content: &models.IntotoV002SchemaContent{
+						Envelope: &models.IntotoV002SchemaContentEnvelope{
+							Payload: strfmt.Base64("payload"),
+							//PayloadType: swag.String("payloadType"),
+							Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+								{
+									PublicKey: strfmt.Base64([]byte("key")),
+									Sig:       strfmt.Base64([]byte("sig")),
+								},
+							},
+						},
+					},
+				},
+				env: *env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing payload",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					Content: &models.IntotoV002SchemaContent{
+						Envelope: &models.IntotoV002SchemaContentEnvelope{
+							//Payload:     strfmt.Base64("payload"),
+							PayloadType: swag.String("payloadType"),
+							Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+								{
+									PublicKey: strfmt.Base64([]byte("key")),
+									Sig:       strfmt.Base64([]byte("sig")),
+								},
+							},
+						},
+					},
+				},
+				env: *env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing envelope",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					Content: &models.IntotoV002SchemaContent{
+						/*
+							Envelope: &models.IntotoV002SchemaContentEnvelope{
+								Payload:     strfmt.Base64("payload"),
+								PayloadType: swag.String("payloadType"),
+								Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+									{
+										PublicKey: strfmt.Base64([]byte("key")),
+										Sig:       strfmt.Base64([]byte("sig")),
+									},
+								},
+							},
+						*/
+					},
+				},
+				env: *env,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing content",
+			entry: V002Entry{
+				IntotoObj: models.IntotoV002Schema{
+					/*
+						Content: &models.IntotoV002SchemaContent{
+							Envelope: &models.IntotoV002SchemaContentEnvelope{
+								Payload:     strfmt.Base64("payload"),
+								PayloadType: swag.String("payloadType"),
+								Signatures: []*models.IntotoV002SchemaContentEnvelopeSignaturesItems0{
+									{
+										PublicKey: strfmt.Base64([]byte("key")),
+										Sig:       strfmt.Base64([]byte("sig")),
+									},
+								},
+							},
+						},
+					*/
+				},
+				env: *env,
+			},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/jar/jar_test.go b/pkg/types/jar/jar_test.go
index b41f6e2..4e43b74 100644
--- a/pkg/types/jar/jar_test.go
+++ b/pkg/types/jar/jar_test.go
@@ -38,7 +38,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
diff --git a/pkg/types/jar/v0.0.1/entry_test.go b/pkg/types/jar/v0.0.1/entry_test.go
index a4b0933..bb5b54e 100644
--- a/pkg/types/jar/v0.0.1/entry_test.go
+++ b/pkg/types/jar/v0.0.1/entry_test.go
@@ -116,6 +116,10 @@ Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ==
 			continue
 		}
 
+		if ok, err := v.Insertable(); !ok || err != nil {
+			t.Errorf("unexpected error calling Insertable on valid proposed entry: %v", err)
+		}
+
 		b, err := v.Canonicalize(context.TODO())
 		if (err == nil) != tc.expectCanonicalizeSuccess {
 			t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
@@ -129,9 +133,13 @@ Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ==
 			if err != nil {
 				t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
 			}
-			if _, err := types.UnmarshalEntry(pe); err != nil {
+			ei, err := types.UnmarshalEntry(pe)
+			if err != nil {
 				t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
 			}
+			if ok, err := ei.Insertable(); ok || err == nil {
+				t.Errorf("unexpected err from calling Insertable on entry created from canonicalized content")
+			}
 		}
 
 		verifier, err := v.Verifier()
@@ -184,3 +192,56 @@ func TestJarMetadataSize(t *testing.T) {
 		t.Fatalf("unexpected error %v", err)
 	}
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				JARModel: models.JarV001Schema{
+					Archive: &models.JarV001SchemaArchive{
+						Content: strfmt.Base64([]byte("content")),
+					},
+				},
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing archive content",
+			entry: V001Entry{
+				JARModel: models.JarV001Schema{
+					Archive: &models.JarV001SchemaArchive{
+						//Content: strfmt.Base64([]byte("content")),
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing archive obj",
+			entry: V001Entry{
+				JARModel: models.JarV001Schema{
+					/*
+						Archive: &models.JarV001SchemaArchive{
+							Content: strfmt.Base64([]byte("content")),
+						},
+					*/
+				},
+			},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/rekord/rekord_test.go b/pkg/types/rekord/rekord_test.go
index dace7f1..7d16941 100644
--- a/pkg/types/rekord/rekord_test.go
+++ b/pkg/types/rekord/rekord_test.go
@@ -39,7 +39,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
diff --git a/pkg/types/rekord/v0.0.1/entry_test.go b/pkg/types/rekord/v0.0.1/entry_test.go
index 55e1f9b..ecca289 100644
--- a/pkg/types/rekord/v0.0.1/entry_test.go
+++ b/pkg/types/rekord/v0.0.1/entry_test.go
@@ -232,6 +232,10 @@ func TestCrossFieldValidation(t *testing.T) {
 			continue
 		}
 
+		if ok, err := v.Insertable(); !ok || err != nil {
+			t.Errorf("unexpected error calling Insertable on valid proposed entry: %v", err)
+		}
+
 		b, err := v.Canonicalize(context.TODO())
 		if (err == nil) != tc.expectCanonicalizeSuccess {
 			t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
@@ -245,9 +249,13 @@ func TestCrossFieldValidation(t *testing.T) {
 			if err != nil {
 				t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
 			}
-			if _, err := types.UnmarshalEntry(pe); err != nil {
+			ei, err := types.UnmarshalEntry(pe)
+			if err != nil {
 				t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
 			}
+			if ok, err := ei.Insertable(); ok || err == nil {
+				t.Errorf("unexpected success calling Insertable on entry created from canonicalized content")
+			}
 		}
 
 		verifier, err := v.Verifier()
@@ -288,3 +296,194 @@ func TestUnspecifiedPKIFormat(t *testing.T) {
 		t.Errorf("invalid pki format should not create a valid entry")
 	}
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	sig := strfmt.Base64([]byte("sig"))
+	pub := strfmt.Base64([]byte("pub"))
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					Data: &models.RekordV001SchemaData{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					Signature: &models.RekordV001SchemaSignature{
+						Content: &sig,
+						Format:  swag.String("format"),
+						PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+							Content: &pub,
+						},
+					},
+				},
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing public key content",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					Data: &models.RekordV001SchemaData{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					Signature: &models.RekordV001SchemaSignature{
+						Content:   &sig,
+						Format:    swag.String("format"),
+						PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+							//Content: &pub,
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing public key obj",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					Data: &models.RekordV001SchemaData{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					Signature: &models.RekordV001SchemaSignature{
+						Content: &sig,
+						Format:  swag.String("format"),
+						/*
+							PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+								Content: &pub,
+							},
+						*/
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing format string",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					Data: &models.RekordV001SchemaData{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					Signature: &models.RekordV001SchemaSignature{
+						Content: &sig,
+						//Format:  swag.String("format"),
+						PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+							Content: &pub,
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing signature content",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					Data: &models.RekordV001SchemaData{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					Signature: &models.RekordV001SchemaSignature{
+						//Content: &sig,
+						Format: swag.String("format"),
+						PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+							Content: &pub,
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing signature obj",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					Data: &models.RekordV001SchemaData{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					/*
+						Signature: &models.RekordV001SchemaSignature{
+							Content: &sig,
+							Format:  swag.String("format"),
+							PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+								Content: &pub,
+							},
+						},
+					*/
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing data content",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					Data: &models.RekordV001SchemaData{
+						//Content: strfmt.Base64([]byte("content")),
+					},
+					Signature: &models.RekordV001SchemaSignature{
+						Content: &sig,
+						Format:  swag.String("format"),
+						PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+							Content: &pub,
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing data obj",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					/*
+						Data: &models.RekordV001SchemaData{
+							Content: strfmt.Base64([]byte("content")),
+						},
+					*/
+					Signature: &models.RekordV001SchemaSignature{
+						Content: &sig,
+						Format:  swag.String("format"),
+						PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+							Content: &pub,
+						},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "empty obj",
+			entry: V001Entry{
+				RekordObj: models.RekordV001Schema{
+					/*
+						Data: &models.RekordV001SchemaData{
+							Content: strfmt.Base64([]byte("content")),
+						},
+						Signature: &models.RekordV001SchemaSignature{
+							Content: &sig,
+							Format:  swag.String("format"),
+							PublicKey: &models.RekordV001SchemaSignaturePublicKey{
+								Content: &pub,
+							},
+						},
+					*/
+				},
+			},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/rfc3161/rfc3161_test.go b/pkg/types/rfc3161/rfc3161_test.go
index 36a146d..f9a6b3f 100644
--- a/pkg/types/rfc3161/rfc3161_test.go
+++ b/pkg/types/rfc3161/rfc3161_test.go
@@ -39,7 +39,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
diff --git a/pkg/types/rfc3161/v0.0.1/entry_test.go b/pkg/types/rfc3161/v0.0.1/entry_test.go
index 63b7a9b..6c54574 100644
--- a/pkg/types/rfc3161/v0.0.1/entry_test.go
+++ b/pkg/types/rfc3161/v0.0.1/entry_test.go
@@ -170,6 +170,12 @@ func TestCrossFieldValidation(t *testing.T) {
 			}
 		}
 
+		if tc.expectUnmarshalSuccess {
+			if ok, err := v.Insertable(); !ok || err != nil {
+				t.Errorf("unexpected error calling Insertable on valid proposed entry: %v", err)
+			}
+		}
+
 		b, err := v.Canonicalize(context.TODO())
 		if (err == nil) != tc.expectCanonicalizeSuccess {
 			t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
@@ -183,9 +189,14 @@ func TestCrossFieldValidation(t *testing.T) {
 			if err != nil {
 				t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
 			}
-			if _, err := types.UnmarshalEntry(pe); err != nil {
+			ei, err := types.UnmarshalEntry(pe)
+			if err != nil {
 				t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
 			}
+			// rfc3161 is one of two types that Insertable() should return true from canonicalized entries
+			if ok, err := ei.Insertable(); !ok || err != nil {
+				t.Errorf("unexpected error calling insertable on entry created from canonicalized content")
+			}
 		}
 	}
 }
@@ -244,3 +255,93 @@ func p(b []byte) *strfmt.Base64 {
 	b64 := strfmt.Base64(b)
 	return &b64
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	tsr := strfmt.Base64([]byte("tsr"))
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				Rfc3161Obj: models.Rfc3161V001Schema{
+					Tsr: &models.Rfc3161V001SchemaTsr{
+						Content: &tsr,
+					},
+				},
+				tsrContent: &tsr,
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "unparsed tsr",
+			entry: V001Entry{
+				Rfc3161Obj: models.Rfc3161V001Schema{
+					Tsr: &models.Rfc3161V001SchemaTsr{
+						Content: &tsr,
+					},
+				},
+				//tsrContent: &tsr,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing tsr content",
+			entry: V001Entry{
+				Rfc3161Obj: models.Rfc3161V001Schema{
+					Tsr: &models.Rfc3161V001SchemaTsr{
+						//Content: &tsr,
+					},
+				},
+				tsrContent: &tsr,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing tsr obj",
+			entry: V001Entry{
+				Rfc3161Obj: models.Rfc3161V001Schema{
+					/*
+						Tsr: &models.Rfc3161V001SchemaTsr{
+							Content: &tsr,
+						},
+					*/
+				},
+				tsrContent: &tsr,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing Rfc3161 obj",
+			entry: V001Entry{
+				/*
+					Rfc3161Obj: models.Rfc3161V001Schema{
+						Tsr: &models.Rfc3161V001SchemaTsr{
+							Content: &tsr,
+						},
+					},
+				*/
+				tsrContent: &tsr,
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc:      "empty obj",
+			entry:         V001Entry{},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/rpm/rpm_test.go b/pkg/types/rpm/rpm_test.go
index 747cc9a..d365238 100644
--- a/pkg/types/rpm/rpm_test.go
+++ b/pkg/types/rpm/rpm_test.go
@@ -39,7 +39,7 @@ func (u UnmarshalFailsTester) NewEntry() types.EntryImpl {
 	return &UnmarshalFailsTester{}
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
diff --git a/pkg/types/rpm/v0.0.1/entry_test.go b/pkg/types/rpm/v0.0.1/entry_test.go
index a994f18..941f852 100644
--- a/pkg/types/rpm/v0.0.1/entry_test.go
+++ b/pkg/types/rpm/v0.0.1/entry_test.go
@@ -167,6 +167,12 @@ func TestCrossFieldValidation(t *testing.T) {
 			t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
 		}
 
+		if tc.expectUnmarshalSuccess {
+			if ok, err := v.Insertable(); !ok || err != nil {
+				t.Errorf("unexpected error calling Insertable on valid proposed entry: %v", err)
+			}
+		}
+
 		b, err := v.Canonicalize(context.TODO())
 		if (err == nil) != tc.expectCanonicalizeSuccess {
 			t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
@@ -181,9 +187,13 @@ func TestCrossFieldValidation(t *testing.T) {
 			if err != nil {
 				t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
 			}
-			if _, err := types.UnmarshalEntry(pe); err != nil {
+			ei, err := types.UnmarshalEntry(pe)
+			if err != nil {
 				t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
 			}
+			if ok, err := ei.Insertable(); ok || err == nil {
+				t.Errorf("unexpected success calling Insertable on entry created from canonicalized content")
+			}
 		}
 
 		verifier, err := v.Verifier()
@@ -205,3 +215,103 @@ func TestCrossFieldValidation(t *testing.T) {
 		}
 	}
 }
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	pub := strfmt.Base64([]byte("pub"))
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				RPMModel: models.RpmV001Schema{
+					Package: &models.RpmV001SchemaPackage{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					PublicKey: &models.RpmV001SchemaPublicKey{
+						Content: &pub,
+					},
+				},
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing public key content",
+			entry: V001Entry{
+				RPMModel: models.RpmV001Schema{
+					Package: &models.RpmV001SchemaPackage{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					PublicKey: &models.RpmV001SchemaPublicKey{
+						//Content: &pub,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing public key obj",
+			entry: V001Entry{
+				RPMModel: models.RpmV001Schema{
+					Package: &models.RpmV001SchemaPackage{
+						Content: strfmt.Base64([]byte("content")),
+					},
+					/*
+						PublicKey: &models.RpmV001SchemaPublicKey{
+							Content: &pub,
+						},
+					*/
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing package content",
+			entry: V001Entry{
+				RPMModel: models.RpmV001Schema{
+					Package: &models.RpmV001SchemaPackage{
+						//Content: strfmt.Base64([]byte("content")),
+					},
+					PublicKey: &models.RpmV001SchemaPublicKey{
+						Content: &pub,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing package obj",
+			entry: V001Entry{
+				RPMModel: models.RpmV001Schema{
+					/*
+						Package: &models.RpmV001SchemaPackage{
+							Content: strfmt.Base64([]byte("content")),
+						},
+					*/
+					PublicKey: &models.RpmV001SchemaPublicKey{
+						Content: &pub,
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc:      "empty obj",
+			entry:         V001Entry{},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
+			}
+		})
+	}
+}
diff --git a/pkg/types/test_util.go b/pkg/types/test_util.go
index e65f574..03b5b9c 100644
--- a/pkg/types/test_util.go
+++ b/pkg/types/test_util.go
@@ -43,11 +43,11 @@ func (u BaseUnmarshalTester) IndexKeys() ([]string, error) {
 	return []string{}, nil
 }
 
-func (u BaseUnmarshalTester) Canonicalize(ctx context.Context) ([]byte, error) {
+func (u BaseUnmarshalTester) Canonicalize(_ context.Context) ([]byte, error) {
 	return nil, nil
 }
 
-func (u BaseUnmarshalTester) Unmarshal(pe models.ProposedEntry) error {
+func (u BaseUnmarshalTester) Unmarshal(_ models.ProposedEntry) error {
 	return nil
 }
 
@@ -67,20 +67,24 @@ func (u BaseUnmarshalTester) CreateFromArtifactProperties(_ context.Context, _ A
 	return nil, nil
 }
 
+func (u BaseUnmarshalTester) Insertable() (bool, error) {
+	return false, nil
+}
+
 type BaseProposedEntryTester struct{}
 
 func (b BaseProposedEntryTester) Kind() string {
 	return "nil"
 }
 
-func (b BaseProposedEntryTester) SetKind(v string) {
+func (b BaseProposedEntryTester) SetKind(_ string) {
 
 }
 
-func (b BaseProposedEntryTester) Validate(r strfmt.Registry) error {
+func (b BaseProposedEntryTester) Validate(_ strfmt.Registry) error {
 	return nil
 }
 
-func (b BaseProposedEntryTester) ContextValidate(ctx context.Context, r strfmt.Registry) error {
+func (b BaseProposedEntryTester) ContextValidate(_ context.Context, _ strfmt.Registry) error {
 	return nil
 }
diff --git a/pkg/types/tuf/tuf_test.go b/pkg/types/tuf/tuf_test.go
index a08cbb9..16a9fb9 100644
--- a/pkg/types/tuf/tuf_test.go
+++ b/pkg/types/tuf/tuf_test.go
@@ -43,7 +43,7 @@ func (u UnmarshalFailsTester) Verifier() (pki.PublicKey, error) {
 	return nil, nil
 }
 
-func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error {
+func (u UnmarshalFailsTester) Unmarshal(_ models.ProposedEntry) error {
 	return errors.New("error")
 }
 
diff --git a/pkg/types/tuf/v0.0.1/entry_test.go b/pkg/types/tuf/v0.0.1/entry_test.go
index 13ab2fe..4193c4e 100644
--- a/pkg/types/tuf/v0.0.1/entry_test.go
+++ b/pkg/types/tuf/v0.0.1/entry_test.go
@@ -177,68 +177,175 @@ func TestCrossFieldValidation(t *testing.T) {
 	}
 
 	for _, tc := range testCases {
-		if err := tc.entry.Validate(); (err == nil) != tc.expectUnmarshalSuccess {
-			t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
-		}
-		// No need to continue here if we failed at unmarshal
-		if !tc.expectUnmarshalSuccess {
-			continue
-		}
-
-		v := &V001Entry{}
-		r := models.TUF{
-			APIVersion: swag.String(tc.entry.APIVersion()),
-			Spec:       tc.entry.TufObj,
-		}
-
-		unmarshalAndValidate := func() error {
-			if err := v.Unmarshal(&r); err != nil {
-				return err
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if err := tc.entry.Validate(); (err == nil) != tc.expectUnmarshalSuccess {
+				t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
 			}
-			return v.Validate()
-		}
-		if err := unmarshalAndValidate(); (err == nil) != tc.expectUnmarshalSuccess {
-			t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
-		}
-
-		b, err := v.Canonicalize(context.TODO())
-		if (err == nil) != tc.expectCanonicalizeSuccess {
-			t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
-		} else if err != nil {
-			if _, ok := err.(types.ValidationError); !ok {
-				t.Errorf("canonicalize returned an unexpected error that isn't of type types.ValidationError: %v", err)
+			// No need to continue here if we failed at unmarshal
+			if !tc.expectUnmarshalSuccess {
+				return
 			}
-		}
 
-		if b != nil {
-			pe, err := models.UnmarshalProposedEntry(bytes.NewReader(b), runtime.JSONConsumer())
-			if err != nil {
-				t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
+			v := &V001Entry{}
+			r := models.TUF{
+				APIVersion: swag.String(tc.entry.APIVersion()),
+				Spec:       tc.entry.TufObj,
 			}
-			if _, err := types.UnmarshalEntry(pe); err != nil {
-				t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
+
+			unmarshalAndValidate := func() error {
+				if err := v.Unmarshal(&r); err != nil {
+					return err
+				}
+				return v.Validate()
+			}
+			if err := unmarshalAndValidate(); (err == nil) != tc.expectUnmarshalSuccess {
+				t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
 			}
-		}
 
-		verifier, err := v.Verifier()
-		if tc.expectVerifierSuccess {
-			if err != nil {
-				t.Errorf("%v: unexpected error, got %v", tc.caseDesc, err)
-			} else {
-				pub, _ := verifier.CanonicalValue()
-				rootBytes := new(bytes.Buffer)
-				if err := json.Compact(rootBytes, keyBytes); err != nil {
-					t.Fatal(err)
+			if tc.expectUnmarshalSuccess {
+				if ok, err := v.Insertable(); !ok || err != nil {
+					t.Errorf("unexpected error calling Insertable on valid proposed entry: %v", err)
+				}
+			}
+
+			b, err := v.Canonicalize(context.TODO())
+			if (err == nil) != tc.expectCanonicalizeSuccess {
+				t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
+			} else if err != nil {
+				if _, ok := err.(types.ValidationError); !ok {
+					t.Errorf("canonicalize returned an unexpected error that isn't of type types.ValidationError: %v", err)
+				}
+			}
+
+			if b != nil {
+				pe, err := models.UnmarshalProposedEntry(bytes.NewReader(b), runtime.JSONConsumer())
+				if err != nil {
+					t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
 				}
-				if !reflect.DeepEqual(pub, rootBytes.Bytes()) {
-					t.Errorf("%v: verifier and public keys do not match: %v, %v", tc.caseDesc, string(pub), rootBytes)
+				if _, err := types.UnmarshalEntry(pe); err != nil {
+					t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
 				}
+				// Insertable on canonicalized content is variable so we skip testing it here
 			}
-		} else {
-			if err == nil {
-				s, _ := verifier.CanonicalValue()
-				t.Errorf("%v: expected error for %v, got %v", tc.caseDesc, string(s), err)
+
+			verifier, err := v.Verifier()
+			if tc.expectVerifierSuccess {
+				if err != nil {
+					t.Errorf("%v: unexpected error, got %v", tc.caseDesc, err)
+				} else {
+					pub, _ := verifier.CanonicalValue()
+					rootBytes := new(bytes.Buffer)
+					if err := json.Compact(rootBytes, keyBytes); err != nil {
+						t.Fatal(err)
+					}
+					if !reflect.DeepEqual(pub, rootBytes.Bytes()) {
+						t.Errorf("%v: verifier and public keys do not match: %v, %v", tc.caseDesc, string(pub), rootBytes)
+					}
+				}
+			} else {
+				if err == nil {
+					s, _ := verifier.CanonicalValue()
+					t.Errorf("%v: expected error for %v, got %v", tc.caseDesc, string(s), err)
+				}
+			}
+		})
+	}
+}
+
+func TestInsertable(t *testing.T) {
+	type TestCase struct {
+		caseDesc      string
+		entry         V001Entry
+		expectSuccess bool
+	}
+
+	testCases := []TestCase{
+		{
+			caseDesc: "valid entry",
+			entry: V001Entry{
+				TufObj: models.TUFV001Schema{
+					Metadata: &models.TUFV001SchemaMetadata{
+						Content: struct{}{},
+					},
+					Root: &models.TUFV001SchemaRoot{
+						Content: struct{}{},
+					},
+				},
+			},
+			expectSuccess: true,
+		},
+		{
+			caseDesc: "missing root content",
+			entry: V001Entry{
+				TufObj: models.TUFV001Schema{
+					Metadata: &models.TUFV001SchemaMetadata{
+						Content: struct{}{},
+					},
+					Root: &models.TUFV001SchemaRoot{
+						//Content: struct{}{},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing root obj",
+			entry: V001Entry{
+				TufObj: models.TUFV001Schema{
+					Metadata: &models.TUFV001SchemaMetadata{
+						Content: struct{}{},
+					},
+					/*
+						Root: &models.TUFV001SchemaRoot{
+							Content: struct{}{},
+						},
+					*/
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing metadata content",
+			entry: V001Entry{
+				TufObj: models.TUFV001Schema{
+					Metadata: &models.TUFV001SchemaMetadata{
+						//Content: struct{}{},
+					},
+					Root: &models.TUFV001SchemaRoot{
+						Content: struct{}{},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc: "missing metadata content",
+			entry: V001Entry{
+				TufObj: models.TUFV001Schema{
+					/*
+						Metadata: &models.TUFV001SchemaMetadata{
+							Content: struct{}{},
+						},
+					*/
+					Root: &models.TUFV001SchemaRoot{
+						Content: struct{}{},
+					},
+				},
+			},
+			expectSuccess: false,
+		},
+		{
+			caseDesc:      "empty obj",
+			entry:         V001Entry{},
+			expectSuccess: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.caseDesc, func(t *testing.T) {
+			if ok, err := tc.entry.Insertable(); ok != tc.expectSuccess {
+				t.Errorf("unexpected result calling Insertable: %v", err)
 			}
-		}
+		})
 	}
 }
diff --git a/pkg/types/types_test.go b/pkg/types/types_test.go
index ea7c530..7d9ca66 100644
--- a/pkg/types/types_test.go
+++ b/pkg/types/types_test.go
@@ -38,11 +38,11 @@ func (e InvalidEntry) Kind() string {
 
 func (e InvalidEntry) SetKind(string) {}
 
-func (e InvalidEntry) Validate(formats strfmt.Registry) error {
+func (e InvalidEntry) Validate(_ strfmt.Registry) error {
 	return nil
 }
 
-func (e InvalidEntry) ContextValidate(context context.Context, formats strfmt.Registry) error {
+func (e InvalidEntry) ContextValidate(_ context.Context, _ strfmt.Registry) error {
 	return nil
 }
 
@@ -57,11 +57,11 @@ func (e UnmarshalErrorValidEntry) Kind() string {
 
 func (e UnmarshalErrorValidEntry) SetKind(string) {}
 
-func (e UnmarshalErrorValidEntry) Validate(formats strfmt.Registry) error {
+func (e UnmarshalErrorValidEntry) Validate(_ strfmt.Registry) error {
 	return errors.New("invalid content")
 }
 
-func (e UnmarshalErrorValidEntry) ContextValidate(context context.Context, formats strfmt.Registry) error {
+func (e UnmarshalErrorValidEntry) ContextValidate(_ context.Context, _ strfmt.Registry) error {
 	return nil
 }
 
diff --git a/pkg/util/timestamp_note_test.go b/pkg/util/timestamp_note_test.go
deleted file mode 100644
index f263e1d..0000000
--- a/pkg/util/timestamp_note_test.go
+++ /dev/null
@@ -1,537 +0,0 @@
-//
-// Copyright 2021 The Sigstore Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package util
-
-import (
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/elliptic"
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/sha256"
-	"encoding/hex"
-	"math/big"
-	"net/url"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/sigstore/sigstore/pkg/signature"
-	"github.com/sigstore/sigstore/pkg/signature/options"
-	"golang.org/x/mod/sumdb/note"
-)
-
-// heavily borrowed from https://github.com/google/trillian-examples/blob/master/formats/log/checkpoint_test.go
-
-func TestMarshalTimestampNote(t *testing.T) {
-	certChainURL, err := url.Parse("http://localhost:3000/api/v1/timestamp/certchain")
-	if err != nil {
-		t.Fatal("error parsing URL")
-	}
-	location, err := time.LoadLocation("UTC")
-	if err != nil {
-		t.Fatal("error loading location")
-	}
-	someTime := time.Date(2021, 07, 26, 0, 0, 0, 0, location)
-	for _, test := range []struct {
-		msg  []byte
-		t    TimestampNote
-		want string
-	}{
-		{
-			msg: []byte("bananas"),
-			t: TimestampNote{
-				Origin:       "Timestamp Note v0",
-				Nonce:        big.NewInt(123).Bytes(),
-				Time:         someTime,
-				Radius:       123,
-				CertChainRef: certChainURL,
-			},
-			want: "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-		},
-		{
-			msg: []byte("the view from the tree tops is great!"),
-			t: TimestampNote{
-				Origin:       "Timestamp Note v1",
-				Nonce:        big.NewInt(12345678).Bytes(),
-				Time:         someTime,
-				Radius:       1,
-				CertChainRef: certChainURL,
-			},
-			want: "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\n2021-07-26T00:00:00Z\n1\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-		}, {
-			msg: []byte("bananas"),
-			t: TimestampNote{
-				Origin:       "Timestamp Note v7",
-				Nonce:        big.NewInt(123).Bytes(),
-				Time:         someTime,
-				Radius:       123,
-				CertChainRef: certChainURL,
-				OtherContent: []string{"foo", "bar"},
-			},
-			want: "Timestamp Note v7\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\nfoo\nbar\n",
-		},
-	} {
-		t.Run(string(test.t.Origin), func(t *testing.T) {
-			h := sha256.Sum256([]byte(test.msg))
-			test.t.MessageImprint = "sha256:" + hex.EncodeToString(h[:])
-			got, err := test.t.MarshalText()
-			if err != nil {
-				t.Fatalf("unexpected error marshalling: %v", err)
-			}
-			if string(got) != test.want {
-				t.Fatalf("Marshal = %q, want %q", got, test.want)
-			}
-		})
-	}
-}
-
-func TestUnmarshalTimestampNote(t *testing.T) {
-	certChainURL, err := url.Parse("http://localhost:3000/api/v1/timestamp/certchain")
-	if err != nil {
-		t.Fatal("error parsing URL")
-	}
-	location, err := time.LoadLocation("UTC")
-	if err != nil {
-		t.Fatal("error loading location")
-	}
-	someTime := time.Date(2021, 07, 26, 0, 0, 0, 0, location)
-	for _, test := range []struct {
-		desc    string
-		m       string
-		want    TimestampNote
-		wantErr bool
-	}{
-		{
-			desc: "valid one",
-			m:    "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-			want: TimestampNote{
-				Origin:         "Timestamp Note v0",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			wantErr: false,
-		}, {
-			desc: "valid with different ecosystem",
-			m:    "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\n2021-07-26T00:00:00Z\n1\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-			want: TimestampNote{
-				Origin:         "Timestamp Note v1",
-				MessageImprint: "sha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e",
-				Nonce:          big.NewInt(12345678).Bytes(),
-				Time:           someTime,
-				Radius:         1,
-				CertChainRef:   certChainURL,
-			},
-		}, {
-			desc: "valid with trailing data",
-			m:    "Timestamp Note v7\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\nfoo\nbar\n",
-			want: TimestampNote{
-				Origin:         "Timestamp Note v7",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-				OtherContent:   []string{"foo", "bar"},
-			},
-		}, {
-			desc: "valid with trailing newlines",
-			m:    "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\n2021-07-26T00:00:00Z\n1\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n\n\n",
-			want: TimestampNote{
-				Origin:         "Timestamp Note v1",
-				MessageImprint: "sha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e",
-				Nonce:          big.NewInt(12345678).Bytes(),
-				Time:           someTime,
-				Radius:         1,
-				CertChainRef:   certChainURL,
-			},
-		}, {
-			desc:    "invalid - insufficient lines",
-			m:       "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\n",
-			wantErr: true,
-		}, {
-			desc:    "invalid - empty header",
-			m:       "\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\n2021-07-26T00:00:00Z\n1\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-			wantErr: true,
-		}, {
-			desc:    "invalid - missing newline",
-			m:       "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\n2021-07-26T00:00:00Z\n1\nhttp://localhost:3000/api/v1/timestamp/certchain",
-			wantErr: true,
-		}, {
-			desc:    "invalid sha - not a valid sha",
-			m:       "Timestamp Note v1\nsha256:17fb2e8cbf60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\n2021-07-26T00:00:00Z\n1\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-			wantErr: true,
-		}, {
-			desc:    "invalid base64 - nonce",
-			m:       "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\n@\n2021-07-26T00:00:00Z\n1\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-			wantErr: true,
-		}, {
-			desc:    "invalid time",
-			m:       "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\nabc\n1\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-			wantErr: true,
-		}, {
-			desc:    "invalid radius - not an int",
-			m:       "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\n2021-07-26T00:00:00Z\na\nhttp://localhost:3000/api/v1/timestamp/certchain\n",
-			wantErr: true,
-		},
-		{
-			desc:    "invalid cert chain - not a url",
-			m:       "Timestamp Note v1\nsha256:17fb2e8cbf5f60f881c075b1fd0cad32913f2f08b35053fed1c5a785dff90e8e\nvGFO\n2021-07-26T00:00:00Z\n1\n%gh&%ij\n",
-			wantErr: true,
-		},
-	} {
-		t.Run(string(test.desc), func(t *testing.T) {
-			var got TimestampNote
-			var gotErr error
-			if gotErr = got.UnmarshalText([]byte(test.m)); (gotErr != nil) != test.wantErr {
-				t.Fatalf("Unmarshal = %q, wantErr: %T", gotErr, test.wantErr)
-			}
-			if diff := cmp.Diff(test.want, got); len(diff) != 0 {
-				t.Fatalf("Unmarshalled TimestampNote with diff %s", diff)
-			}
-			if !test.wantErr != TimestampNoteValidator(test.m) {
-				t.Fatalf("Validator failed for %s", test.desc)
-			}
-		})
-	}
-}
-
-func TestSigningRoundtripTimestampNote(t *testing.T) {
-	certChainURL, err := url.Parse("http://localhost:3000/api/v1/timestamp/certchain")
-	if err != nil {
-		t.Fatal("error parsing URL")
-	}
-	location, err := time.LoadLocation("UTC")
-	if err != nil {
-		t.Fatal("error loading location")
-	}
-	someTime := time.Date(2021, 07, 26, 0, 0, 0, 0, location)
-	rsaKey, _ := rsa.GenerateKey(rand.Reader, 2048)
-	ecdsaKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	edPubKey, edPrivKey, _ := ed25519.GenerateKey(rand.Reader)
-	for _, test := range []struct {
-		t             TimestampNote
-		identity      string
-		signer        crypto.Signer
-		pubKey        crypto.PublicKey
-		opts          crypto.SignerOpts
-		wantSignErr   bool
-		wantVerifyErr bool
-	}{
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note RSA v0",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			identity:      "someone",
-			signer:        rsaKey,
-			pubKey:        rsaKey.Public(),
-			opts:          &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthAuto, Hash: crypto.SHA256},
-			wantSignErr:   false,
-			wantVerifyErr: false,
-		},
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note ECDSA v0",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			identity:      "someone",
-			signer:        ecdsaKey,
-			pubKey:        ecdsaKey.Public(),
-			opts:          nil,
-			wantSignErr:   false,
-			wantVerifyErr: false,
-		},
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note ED25519 v0",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			identity:      "someone",
-			signer:        edPrivKey,
-			pubKey:        edPubKey,
-			opts:          crypto.Hash(0),
-			wantSignErr:   false,
-			wantVerifyErr: false,
-		},
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note Mismatch v0",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			identity:      "someone",
-			signer:        edPrivKey,
-			pubKey:        ecdsaKey.Public(),
-			opts:          crypto.Hash(0),
-			wantSignErr:   false,
-			wantVerifyErr: true,
-		},
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note Mismatch v1",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			identity:      "someone",
-			signer:        ecdsaKey,
-			pubKey:        rsaKey.Public(),
-			opts:          &rsa.PSSOptions{Hash: crypto.SHA256},
-			wantSignErr:   false,
-			wantVerifyErr: true,
-		},
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note Mismatch v2",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			identity:      "someone",
-			signer:        edPrivKey,
-			pubKey:        rsaKey.Public(),
-			opts:          &rsa.PSSOptions{Hash: crypto.SHA256},
-			wantSignErr:   false,
-			wantVerifyErr: true,
-		},
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note Mismatch v3",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			identity:      "someone",
-			signer:        ecdsaKey,
-			pubKey:        edPubKey,
-			opts:          nil,
-			wantSignErr:   false,
-			wantVerifyErr: true,
-		},
-	} {
-		t.Run(string(test.t.Origin), func(t *testing.T) {
-			text, _ := test.t.MarshalText()
-			sc := &SignedNote{
-				Note: string(text),
-			}
-			signer, _ := signature.LoadSigner(test.signer, crypto.SHA256)
-			if _, ok := test.signer.(*rsa.PrivateKey); ok {
-				signer, _ = signature.LoadRSAPSSSigner(test.signer.(*rsa.PrivateKey), crypto.SHA256, test.opts.(*rsa.PSSOptions))
-			}
-
-			_, err := sc.Sign(test.identity, signer, options.WithCryptoSignerOpts(test.opts))
-			if (err != nil) != test.wantSignErr {
-				t.Fatalf("signing test failed: wantSignErr %v, err %v", test.wantSignErr, err)
-			}
-			if !test.wantSignErr {
-				verifier, _ := signature.LoadVerifier(test.pubKey, crypto.SHA256)
-				if _, ok := test.pubKey.(*rsa.PublicKey); ok {
-					verifier, _ = signature.LoadRSAPSSVerifier(test.pubKey.(*rsa.PublicKey), crypto.SHA256, test.opts.(*rsa.PSSOptions))
-				}
-
-				if !sc.Verify(verifier) != test.wantVerifyErr {
-					t.Fatalf("verification test failed %v", sc.Verify(verifier))
-				}
-				if _, err := sc.Sign("second", signer, options.WithCryptoSignerOpts(test.opts)); err != nil {
-					t.Fatalf("adding second signature failed: %v", err)
-				}
-				if len(sc.Signatures) != 2 {
-					t.Fatalf("expected two signatures on checkpoint, only found %v", len(sc.Signatures))
-				}
-				// finally, test marshalling object and unmarshalling
-				marshalledSc, err := sc.MarshalText()
-				if err != nil {
-					t.Fatalf("error during marshalling: %v", err)
-				}
-				text, _ = test.t.MarshalText()
-				sc2 := &SignedNote{
-					Note: string(text),
-				}
-				if err := sc2.UnmarshalText(marshalledSc); err != nil {
-					t.Fatalf("error unmarshalling just marshalled object %v\n%v", err, string(marshalledSc))
-				}
-				if diff := cmp.Diff(sc, sc2); len(diff) != 0 {
-					t.Fatalf("UnmarshalText = diff %s", diff)
-				}
-			}
-		})
-	}
-}
-
-func TestInvalidSigVerificationTimestampNote(t *testing.T) {
-	certChainURL, err := url.Parse("http://localhost:3000/api/v1/timestamp/certchain")
-	if err != nil {
-		t.Fatal("error parsing URL")
-	}
-	location, err := time.LoadLocation("UTC")
-	if err != nil {
-		t.Fatal("error loading location")
-	}
-	someTime := time.Date(2021, 07, 26, 0, 0, 0, 0, location)
-	ecdsaKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	for _, test := range []struct {
-		t              TimestampNote
-		s              []note.Signature
-		pubKey         crypto.PublicKey
-		expectedResult bool
-	}{
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note v0",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			s:              []note.Signature{},
-			pubKey:         ecdsaKey.Public(),
-			expectedResult: false,
-		},
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note v0 - not base 64",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			pubKey: ecdsaKey.Public(),
-			s: []note.Signature{
-				{
-					Name:   "something",
-					Hash:   1234,
-					Base64: "not_base 64 string",
-				},
-			},
-			expectedResult: false,
-		},
-		{
-			t: TimestampNote{
-				Origin:         "Timestamp Note v0 invalid signature",
-				MessageImprint: "sha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904",
-				Nonce:          big.NewInt(123).Bytes(),
-				Time:           someTime,
-				Radius:         123,
-				CertChainRef:   certChainURL,
-			},
-			pubKey: ecdsaKey.Public(),
-			s: []note.Signature{
-				{
-					Name:   "someone",
-					Hash:   142,
-					Base64: "bm90IGEgc2ln", // valid base64, not a valid signature
-				},
-			},
-			expectedResult: false,
-		},
-	} {
-		t.Run(string(test.t.Origin), func(t *testing.T) {
-			text, _ := test.t.MarshalText()
-			sc := SignedNote{
-				Note:       string(text),
-				Signatures: test.s,
-			}
-			verifier, _ := signature.LoadVerifier(test.pubKey, crypto.SHA256)
-			result := sc.Verify(verifier)
-			if result != test.expectedResult {
-				t.Fatal("verification test generated unexpected result")
-			}
-		})
-	}
-}
-
-// does not test validity of signatures but merely parsing logic
-func TestUnmarshalSignedTimestampNote(t *testing.T) {
-	for _, test := range []struct {
-		desc    string
-		m       string
-		wantErr bool
-	}{
-		{
-			desc:    "invalid timestamp note, no signatures",
-			m:       "Timestamp Note v0\n\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n",
-			wantErr: true,
-		}, {
-			desc:    "valid timestamp note, no signatures",
-			m:       "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n",
-			wantErr: true,
-		}, {
-			desc:    "incorrect signature line format",
-			m:       "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n* name not-a-sig\n",
-			wantErr: true,
-		}, {
-			desc: "signature not base64 encoded",
-
-			m:       "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n\u2014 name not-b64\n",
-			wantErr: true,
-		}, {
-			desc:    "missing identity",
-			m:       "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n\u2014 YQ==\n",
-			wantErr: true,
-		}, {
-			desc:    "signature base64 encoded but too short",
-			m:       "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n\u2014 name YQ==\n",
-			wantErr: true,
-		}, {
-			desc:    "valid signed timestamp note - single signature",
-			m:       "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n\u2014 name pOhM+S/mYjEYtQsOF4lL8o/dR+nbjoz5Cvg/n486KIismpVq0s4wxBaakmryI7zThjWAqRUyECPL3WSEcVDEBQ==\n",
-			wantErr: false,
-		}, {
-			desc:    "valid signed timestamp note - two signatures",
-			m:       "Timestamp Note v0\nsha256:e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904\new==\n2021-07-26T00:00:00Z\n123\nhttp://localhost:3000/api/v1/timestamp/certchain\n\n\u2014 name pOhM+S/mYjEYtQsOF4lL8o/dR+nbjoz5Cvg/n486KIismpVq0s4wxBaakmryI7zThjWAqRUyECPL3WSEcVDEBQ==\n\u2014 another_name pOhM+S/mYjEYtQsOF4lL8o/dR+nbjoz5Cvg/n486KIismpVq0s4wxBaakmryI7zThjWAqRUyECPL3WSEcVDEBQ==\n",
-			wantErr: false,
-		},
-	} {
-		t.Run(string(test.desc), func(t *testing.T) {
-			var got SignedNote
-			var gotErr error
-			if gotErr = got.UnmarshalText([]byte(test.m)); (gotErr != nil) != test.wantErr {
-				t.Fatalf("UnmarshalText(%s) = %q, wantErr: %v", test.desc, gotErr, test.wantErr)
-			}
-			if !test.wantErr != SignedTimestampNoteValidator(test.m) {
-				t.Fatalf("Validator failed for %s", test.desc)
-			}
-		})
-	}
-}
diff --git a/pkg/verify/verify_test.go b/pkg/verify/verify_test.go
index 7cc7ded..02dd06a 100644
--- a/pkg/verify/verify_test.go
+++ b/pkg/verify/verify_test.go
@@ -38,7 +38,7 @@ type TlogClient struct {
 	LogInfo models.LogInfo
 }
 
-func (m *TlogClient) GetLogProof(params *tlog.GetLogProofParams, opts ...tlog.ClientOption) (*tlog.GetLogProofOK, error) {
+func (m *TlogClient) GetLogProof(_ *tlog.GetLogProofParams, _ ...tlog.ClientOption) (*tlog.GetLogProofOK, error) {
 	return &tlog.GetLogProofOK{
 		Payload: &models.ConsistencyProof{
 			Hashes:   m.Proof,
@@ -46,14 +46,14 @@ func (m *TlogClient) GetLogProof(params *tlog.GetLogProofParams, opts ...tlog.Cl
 		}}, nil
 }
 
-func (m *TlogClient) GetLogInfo(params *tlog.GetLogInfoParams, opts ...tlog.ClientOption) (*tlog.GetLogInfoOK, error) {
+func (m *TlogClient) GetLogInfo(_ *tlog.GetLogInfoParams, _ ...tlog.ClientOption) (*tlog.GetLogInfoOK, error) {
 	return &tlog.GetLogInfoOK{
 		Payload: &m.LogInfo,
 	}, nil
 }
 
 // TODO: Implement mock
-func (m *TlogClient) SetTransport(transport runtime.ClientTransport) {
+func (m *TlogClient) SetTransport(_ runtime.ClientTransport) {
 }
 
 func TestConsistency(t *testing.T) {
diff --git a/tests/e2e_test.go b/tests/e2e_test.go
index 1ef80d4..7561c31 100644
--- a/tests/e2e_test.go
+++ b/tests/e2e_test.go
@@ -21,19 +21,19 @@ import (
 	"bytes"
 	"context"
 	"crypto"
+	"crypto/ecdsa"
 	"crypto/sha256"
 	"encoding/hex"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io/ioutil"
 	"net/http"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"strconv"
 	"strings"
 	"testing"
-	"time"
 
 	"golang.org/x/sync/errgroup"
 
@@ -43,14 +43,15 @@ import (
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-cmp/cmp/cmpopts"
 	"github.com/sigstore/rekor/pkg/client"
+	generatedClient "github.com/sigstore/rekor/pkg/generated/client"
 	"github.com/sigstore/rekor/pkg/generated/client/entries"
+	"github.com/sigstore/rekor/pkg/generated/client/pubkey"
 	"github.com/sigstore/rekor/pkg/generated/models"
 	sigx509 "github.com/sigstore/rekor/pkg/pki/x509"
 	"github.com/sigstore/rekor/pkg/sharding"
 	"github.com/sigstore/rekor/pkg/signer"
 	_ "github.com/sigstore/rekor/pkg/types/intoto/v0.0.1"
 	rekord "github.com/sigstore/rekor/pkg/types/rekord/v0.0.1"
-	"github.com/sigstore/rekor/pkg/util"
 	"github.com/sigstore/sigstore/pkg/cryptoutils"
 	"github.com/sigstore/sigstore/pkg/signature"
 	"github.com/sigstore/sigstore/pkg/signature/options"
@@ -181,30 +182,22 @@ func TestGetCLI(t *testing.T) {
 	runCli(t, "get", "--format=json", "--uuid", entryID.ReturnEntryIDString())
 }
 
-func TestWatch(t *testing.T) {
-	td := t.TempDir()
-	cmd := exec.Command(server, "watch", "--interval=1s")
-	cmd.Env = append(os.Environ(), "REKOR_STH_BUCKET=file://"+td)
-	go func() {
-		b, err := cmd.CombinedOutput()
-		t.Log(string(b))
-		if cmd.ProcessState.Exited() && cmd.ProcessState.ExitCode() != 0 {
-			if err != nil {
-				t.Fatal(err)
-			}
-		}
-	}()
-
-	// Wait 3 intervals
-	time.Sleep(3 * time.Second)
-	cmd.Process.Kill()
+func publicKeyFromRekorClient(ctx context.Context, c *generatedClient.Rekor) (*ecdsa.PublicKey, error) {
+	resp, err := c.Pubkey.GetPublicKey(&pubkey.GetPublicKeyParams{Context: ctx})
+	if err != nil {
+		return nil, err
+	}
 
-	// Check for files
-	fi, err := ioutil.ReadDir(td)
-	if err != nil || len(fi) == 0 {
-		t.Error("expected files")
+	// marshal the pubkey
+	pubKey, err := cryptoutils.UnmarshalPEMToPublicKey([]byte(resp.GetPayload()))
+	if err != nil {
+		return nil, err
+	}
+	ed, ok := pubKey.(*ecdsa.PublicKey)
+	if !ok {
+		return nil, errors.New("public key retrieved from Rekor is not an ECDSA key")
 	}
-	fmt.Println(fi[0].Name())
+	return ed, nil
 }
 
 func TestSignedEntryTimestamp(t *testing.T) {
@@ -273,7 +266,7 @@ func TestSignedEntryTimestamp(t *testing.T) {
 		t.Fatal(err)
 	}
 	// get rekor's public key
-	rekorPubKey, err := util.PublicKey(ctx, rekorClient)
+	rekorPubKey, err := publicKeyFromRekorClient(ctx, rekorClient)
 	if err != nil {
 		t.Fatal(err)
 	}