Repository: google/exposure-notifications-server
Pull request #645 (2020-06-18 13:48:05)

Make secrets and key management public
/assign @mikehelmick 

google-oss-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/google/exposure-notifications-server/pull/645#" title="Author self-approved">sethvargo</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=google%2Fexposure-notifications-server).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/google/exposure-notifications-server/blob/master/OWNERS)~~ [sethvargo]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
google-oss-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/google/exposure-notifications-server/pull/645#pullrequestreview-433409997" title="Approved">mikehelmick</a>*, *<a href="https://github.com/google/exposure-notifications-server/pull/645#" title="Author self-approved">sethvargo</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=google%2Fexposure-notifications-server).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/google/exposure-notifications-server/blob/master/OWNERS)~~ [mikehelmick,sethvargo]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/internal/admin/config.go b/internal/admin/config.go
index 78fccde..024a754 100644
--- a/internal/admin/config.go
+++ b/internal/admin/config.go
@@ -23,10 +23,10 @@ import (
 	"net/http"
 
 	"github.com/google/exposure-notifications-server/internal/database"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/keys"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 var _ setup.BlobstoreConfigProvider = (*Config)(nil)
@@ -36,7 +36,7 @@ var _ setup.SecretManagerConfigProvider = (*Config)(nil)
 
 type Config struct {
 	Database      database.Config
-	KeyManager    signing.Config
+	KeyManager    keys.Config
 	SecretManager secrets.Config
 	Storage       storage.Config
 
@@ -50,7 +50,7 @@ func (c *Config) DatabaseConfig() *database.Config {
 	return &c.Database
 }
 
-func (c *Config) KeyManagerConfig() *signing.Config {
+func (c *Config) KeyManagerConfig() *keys.Config {
 	return &c.KeyManager
 }
 
diff --git a/internal/authorizedapp/database/authorized_app.go b/internal/authorizedapp/database/authorized_app.go
index 87254da..598b805 100644
--- a/internal/authorizedapp/database/authorized_app.go
+++ b/internal/authorizedapp/database/authorized_app.go
@@ -23,7 +23,7 @@ import (
 
 	"github.com/google/exposure-notifications-server/internal/authorizedapp/model"
 	"github.com/google/exposure-notifications-server/internal/database"
-	"github.com/google/exposure-notifications-server/internal/secrets"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 	pgx "github.com/jackc/pgx/v4"
 )
 
diff --git a/internal/authorizedapp/database_provider.go b/internal/authorizedapp/database_provider.go
index 35e36ea..676ca9a 100644
--- a/internal/authorizedapp/database_provider.go
+++ b/internal/authorizedapp/database_provider.go
@@ -27,7 +27,7 @@ import (
 	"github.com/google/exposure-notifications-server/pkg/cache"
 
 	"github.com/google/exposure-notifications-server/internal/logging"
-	"github.com/google/exposure-notifications-server/internal/secrets"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 // Compile-time check to assert implementation.
diff --git a/internal/cleanup/config.go b/internal/cleanup/config.go
index 08abc5d..6eefd5c 100644
--- a/internal/cleanup/config.go
+++ b/internal/cleanup/config.go
@@ -19,9 +19,9 @@ import (
 
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 // Compile-time check to assert this config matches requirements.
diff --git a/internal/debugger/config.go b/internal/debugger/config.go
index 6953b79..8de29ab 100644
--- a/internal/debugger/config.go
+++ b/internal/debugger/config.go
@@ -17,10 +17,10 @@ package debugger
 import (
 	"github.com/google/exposure-notifications-server/internal/authorizedapp"
 	"github.com/google/exposure-notifications-server/internal/database"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/keys"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 // Compile-time check to assert this config matches requirements.
@@ -34,7 +34,7 @@ var _ setup.SecretManagerConfigProvider = (*Config)(nil)
 type Config struct {
 	AuthorizedApp authorizedapp.Config
 	Database      database.Config
-	KeyManager    signing.Config
+	KeyManager    keys.Config
 	SecretManager secrets.Config
 	Storage       storage.Config
 
@@ -53,7 +53,7 @@ func (c *Config) DatabaseConfig() *database.Config {
 	return &c.Database
 }
 
-func (c *Config) KeyManagerConfig() *signing.Config {
+func (c *Config) KeyManagerConfig() *keys.Config {
 	return &c.KeyManager
 }
 
diff --git a/internal/export/config.go b/internal/export/config.go
index cceb976..aefffac 100644
--- a/internal/export/config.go
+++ b/internal/export/config.go
@@ -20,10 +20,10 @@ import (
 
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/keys"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 // Compile-time check to assert this config matches requirements.
@@ -37,7 +37,7 @@ var _ setup.ObservabilityExporterConfigProvider = (*Config)(nil)
 // the export components.
 type Config struct {
 	Database              database.Config
-	KeyManager            signing.Config
+	KeyManager            keys.Config
 	SecretManager         secrets.Config
 	Storage               storage.Config
 	ObservabilityExporter observability.Config
@@ -61,7 +61,7 @@ func (c *Config) DatabaseConfig() *database.Config {
 	return &c.Database
 }
 
-func (c *Config) KeyManagerConfig() *signing.Config {
+func (c *Config) KeyManagerConfig() *keys.Config {
 	return &c.KeyManager
 }
 
diff --git a/internal/federationin/config.go b/internal/federationin/config.go
index cadfc68..e7eb2e8 100644
--- a/internal/federationin/config.go
+++ b/internal/federationin/config.go
@@ -20,8 +20,8 @@ import (
 
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 const (
diff --git a/internal/federationout/config.go b/internal/federationout/config.go
index f02ac23..8329d97 100644
--- a/internal/federationout/config.go
+++ b/internal/federationout/config.go
@@ -19,8 +19,8 @@ import (
 
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 // Compile-time check to assert this config matches requirements.
diff --git a/internal/generate/config.go b/internal/generate/config.go
index 7db3d3a..2dc626a 100644
--- a/internal/generate/config.go
+++ b/internal/generate/config.go
@@ -20,8 +20,8 @@ import (
 
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 // Compile-time check to assert this config matches requirements.
diff --git a/internal/publish/config.go b/internal/publish/config.go
index d69cfec..df50a12 100644
--- a/internal/publish/config.go
+++ b/internal/publish/config.go
@@ -21,9 +21,9 @@ import (
 	"github.com/google/exposure-notifications-server/internal/authorizedapp"
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
 	"github.com/google/exposure-notifications-server/internal/verification"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 // Compile-time check to assert this config matches requirements.
diff --git a/internal/serverenv/env.go b/internal/serverenv/env.go
index 9632d1c..3928b9b 100644
--- a/internal/serverenv/env.go
+++ b/internal/serverenv/env.go
@@ -24,9 +24,9 @@ import (
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/metrics"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/keys"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 // ExporterFunc defines a factory function for creating a context aware metrics exporter.
@@ -38,7 +38,7 @@ type ServerEnv struct {
 	blobstore             storage.Blobstore
 	database              *database.DB
 	exporter              metrics.ExporterFromContext
-	keyManager            signing.KeyManager
+	keyManager            keys.KeyManager
 	secretManager         secrets.SecretManager
 	observabilityExporter observability.Exporter
 }
@@ -95,7 +95,7 @@ func WithSecretManager(sm secrets.SecretManager) Option {
 }
 
 // WithKeyManager creates an Option to install a specific KeyManager to use for signing requests.
-func WithKeyManager(km signing.KeyManager) Option {
+func WithKeyManager(km keys.KeyManager) Option {
 	return func(s *ServerEnv) *ServerEnv {
 		s.keyManager = km
 		return s
@@ -122,7 +122,7 @@ func (s *ServerEnv) SecretManager() secrets.SecretManager {
 	return s.secretManager
 }
 
-func (s *ServerEnv) KeyManager() signing.KeyManager {
+func (s *ServerEnv) KeyManager() keys.KeyManager {
 	return s.keyManager
 }
 
diff --git a/internal/setup/setup.go b/internal/setup/setup.go
index b8765b5..0461eb4 100644
--- a/internal/setup/setup.go
+++ b/internal/setup/setup.go
@@ -24,10 +24,10 @@ import (
 	"github.com/google/exposure-notifications-server/internal/logging"
 	"github.com/google/exposure-notifications-server/internal/metrics"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/serverenv"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/keys"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 	"github.com/sethvargo/go-envconfig/pkg/envconfig"
 )
 
@@ -52,7 +52,7 @@ type DatabaseConfigProvider interface {
 // KeyManagerConfigProvider is a marker interface indicating the key manager
 // should be installed.
 type KeyManagerConfigProvider interface {
-	KeyManagerConfig() *signing.Config
+	KeyManagerConfig() *keys.Config
 }
 
 // ObservabilityExporterConfigProvider signals that the config knows how to configure an
@@ -132,7 +132,7 @@ func SetupWith(ctx context.Context, config interface{}, l envconfig.Lookuper) (*
 	}
 
 	// Load the key manager.
-	var km signing.KeyManager
+	var km keys.KeyManager
 	if provider, ok := config.(KeyManagerConfigProvider); ok {
 		logger.Info("configuring key manager")
 
@@ -142,7 +142,7 @@ func SetupWith(ctx context.Context, config interface{}, l envconfig.Lookuper) (*
 		}
 
 		var err error
-		km, err = signing.KeyManagerFor(ctx, kmConfig.KeyManagerType)
+		km, err = keys.KeyManagerFor(ctx, kmConfig.KeyManagerType)
 		if err != nil {
 			return nil, fmt.Errorf("unable to connect to key manager: %w", err)
 		}
diff --git a/internal/signing/aws_kms.go b/pkg/keys/aws_kms.go
similarity index 93%
rename from internal/signing/aws_kms.go
rename to pkg/keys/aws_kms.go
index 692aaf0..f54efc9 100644
--- a/internal/signing/aws_kms.go
+++ b/pkg/keys/aws_kms.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package signing
+package keys
 
 import (
 	"context"
@@ -27,7 +27,7 @@ import (
 // Compile-time check to verify implements interface.
 var _ KeyManager = (*AWSKMS)(nil)
 
-// AWSKMS implements the signing.KeyManager interface and can be used to sign
+// AWSKMS implements the keys.KeyManager interface and can be used to sign
 // export files using AWS KMS.
 type AWSKMS struct {
 	svc *kms.KMS
diff --git a/internal/signing/azure_keyvault.go b/pkg/keys/azure_keyvault.go
similarity index 98%
rename from internal/signing/azure_keyvault.go
rename to pkg/keys/azure_keyvault.go
index 244cbfb..fec18f6 100644
--- a/internal/signing/azure_keyvault.go
+++ b/pkg/keys/azure_keyvault.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package signing
+package keys
 
 import (
 	"context"
@@ -36,7 +36,7 @@ import (
 var _ KeyManager = (*AzureKeyVault)(nil)
 var _ crypto.Signer = (*AzureKeyVaultSigner)(nil)
 
-// AzureKeyVault implements the signing.KeyManager interface and can be used to
+// AzureKeyVault implements the keys.KeyManager interface and can be used to
 // sign export files.
 type AzureKeyVault struct {
 	client *keyvault.BaseClient
diff --git a/internal/signing/config.go b/pkg/keys/config.go
similarity index 98%
rename from internal/signing/config.go
rename to pkg/keys/config.go
index ab644dd..bd79bd6 100644
--- a/internal/signing/config.go
+++ b/pkg/keys/config.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package signing
+package keys
 
 // KeyManagerType defines a specific key manager.
 type KeyManagerType string
diff --git a/internal/signing/google_cloud_kms.go b/pkg/keys/google_cloud_kms.go
similarity index 92%
rename from internal/signing/google_cloud_kms.go
rename to pkg/keys/google_cloud_kms.go
index 74abb4f..6298e77 100644
--- a/internal/signing/google_cloud_kms.go
+++ b/pkg/keys/google_cloud_kms.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package signing
+package keys
 
 import (
 	"context"
@@ -25,7 +25,7 @@ import (
 // Compile-time check to verify implements interface.
 var _ KeyManager = (*GoogleCloudKMS)(nil)
 
-// GoogleCloudKMS implements the signing.KeyManager interface and can be used to sign
+// GoogleCloudKMS implements the keys.KeyManager interface and can be used to sign
 // export files.
 type GoogleCloudKMS struct {
 	client *kms.KeyManagementClient
diff --git a/internal/signing/hashicorp_vault.go b/pkg/keys/hashicorp_vault.go
similarity index 98%
rename from internal/signing/hashicorp_vault.go
rename to pkg/keys/hashicorp_vault.go
index 33bcd65..934bc7b 100644
--- a/internal/signing/hashicorp_vault.go
+++ b/pkg/keys/hashicorp_vault.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package signing
+package keys
 
 import (
 	"context"
@@ -34,7 +34,7 @@ import (
 var _ KeyManager = (*HashiCorpVault)(nil)
 var _ crypto.Signer = (*HashiCorpVaultSigner)(nil)
 
-// HashiCorpVault implements the signing.KeyManager interface and can be used to
+// HashiCorpVault implements the keys.KeyManager interface and can be used to
 // sign export files.
 type HashiCorpVault struct {
 	client *vaultapi.Client
diff --git a/internal/signing/signing.go b/pkg/keys/keys.go
similarity index 80%
rename from internal/signing/signing.go
rename to pkg/keys/keys.go
index e820bb7..dc37524 100644
--- a/internal/signing/signing.go
+++ b/pkg/keys/keys.go
@@ -12,8 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Package signing defines the interface to and implementation of signing
-package signing
+// Package keys defines the interface to and implementation of key management
+// operations.
+//
+// Although exported, this package is non intended for general consumption. It
+// is a shared dependency between multiple exposure notifications projects. We
+// cannot guarantee that there won't be breaking changes in the future.
+package keys
 
 import (
 	"context"
diff --git a/internal/signing/noop.go b/pkg/keys/noop.go
similarity index 98%
rename from internal/signing/noop.go
rename to pkg/keys/noop.go
index c3ce545..55e5d64 100644
--- a/internal/signing/noop.go
+++ b/pkg/keys/noop.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package signing
+package keys
 
 import (
 	"context"
diff --git a/internal/secrets/aws_secrets_manager.go b/pkg/secrets/aws_secrets_manager.go
similarity index 100%
rename from internal/secrets/aws_secrets_manager.go
rename to pkg/secrets/aws_secrets_manager.go
diff --git a/internal/secrets/azure_keyvault.go b/pkg/secrets/azure_keyvault.go
similarity index 100%
rename from internal/secrets/azure_keyvault.go
rename to pkg/secrets/azure_keyvault.go
diff --git a/internal/secrets/cacher.go b/pkg/secrets/cacher.go
similarity index 100%
rename from internal/secrets/cacher.go
rename to pkg/secrets/cacher.go
diff --git a/internal/secrets/cacher_test.go b/pkg/secrets/cacher_test.go
similarity index 100%
rename from internal/secrets/cacher_test.go
rename to pkg/secrets/cacher_test.go
diff --git a/internal/secrets/config.go b/pkg/secrets/config.go
similarity index 100%
rename from internal/secrets/config.go
rename to pkg/secrets/config.go
diff --git a/internal/secrets/google_secret_manager.go b/pkg/secrets/google_secret_manager.go
similarity index 100%
rename from internal/secrets/google_secret_manager.go
rename to pkg/secrets/google_secret_manager.go
diff --git a/internal/secrets/hashicorp_vault.go b/pkg/secrets/hashicorp_vault.go
similarity index 100%
rename from internal/secrets/hashicorp_vault.go
rename to pkg/secrets/hashicorp_vault.go
diff --git a/internal/secrets/hashicorp_vault_test.go b/pkg/secrets/hashicorp_vault_test.go
similarity index 100%
rename from internal/secrets/hashicorp_vault_test.go
rename to pkg/secrets/hashicorp_vault_test.go
diff --git a/internal/secrets/noop.go b/pkg/secrets/noop.go
similarity index 100%
rename from internal/secrets/noop.go
rename to pkg/secrets/noop.go
diff --git a/internal/secrets/resolver.go b/pkg/secrets/resolver.go
similarity index 100%
rename from internal/secrets/resolver.go
rename to pkg/secrets/resolver.go
diff --git a/internal/secrets/secrets.go b/pkg/secrets/secrets.go
similarity index 87%
rename from internal/secrets/secrets.go
rename to pkg/secrets/secrets.go
index d26647d..6bfa61f 100644
--- a/internal/secrets/secrets.go
+++ b/pkg/secrets/secrets.go
@@ -13,7 +13,11 @@
 // limitations under the License.
 
 // Package secrets defines a minimum abstract interface for a secret manager.
-// Allows for a different implementation to be bound within the servernv.ServeEnv
+// Allows for a different implementation to be bound within the ServeEnv.
+//
+// Although exported, this package is non intended for general consumption. It
+// is a shared dependency between multiple exposure notifications projects. We
+// cannot guarantee that there won't be breaking changes in the future.
 package secrets
 
 import (
diff --git a/tools/example-verification-signing/main.go b/tools/example-verification-signing/main.go
index f13475e..23c7a3b 100644
--- a/tools/example-verification-signing/main.go
+++ b/tools/example-verification-signing/main.go
@@ -32,8 +32,8 @@ import (
 	"time"
 
 	"github.com/google/exposure-notifications-server/internal/setup"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/pkg/api/v1alpha1"
+	"github.com/google/exposure-notifications-server/pkg/keys"
 
 	"github.com/dgrijalva/jwt-go"
 	"github.com/gin-gonic/gin"
@@ -52,7 +52,7 @@ type VerifyResponse struct {
 }
 
 type config struct {
-	KeyManager signing.Config
+	KeyManager keys.Config
 
 	SigningKey string `env:"SIGNING_KEY,required"`
 	KeyVersion string `env:"KEY_VERSION, default=1"`
@@ -63,7 +63,7 @@ type config struct {
 	ValidDuration time.Duration `env:"VALID_DURATION, default=5m"`
 }
 
-func (c *config) KeyManagerConfig() *signing.Config {
+func (c *config) KeyManagerConfig() *keys.Config {
 	return &c.KeyManager
 }
 


Test patch:
diff --git a/internal/export/server_test.go b/internal/export/server_test.go
index eb66493..5f0044a 100644
--- a/internal/export/server_test.go
+++ b/internal/export/server_test.go
@@ -21,14 +21,14 @@ import (
 
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/serverenv"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/keys"
 )
 
 // TestNewServer tests NewServer().
 func TestNewServer(t *testing.T) {
 	emptyStorage := &storage.GoogleCloudStorage{}
-	emptyKMS := &signing.GoogleCloudKMS{}
+	emptyKMS := &keys.GoogleCloudKMS{}
 	emptyDB := &database.DB{}
 	ctx := context.Background()
 
diff --git a/internal/integration/integration_test.go b/internal/integration/integration_test.go
index 09d8b60..4bc154b 100644
--- a/internal/integration/integration_test.go
+++ b/internal/integration/integration_test.go
@@ -26,11 +26,11 @@ import (
 	"github.com/google/exposure-notifications-server/internal/export"
 	"github.com/google/exposure-notifications-server/internal/federationin"
 	"github.com/google/exposure-notifications-server/internal/publish"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/server"
 	"github.com/google/exposure-notifications-server/internal/serverenv"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/keys"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 )
 
 func testServer(tb testing.TB) (*serverenv.ServerEnv, *http.Client) {
@@ -50,7 +50,7 @@ func testServer(tb testing.TB) (*serverenv.ServerEnv, *http.Client) {
 
 	db := database.NewTestDatabase(tb)
 
-	km, err := signing.NewNoop(ctx)
+	km, err := keys.NewNoop(ctx)
 	if err != nil {
 		tb.Fatal(err)
 	}
diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go
index 20adb85..440a306 100644
--- a/internal/setup/setup_test.go
+++ b/internal/setup/setup_test.go
@@ -25,10 +25,10 @@ import (
 	"github.com/google/exposure-notifications-server/internal/authorizedapp"
 	"github.com/google/exposure-notifications-server/internal/database"
 	"github.com/google/exposure-notifications-server/internal/observability"
-	"github.com/google/exposure-notifications-server/internal/secrets"
 	"github.com/google/exposure-notifications-server/internal/setup"
-	"github.com/google/exposure-notifications-server/internal/signing"
 	"github.com/google/exposure-notifications-server/internal/storage"
+	"github.com/google/exposure-notifications-server/pkg/keys"
+	"github.com/google/exposure-notifications-server/pkg/secrets"
 	"github.com/sethvargo/go-envconfig/pkg/envconfig"
 )
 
@@ -62,9 +62,9 @@ func (t *testConfig) DatabaseConfig() *database.Config {
 	return t.Database
 }
 
-func (t *testConfig) KeyManagerConfig() *signing.Config {
-	return &signing.Config{
-		KeyManagerType: signing.KeyManagerType("NOOP"),
+func (t *testConfig) KeyManagerConfig() *keys.Config {
+	return &keys.Config{
+		KeyManagerType: keys.KeyManagerType("NOOP"),
 	}
 }
 
@@ -197,7 +197,7 @@ func TestSetupWith(t *testing.T) {
 			t.Errorf("expected key manager to exist")
 		}
 
-		if _, ok := km.(*signing.Noop); !ok {
+		if _, ok := km.(*keys.Noop); !ok {
 			t.Errorf("expected %T to be Noop", km)
 		}
 	})
diff --git a/internal/signing/hashicorp_vault_test.go b/pkg/keys/hashicorp_vault_test.go
similarity index 99%
rename from internal/signing/hashicorp_vault_test.go
rename to pkg/keys/hashicorp_vault_test.go
index e83447e..9f0cdac 100644
--- a/internal/signing/hashicorp_vault_test.go
+++ b/pkg/keys/hashicorp_vault_test.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package signing
+package keys
 
 import (
 	"context"