Skip to content

Commit

Permalink
Remove KMS requiring metadata files (closes #4375)
Browse files Browse the repository at this point in the history
Signed-off-by: Keegan Witt <keeganwitt@gmail.com>
  • Loading branch information
keeganwitt committed Nov 28, 2023
1 parent 31425ca commit 22f1702
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 46 deletions.
15 changes: 8 additions & 7 deletions doc/plugin_server_keymanager_aws_kms.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ The `aws_kms` key manager plugin leverages the AWS Key Management Service (KMS)

The plugin accepts the following configuration options:

| Key | Type | Required | Description | Default |
|-------------------|--------|---------------------------------------|-------------------------------------------------------------------------------|---------------------------------------------------------|
| access_key_id | string | see [AWS KMS Access](#aws-kms-access) | The Access Key Id used to authenticate to KMS | Value of the AWS_ACCESS_KEY_ID environment variable |
| secret_access_key | string | see [AWS KMS Access](#aws-kms-access) | The Secret Access Key used to authenticate to KMS | Value of the AWS_SECRET_ACCESS_KEY environment variable |
| region | string | yes | The region where the keys will be stored | |
| key_metadata_file | string | yes | A file path location where information about generated keys will be persisted | |
| key_policy_file | string | no | A file path location to a custom key policy in JSON format | "" |
| Key | Type | Required | Description | Default |
|-------------------|--------|---------------------------------------|-----------------------------------------------------------------------------------------|---------------------------------------------------------|
| access_key_id | string | see [AWS KMS Access](#aws-kms-access) | The Access Key Id used to authenticate to KMS | Value of the AWS_ACCESS_KEY_ID environment variable |
| secret_access_key | string | see [AWS KMS Access](#aws-kms-access) | The Secret Access Key used to authenticate to KMS | Value of the AWS_SECRET_ACCESS_KEY environment variable |
| region | string | yes | The region where the keys will be stored | |
| key_metadata_file | string | yes | A file path location where information about generated keys will be persisted | |
| key_metadata | string | yes | A static identifier for the SPIRE server instance (used instead of `key_metadata_file`) | |
| key_policy_file | string | no | A file path location to a custom key policy in JSON format | "" |

### Alias and Key Management

Expand Down
19 changes: 10 additions & 9 deletions doc/plugin_server_keymanager_azure_key_vault.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ SPIRE.

The plugin accepts the following configuration options:

| Key | Type | Required | Description | Default |
|-------------------|---------|---------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|---------|
| key_metadata_file | string | yes | A file path location where key metadata used by the plugin will be persisted. See "[Management of keys](#management-of-keys)" for more information. | "" |
| key_vault_uri | string | Yes | The Key Vault URI where the keys managed by this plugin reside. | "" |
| use_msi | boolean | [Deprecated](#authenticating-to-azure) | Whether or not to use MSI to authenticate to Azure Key Vault. | false |
| subscription_id | string | [Optional](#authenticating-to-azure) | The subscription id. | "" |
| app_id | string | [Optional](#authenticating-to-azure) | The application id. | "" |
| app_secret | string | [Optional](#authenticating-to-azure) | The application secret. | "" |
| tenant_id | string | [Optional](#authenticating-to-azure) | The tenant id. | "" |
| Key | Type | Required | Description | Default |
|-------------------|---------|----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|---------|
| key_metadata_file | string | yes | A file path location where key metadata used by the plugin will be persisted. See "[Management of keys](#management-of-keys)" for more information. | "" |
| key_metadata_file | string | yes | A static identifier for the SPIRE server instance (used instead of `key_metadata_file`) | "" |
| key_vault_uri | string | Yes | The Key Vault URI where the keys managed by this plugin reside. | "" |
| use_msi | boolean | [Deprecated](#authenticating-to-azure) | Whether or not to use MSI to authenticate to Azure Key Vault. | false |
| subscription_id | string | [Optional](#authenticating-to-azure) | The subscription id. | "" |
| app_id | string | [Optional](#authenticating-to-azure) | The application id. | "" |
| app_secret | string | [Optional](#authenticating-to-azure) | The application secret. | "" |
| tenant_id | string | [Optional](#authenticating-to-azure) | The tenant id. | "" |

### Authenticating to Azure

Expand Down
13 changes: 7 additions & 6 deletions doc/plugin_server_keymanager_gcp_kms.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ SPIRE.

The plugin accepts the following configuration options:

| Key | Type | Required | Description | Default |
| --- | ---- | -------- | ----------- | ------- |
| key_policy_file | string | no | A file path location to a custom [IAM Policy (v3)](https://cloud.google.com/pubsub/docs/reference/rpc/google.iam.v1#google.iam.v1.Policy) in JSON format to be attached to created CryptoKeys. | "" |
| key_metadata_file | string | yes | A file path location where key metadata used by the plugin will be persisted. See "[Management of keys](#management-of-keys)" for more information. | "" |
| key_ring | string | yes | Resource ID of the key ring where the keys managed by this plugin reside, in the format projects/\*/locations/\*/keyRings/\* | "" |
| service_account_file | string | no | Path to the service account file used to authenticate with the Cloud KMS API. | Value of `GOOGLE_APPLICATION_CREDENTIALS` environment variable. |
| Key | Type | Required | Description | Default |
|----------------------|--------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
| key_policy_file | string | no | A file path location to a custom [IAM Policy (v3)](https://cloud.google.com/pubsub/docs/reference/rpc/google.iam.v1#google.iam.v1.Policy) in JSON format to be attached to created CryptoKeys. | "" |
| key_metadata_file | string | yes | A file path location where key metadata used by the plugin will be persisted. See "[Management of keys](#management-of-keys)" for more information. | "" |
| key_metadata_file | string | yes | A static identifier for the SPIRE server instance (used instead of `key_metadata_file`) | "" |
| key_ring | string | yes | Resource ID of the key ring where the keys managed by this plugin reside, in the format projects/\*/locations/\*/keyRings/\* | "" |
| service_account_file | string | no | Path to the service account file used to authenticate with the Cloud KMS API. | Value of `GOOGLE_APPLICATION_CREDENTIALS` environment variable. |

### Authenticating with the Cloud KMS API

Expand Down
18 changes: 11 additions & 7 deletions pkg/server/plugin/keymanager/awskms/awskms.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ type Config struct {
SecretAccessKey string `hcl:"secret_access_key" json:"secret_access_key"`
Region string `hcl:"region" json:"region"`
KeyMetadataFile string `hcl:"key_metadata_file" json:"key_metadata_file"`
KeyMetadata string `hcl:"key_metadata" json:"key_metadata"`
KeyPolicyFile string `hcl:"key_policy_file" json:"key_policy_file"`
}

Expand Down Expand Up @@ -131,11 +132,14 @@ func (p *Plugin) Configure(ctx context.Context, req *configv1.ConfigureRequest)
return nil, err
}

serverID, err := loadServerID(config.KeyMetadataFile)
if err != nil {
return nil, err
var serverID = config.KeyMetadata
if config.KeyMetadata == "" {
serverID, err := getOrCreateServerID(config.KeyMetadataFile)
if err != nil {
return nil, err
}
p.log.Debug("Loaded server id", "server_id", serverID)
}
p.log.Debug("Loaded server id", "server_id", serverID)

if config.KeyPolicyFile != "" {
policyBytes, err := os.ReadFile(config.KeyPolicyFile)
Expand Down Expand Up @@ -832,8 +836,8 @@ func parseAndValidateConfig(c string) (*Config, error) {
return nil, status.Error(codes.InvalidArgument, "configuration is missing a region")
}

if config.KeyMetadataFile == "" {
return nil, status.Error(codes.InvalidArgument, "configuration is missing server id file path")
if config.KeyMetadataFile == "" && config.KeyMetadata == "" {
return nil, status.Error(codes.InvalidArgument, "configuration requires server id or server id file path")
}

return config, nil
Expand Down Expand Up @@ -923,7 +927,7 @@ func min(x, y time.Duration) time.Duration {
return y
}

func loadServerID(idPath string) (string, error) {
func getOrCreateServerID(idPath string) (string, error) {
// get id from path
data, err := os.ReadFile(idPath)
switch {
Expand Down
4 changes: 2 additions & 2 deletions pkg/server/plugin/keymanager/awskms/awskms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func TestKeyManagerContract(t *testing.T) {
func(aws.Config) (stsClient, error) { return fakeSTSClient, nil },
)
km := new(keymanager.V1)
keyMetadataFile := filepath.Join(dir, "metadata.json")
keyMetadataFile := filepath.Join(dir, "metadata")
if isWindows {
keyMetadataFile = filepath.ToSlash(keyMetadataFile)
}
Expand Down Expand Up @@ -226,7 +226,7 @@ func TestConfigure(t *testing.T) {
{
name: "missing server id file path",
configureRequest: configureRequestWithVars("access_key_id", "secret_access_key", "region", "", ""),
err: "configuration is missing server id file path",
err: "configuration requires server id or server id file path",
code: codes.InvalidArgument,
},
{
Expand Down
16 changes: 10 additions & 6 deletions pkg/server/plugin/keymanager/azurekeyvault/azure_key_vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ type pluginHooks struct {
// Config provides configuration context for the plugin.
type Config struct {
KeyMetadataFile string `hcl:"key_metadata_file" json:"key_metadata_file"`
KeyMetadata string `hcl:"key_metadata" json:"key_metadata"`
KeyVaultURI string `hcl:"key_vault_uri" json:"key_vault_uri"`
TenantID string `hcl:"tenant_id" json:"tenant_id"`
SubscriptionID string `hcl:"subscription_id" json:"subscription_id"`
Expand Down Expand Up @@ -139,11 +140,14 @@ func (p *Plugin) Configure(ctx context.Context, req *configv1.ConfigureRequest)
return nil, err
}

serverID, err := getOrCreateServerID(config.KeyMetadataFile)
if err != nil {
return nil, err
var serverID = config.KeyMetadata
if config.KeyMetadata == "" {
serverID, err := getOrCreateServerID(config.KeyMetadataFile)
if err != nil {
return nil, err
}
p.log.Debug("Loaded server ID", "server_id", serverID)
}
p.log.Debug("Loaded server ID", "server_id", serverID)

var client cloudKeyManagementService

Expand Down Expand Up @@ -685,8 +689,8 @@ func parseAndValidateConfig(c string) (*Config, error) {
return nil, status.Error(codes.InvalidArgument, "configuration is missing the Key Vault URI")
}

if config.KeyMetadataFile == "" {
return nil, status.Error(codes.InvalidArgument, "configuration is missing server ID file path")
if config.KeyMetadataFile == "" && config.KeyMetadata == "" {
return nil, status.Error(codes.InvalidArgument, "configuration requires server id or server id file path")
}

return config, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func TestConfigure(t *testing.T) {
{
name: "missing key metadata file",
configureRequest: configureRequestWithVars("", validKeyVaultURI, "", "", "", validAppSecret, "true"),
err: "configuration is missing server ID file path",
err: "configuration requires server id or server id file path",
code: codes.InvalidArgument,
},
{
Expand Down Expand Up @@ -149,7 +149,7 @@ func TestConfigure(t *testing.T) {
{
name: "missing server id file path",
configureRequest: configureRequestWithVars("", validKeyVaultURI, validTenantID, validSubscriptionID, validAppID, validAppSecret, "false"),
err: "configuration is missing server ID file path",
err: "configuration requires server id or server id file path",
code: codes.InvalidArgument,
},
{
Expand Down
19 changes: 13 additions & 6 deletions pkg/server/plugin/keymanager/gcpkms/gcpkms.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ type Config struct {
// File path location where key metadata used by the plugin is persisted.
KeyMetadataFile string `hcl:"key_metadata_file" json:"key_metadata_file"`

// Key metadata used by the plugin.
KeyMetadata string `hcl:"key_metadata" json:"key_metadata"`

// File path location to a custom IAM Policy (v3) that will be set to
// created CryptoKeys.
KeyPolicyFile string `hcl:"key_policy_file" json:"key_policy_file"`
Expand Down Expand Up @@ -167,11 +170,15 @@ func (p *Plugin) Configure(ctx context.Context, req *configv1.ConfigureRequest)
return nil, err
}

serverID, err := getOrCreateServerID(config.KeyMetadataFile)
if err != nil {
return nil, err
var serverID = config.KeyMetadata
if config.KeyMetadata == "" {
serverID, err := getOrCreateServerID(config.KeyMetadataFile)
if err != nil {
return nil, err
}
p.log.Debug("Loaded server ID", "server_id", serverID)
}
p.log.Debug("Loaded server ID", "server_id", serverID)

var customPolicy *iam.Policy3
if config.KeyPolicyFile != "" {
if customPolicy, err = parsePolicyFile(config.KeyPolicyFile); err != nil {
Expand Down Expand Up @@ -1103,8 +1110,8 @@ func parseAndValidateConfig(c string) (*Config, error) {
return nil, status.Error(codes.InvalidArgument, "configuration is missing the key ring")
}

if config.KeyMetadataFile == "" {
return nil, status.Error(codes.InvalidArgument, "configuration is missing server ID file path")
if config.KeyMetadataFile == "" && config.KeyMetadata == "" {
return nil, status.Error(codes.InvalidArgument, "configuration requires server id or server id file path")
}

return config, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/plugin/keymanager/gcpkms/gcpkms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func TestConfigure(t *testing.T) {
config: &Config{
KeyRing: validKeyRing,
},
expectMsg: "configuration is missing server ID file path",
expectMsg: "configuration requires server id or server id file path",
expectCode: codes.InvalidArgument,
},
{
Expand Down

0 comments on commit 22f1702

Please sign in to comment.