From 650cf9a558bc857d8af7c48c8efc23ac079e2925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Strna=CC=81dek?= Date: Thu, 27 Nov 2025 08:34:20 +0100 Subject: [PATCH] AWS configuration from IAM --- Makefile | 20 ++++- cmd/kms_priv_key_importer/main.go | 70 ++------------- internal/api/credentials.go | 1 + internal/config/config.go | 24 ++--- internal/config/config_test.go | 3 - internal/kms/aws.go | 89 +++++++++++++++++++ internal/kms/aws_kms_eth_key_provider.go | 34 ++----- internal/kms/aws_kms_eth_key_provider_test.go | 35 ++------ internal/kms/aws_secret_storage_provider.go | 33 ++----- .../kms/aws_secret_storage_provider_test.go | 35 ++------ internal/kms/kms.go | 42 ++------- internal/kms/local_bjj_key_provider_test.go | 42 ++------- .../kms/local_ed25519_key_provider_test.go | 35 ++------ internal/kms/local_eth_key_provider_test.go | 35 ++------ internal/kms/main_test.go | 8 ++ 15 files changed, 173 insertions(+), 333 deletions(-) create mode 100644 internal/kms/aws.go diff --git a/Makefile b/Makefile index d5adc9dbb..68c55ba23 100644 --- a/Makefile +++ b/Makefile @@ -22,8 +22,20 @@ ISSUER_KMS_BJJ_PROVIDER := ${ISSUER_KMS_BJJ_PROVIDER} ISSUER_KMS_SOL_PROVIDER := ${ISSUER_KMS_SOL_PROVIDER} aws_access_key := ${ISSUER_KMS_AWS_ACCESS_KEY} +ifeq ($(aws_access_key),) + aws_access_key := ${AWS_ACCESS_KEY_ID} +endif + aws_secret_key := ${ISSUER_KMS_AWS_SECRET_KEY} +ifeq ($(aws_secret_key),) + aws_secret_key := ${AWS_SECRET_ACCESS_KEY} +endif + aws_region := ${ISSUER_KMS_AWS_REGION} +ifeq ($(aws_region),) + aws_region := ${AWS_REGION} +endif + aws_endpoint := ${ISSUER_KMS_AWS_URL} ISSUER_RESOLVER_FILE := ${ISSUER_RESOLVER_FILE} @@ -89,16 +101,16 @@ endif ifeq ($(ISSUER_KMS_BJJ_PROVIDER), vault) $(DOCKER_COMPOSE_INFRA_CMD) up -d vault endif -ifeq ($(ISSUER_KMS_ETH_PROVIDER)$(ISSUER_KMS_AWS_REGION), aws-smlocal) +ifeq ($(ISSUER_KMS_ETH_PROVIDER)$(aws_region), aws-smlocal) $(DOCKER_COMPOSE_INFRA_CMD) up -d localstack endif -ifeq ($(ISSUER_KMS_ETH_PROVIDER)$(ISSUER_KMS_AWS_REGION), aws-kmslocal) +ifeq ($(ISSUER_KMS_ETH_PROVIDER)$(aws_region), aws-kmslocal) $(DOCKER_COMPOSE_INFRA_CMD) up -d localstack endif -ifeq ($(ISSUER_KMS_BJJ_PROVIDER)$(ISSUER_KMS_AWS_REGION), aws-smlocal) +ifeq ($(ISSUER_KMS_BJJ_PROVIDER)$(aws_region), aws-smlocal) $(DOCKER_COMPOSE_INFRA_CMD) up -d localstack endif -ifeq ($(ISSUER_KMS_SOL_PROVIDER)$(ISSUER_KMS_AWS_REGION), aws-smlocal) +ifeq ($(ISSUER_KMS_SOL_PROVIDER)$(aws_region), aws-smlocal) $(DOCKER_COMPOSE_INFRA_CMD) up -d localstack endif diff --git a/cmd/kms_priv_key_importer/main.go b/cmd/kms_priv_key_importer/main.go index ca9629d8d..50379fd0b 100644 --- a/cmd/kms_priv_key_importer/main.go +++ b/cmd/kms_priv_key_importer/main.go @@ -11,11 +11,8 @@ import ( "path" "path/filepath" "strconv" - "strings" "github.com/aws/aws-sdk-go-v2/aws" - awsconfig "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/credentials" awskms "github.com/aws/aws-sdk-go-v2/service/kms" "github.com/aws/aws-sdk-go-v2/service/kms/types" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" @@ -38,10 +35,6 @@ const ( issuerKeyStorePluginIden3MountPath = "ISSUER_KEY_STORE_PLUGIN_IDEN3_MOUNT_PATH" issuerVaultUserPassAuthEnabled = "ISSUER_VAULT_USERPASS_AUTH_ENABLED" issuerVaultUserPassAuthPasword = "ISSUER_VAULT_USERPASS_AUTH_PASSWORD" - awsAccessKey = "ISSUER_KMS_AWS_ACCESS_KEY" - awsSecretKey = "ISSUER_KMS_AWS_SECRET_KEY" - awsRegion = "ISSUER_KMS_AWS_REGION" - awsURL = "ISSUER_KMS_AWS_URL" jsonKeyPath = "key_path" jsonKeyType = "key_type" @@ -153,33 +146,11 @@ func main() { } if issuerKMSETHProviderToUse == config.AWSSM { - awsAccessKey := os.Getenv(awsAccessKey) - awsSecretKey := os.Getenv(awsSecretKey) - awsRegion := os.Getenv(awsRegion) - - if awsAccessKey == "" || awsSecretKey == "" || awsRegion == "" { - log.Error(ctx, "aws access key, aws secret key, or aws region is not set") - return - } - - cfg, err := awsconfig.LoadDefaultConfig(ctx, - awsconfig.WithRegion(awsRegion), - awsconfig.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(awsAccessKey, awsSecretKey, "")), - ) + secretManager, err := kms.AwsSecretsManager(ctx) if err != nil { - log.Error(ctx, "error loading AWSSM config", "err", err) + log.Error(ctx, "cannot initialize AWS Secrets Manager client", "err", err) return } - - var options []func(*secretsmanager.Options) - if strings.ToLower(awsRegion) == "local" { - awsURLEndpoint := os.Getenv(awsURL) - options = make([]func(*secretsmanager.Options), 1) - options[0] = func(o *secretsmanager.Options) { - o.BaseEndpoint = aws.String(awsURLEndpoint) - } - } - secretManager := secretsmanager.NewFromConfig(cfg, options...) secretName := base64.StdEncoding.EncodeToString([]byte(issuerPublishKeyPathVar)) material[jsonPrivateKey] = *fPrivateKey @@ -203,17 +174,7 @@ func main() { } if issuerKMSETHProviderToUse == config.AWSKMS { - awsAccessKey := os.Getenv(awsAccessKey) - awsSecretKey := os.Getenv(awsSecretKey) - awsRegion := os.Getenv(awsRegion) - awsURLEndpoint := os.Getenv(awsURL) - - if awsAccessKey == "" || awsSecretKey == "" || awsRegion == "" { - log.Error(ctx, "aws access key, aws secret key, or aws region is not set") - return - } - - keyId, err := createEmptyKey(ctx, awsAccessKey, awsSecretKey, awsRegion, awsURLEndpoint, issuerPublishKeyPathVar) + keyId, err := createEmptyKey(ctx, issuerPublishKeyPathVar) if err != nil { log.Error(ctx, "cannot create empty key", "err", err) return @@ -253,28 +214,13 @@ func validate(issuerKMSETHProviderToUse string, fPrivateKey *string, ctx context return nil } -// -//nolint:unused -func createEmptyKey(ctx context.Context, awsAccessKey, awsSecretKey, awsRegion string, awsURL string, privateKeyAlias string) (*string, error) { - cfg, err := awsconfig.LoadDefaultConfig( - ctx, - awsconfig.WithRegion(awsRegion), - awsconfig.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(awsAccessKey, awsSecretKey, "")), - ) +func createEmptyKey(ctx context.Context, privateKeyAlias string) (*string, error) { + kmsClient, err := kms.AwsKms(ctx) if err != nil { - log.Error(ctx, "cannot load aws config", "err", err) + log.Error(ctx, "cannot initialize AWS KMS client", "err", err) return nil, err } - var options []func(*awskms.Options) - if strings.ToLower(awsRegion) == "local" { - options = make([]func(*awskms.Options), 1) - options[0] = func(o *awskms.Options) { - o.BaseEndpoint = aws.String(awsURL) - } - } - - svc := awskms.NewFromConfig(cfg, options...) input := &awskms.CreateKeyInput{ KeySpec: types.KeySpecEccSecgP256k1, KeyUsage: types.KeyUsageTypeSignVerify, @@ -282,7 +228,7 @@ func createEmptyKey(ctx context.Context, awsAccessKey, awsSecretKey, awsRegion s Description: aws.String("imported key"), } - result, err := svc.CreateKey(ctx, input) + result, err := kmsClient.CreateKey(ctx, input) if err != nil { log.Error(ctx, "cannot create key", "err", err) return nil, err @@ -294,7 +240,7 @@ func createEmptyKey(ctx context.Context, awsAccessKey, awsSecretKey, awsRegion s TargetKeyId: result.KeyMetadata.Arn, } - _, err = svc.CreateAlias(ctx, inputAlias) + _, err = kmsClient.CreateAlias(ctx, inputAlias) if err != nil { return nil, fmt.Errorf("failed to create alias: %v", err) } diff --git a/internal/api/credentials.go b/internal/api/credentials.go index 0aea1fabc..6864c11ed 100644 --- a/internal/api/credentials.go +++ b/internal/api/credentials.go @@ -240,6 +240,7 @@ func (s *Server) GetCredentials(ctx context.Context, request GetCredentialsReque log.Error(ctx, "loading credentials", "err", err, "req", request) return GetCredentials500JSONResponse{N500JSONResponse{Message: err.Error()}}, nil } + response := make([]Credential, len(credentials)) var credentialToAdd Credential for i, credential := range credentials { diff --git a/internal/config/config.go b/internal/config/config.go index 5e21fb8e3..c22474235 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -146,10 +146,6 @@ type KeyStore struct { ETHProvider string `env:"ISSUER_KMS_ETH_PROVIDER"` SOLProvider string `env:"ISSUER_KMS_SOL_PROVIDER"` ProviderLocalStorageFilePath string `env:"ISSUER_KMS_PROVIDER_LOCAL_STORAGE_FILE_PATH"` - AWSAccessKey string `env:"ISSUER_KMS_AWS_ACCESS_KEY"` - AWSSecretKey string `env:"ISSUER_KMS_AWS_SECRET_KEY"` - AWSRegion string `env:"ISSUER_KMS_AWS_REGION"` - AWSURL string `env:"ISSUER_KMS_AWS_URL" envDefault:"http://localstack:4566"` VaultUserPassAuthEnabled bool `env:"ISSUER_VAULT_USERPASS_AUTH_ENABLED"` VaultUserPassAuthPassword string `env:"ISSUER_VAULT_USERPASS_AUTH_PASSWORD"` TLSEnabled bool `env:"ISSUER_VAULT_TLS_ENABLED"` @@ -367,17 +363,11 @@ func checkEnvVars(ctx context.Context, cfg *Configuration) error { } if cfg.KeyStore.ETHProvider == AWSSM || cfg.KeyStore.ETHProvider == AWSKMS || cfg.KeyStore.BJJProvider == AWSSM || cfg.KeyStore.SOLProvider == AWSSM { - if cfg.KeyStore.AWSAccessKey == "" { - log.Error(ctx, "ISSUER_AWS_KEY_ID value is missing") - return errors.New("ISSUER_AWS_KEY_ID value is missing") - } - if cfg.KeyStore.AWSSecretKey == "" { - log.Error(ctx, "ISSUER_AWS_SECRET_KEY value is missing") - return errors.New("ISSUER_AWS_SECRET_KEY value is missing") - } - if cfg.KeyStore.AWSRegion == "" { - log.Error(ctx, "ISSUER_AWS_REGION value is missing") - return errors.New("ISSUER_AWS_REGION value is missing") + _, err := kms.LoadAWSConfig(ctx) + + if err != nil { + log.Error(ctx, "AWS configuration loading failed", "err", err) + return fmt.Errorf("failed to load AWS configuration: %w", err) } } @@ -415,10 +405,6 @@ func KeyStoreConfig(ctx context.Context, cfg *Configuration, vaultCfg providers. BJJKeyProvider: kms.ConfigProvider(cfg.KeyStore.BJJProvider), ETHKeyProvider: kms.ConfigProvider(cfg.KeyStore.ETHProvider), SOLKeyProvider: kms.ConfigProvider(cfg.KeyStore.SOLProvider), - AWSAccessKey: cfg.KeyStore.AWSAccessKey, - AWSSecretKey: cfg.KeyStore.AWSSecretKey, - AWSRegion: cfg.KeyStore.AWSRegion, - AWSURL: cfg.KeyStore.AWSURL, LocalStoragePath: cfg.KeyStore.ProviderLocalStorageFilePath, Vault: vaultCli, PluginIden3MountPath: cfg.KeyStore.PluginIden3MountPath, diff --git a/internal/config/config_test.go b/internal/config/config_test.go index db0b0bd1a..0286ee41f 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -137,9 +137,6 @@ func TestLoad(t *testing.T) { assert.Equal(t, "issuernodepwd", cfg.KeyStore.VaultUserPassAuthPassword) assert.Equal(t, "localstorage", cfg.KeyStore.BJJProvider) assert.Equal(t, "localstorage", cfg.KeyStore.ETHProvider) - assert.Equal(t, "XYZ", cfg.KeyStore.AWSAccessKey) - assert.Equal(t, "123HHUBUuO5", cfg.KeyStore.AWSSecretKey) - assert.Equal(t, "eu-west-1", cfg.KeyStore.AWSRegion) assert.Equal(t, "./resolvers_settings.yaml", cfg.NetworkResolverPath) assert.Equal(t, "./payment_settings.yaml", cfg.Payments.SettingsPath) assert.Equal(t, "hvs.NK8jrOU4XNY", cfg.KeyStore.Token) diff --git a/internal/kms/aws.go b/internal/kms/aws.go new file mode 100644 index 000000000..29cd982bd --- /dev/null +++ b/internal/kms/aws.go @@ -0,0 +1,89 @@ +package kms + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/kms" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + + "github.com/polygonid/sh-id-platform/internal/log" +) + +func LoadAWSConfig(ctx context.Context) (aws.Config, error) { + // Backward-compatible behaviour for AWS SDK configuration + // env variables (DEPRECATED) + // "ISSUER_KMS_AWS_ACCESS_KEY" + // "ISSUER_KMS_AWS_SECRET_KEY" + // "ISSUER_KMS_AWS_REGION" + accessKey := strings.TrimSpace(os.Getenv("ISSUER_KMS_AWS_ACCESS_KEY")) + secretKey := strings.TrimSpace(os.Getenv("ISSUER_KMS_AWS_SECRET_KEY")) + region := strings.TrimSpace(os.Getenv("ISSUER_KMS_AWS_REGION")) + + if accessKey != "" && secretKey != "" { + log.Info(ctx, "Loading AWS config with static credentials") + + options := []func(*config.LoadOptions) error{ + config.WithCredentialsProvider( + credentials.NewStaticCredentialsProvider(accessKey, secretKey, ""), + ), + } + + if region != "" { + options = append(options, config.WithRegion(region)) + } + + return config.LoadDefaultConfig(ctx, options...) + } + + log.Info(ctx, "Loading AWS config with default credentials") + + return config.LoadDefaultConfig(ctx) +} + +func AwsSecretsManager(ctx context.Context) (*secretsmanager.Client, error) { + cfg, err := LoadAWSConfig(ctx) + + if err != nil { + return nil, fmt.Errorf("unable to load SDK config, %w", err) + } + + // LocalStack/OpenStack mode + // https://docs.localstack.cloud/aws/integrations/aws-sdks/go/ + // Region is provided from AWS_REGION env variable + url := strings.TrimSpace(os.Getenv("ISSUER_KMS_AWS_URL")) + var options []func(*secretsmanager.Options) + if url != "" { + options = append(options, func(o *secretsmanager.Options) { + o.BaseEndpoint = aws.String(url) + }) + } + return secretsmanager.NewFromConfig(cfg, options...), nil +} + +func AwsKms(ctx context.Context) (*kms.Client, error) { + cfg, err := LoadAWSConfig(ctx) + + if err != nil { + return nil, fmt.Errorf("unable to load SDK config, %w", err) + } + + var options []func(*kms.Options) + + // LocalStack/OpenStack mode + // https://docs.localstack.cloud/aws/integrations/aws-sdks/go/ + // Region is provided from AWS_REGION env variable + url := strings.TrimSpace(os.Getenv("ISSUER_KMS_AWS_URL")) + if url != "" { + options = append(options, func(o *kms.Options) { + o.BaseEndpoint = aws.String(url) + }) + } + + return kms.NewFromConfig(cfg, options...), nil +} diff --git a/internal/kms/aws_kms_eth_key_provider.go b/internal/kms/aws_kms_eth_key_provider.go index 39972e235..f1f1dc12c 100644 --- a/internal/kms/aws_kms_eth_key_provider.go +++ b/internal/kms/aws_kms_eth_key_provider.go @@ -7,8 +7,6 @@ import ( "strings" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/kms" "github.com/aws/aws-sdk-go-v2/service/kms/types" "github.com/ethereum/go-ethereum/crypto" @@ -30,41 +28,21 @@ type awsKmsEthKeyProvider struct { issuerETHTransferKeyPath string } -// AwKmsEthKeyProviderConfig - configuration for AWS KMS Ethereum key provider -type AwKmsEthKeyProviderConfig struct { - AccessKey string - SecretKey string - Region string - URL string -} - // NewAwsKMSEthKeyProvider - creates new key provider for Ethereum keys stored in AWS KMS -func NewAwsKMSEthKeyProvider(ctx context.Context, keyType KeyType, issuerETHTransferKeyPath string, awsKmsEthKeyProviderConfig AwKmsEthKeyProviderConfig) (KeyProvider, error) { +func NewAwsKMSEthKeyProvider(ctx context.Context, keyType KeyType, issuerETHTransferKeyPath string) (KeyProvider, error) { keyTypeRE := regexp.QuoteMeta(string(keyType)) reIdenKeyPathHex := regexp.MustCompile("^(?i).*/" + keyTypeRE + ":([a-f0-9]{64})$") - cfg, err := config.LoadDefaultConfig( - ctx, - config.WithRegion(awsKmsEthKeyProviderConfig.Region), - config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(awsKmsEthKeyProviderConfig.AccessKey, - awsKmsEthKeyProviderConfig.SecretKey, "")), - ) - if err != nil { - return nil, fmt.Errorf("unable to load SDK config, %v", err) - } - var options []func(*kms.Options) - if strings.ToLower(awsKmsEthKeyProviderConfig.Region) == "local" { - options = make([]func(*kms.Options), 1) - options[0] = func(o *kms.Options) { - o.BaseEndpoint = aws.String(awsKmsEthKeyProviderConfig.URL) - } + client, err := AwsKms(ctx) + + if err != nil { + return nil, fmt.Errorf("failed to create AWS KMS client: %w", err) } - svc := kms.NewFromConfig(cfg, options...) return &awsKmsEthKeyProvider{ keyType: keyType, reIdenKeyPathHex: reIdenKeyPathHex, - kmsClient: svc, + kmsClient: client, issuerETHTransferKeyPath: issuerETHTransferKeyPath, }, nil } diff --git a/internal/kms/aws_kms_eth_key_provider_test.go b/internal/kms/aws_kms_eth_key_provider_test.go index c4c4fbcf9..615cceacf 100644 --- a/internal/kms/aws_kms_eth_key_provider_test.go +++ b/internal/kms/aws_kms_eth_key_provider_test.go @@ -12,12 +12,7 @@ import ( func Test_NewInAWSKMS(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey", AwKmsEthKeyProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey") require.NoError(t, err) t.Run("should create a new KEYID", func(t *testing.T) { @@ -30,12 +25,7 @@ func Test_NewInAWSKMS(t *testing.T) { func Test_PublicKeyInAWSKMS(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey", AwKmsEthKeyProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey") require.NoError(t, err) t.Run("should get public key", func(t *testing.T) { @@ -58,12 +48,7 @@ func Test_PublicKeyInAWSKMS(t *testing.T) { func Test_LinkToIdentityInAWSKMS(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey", AwKmsEthKeyProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey") require.NoError(t, err) t.Run("should link the key to an identity", func(t *testing.T) { @@ -87,12 +72,7 @@ func Test_LinkToIdentityInAWSKMS(t *testing.T) { func Test_ListByIdentityInAWSKMS(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey", AwKmsEthKeyProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey") require.NoError(t, err) t.Run("should link the key to an identity", func(t *testing.T) { @@ -143,12 +123,7 @@ func Test_ListByIdentityInAWSKMS(t *testing.T) { func Test_SignInAWSKMS(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey", AwKmsEthKeyProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsKMSEthKeyProvider(ctx, ethereum, "pbkey") require.NoError(t, err) data := make([]byte, 32) _, err = io.ReadFull(rand.Reader, data) diff --git a/internal/kms/aws_secret_storage_provider.go b/internal/kms/aws_secret_storage_provider.go index 9cb6cbecd..de4874390 100644 --- a/internal/kms/aws_secret_storage_provider.go +++ b/internal/kms/aws_secret_storage_provider.go @@ -5,11 +5,10 @@ import ( "encoding/base64" "encoding/json" "errors" + "fmt" "strings" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types" "github.com/iden3/go-iden3-core/v2/w3c" @@ -23,40 +22,20 @@ type secretStorageProviderKeyMaterial struct { PrivateKey string `json:"private_key"` } -// AwsSecretStorageProviderConfig is a config for AwsSecretStorageProvider -// AccessKey and SecretKey are the AWS credentials -type AwsSecretStorageProviderConfig struct { - AccessKey string - SecretKey string - Region string - URL string -} - type awsSecretStorageProvider struct { secretManager *secretsmanager.Client } // NewAwsSecretStorageProvider creates a new instance of AwsSecretStorageProvider -func NewAwsSecretStorageProvider(ctx context.Context, conf AwsSecretStorageProviderConfig) (*awsSecretStorageProvider, error) { - cfg, err := config.LoadDefaultConfig(ctx, - config.WithRegion(conf.Region), - config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(conf.AccessKey, conf.SecretKey, "")), - ) - if err != nil { - log.Error(ctx, "error loading AWS config", "err", err) - return nil, err - } +func NewAwsSecretStorageProvider(ctx context.Context) (*awsSecretStorageProvider, error) { + client, err := AwsSecretsManager(ctx) - var options []func(*secretsmanager.Options) - if strings.ToLower(conf.Region) == "local" { - options = make([]func(*secretsmanager.Options), 1) - options[0] = func(o *secretsmanager.Options) { - o.BaseEndpoint = aws.String(conf.URL) - } + if err != nil { + return nil, fmt.Errorf("failed to create AWS Secrets Manager client: %w", err) } return &awsSecretStorageProvider{ - secretManager: secretsmanager.NewFromConfig(cfg, options...), + secretManager: client, }, nil } diff --git a/internal/kms/aws_secret_storage_provider_test.go b/internal/kms/aws_secret_storage_provider_test.go index 80941f0a0..ca77d9de0 100644 --- a/internal/kms/aws_secret_storage_provider_test.go +++ b/internal/kms/aws_secret_storage_provider_test.go @@ -12,12 +12,7 @@ import ( func Test_SaveKeyMaterial(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should save key bjj material", func(t *testing.T) { @@ -74,12 +69,7 @@ func Test_SaveKeyMaterial(t *testing.T) { func Test_searchByIdentity(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should get identity for BJJ", func(t *testing.T) { @@ -135,12 +125,7 @@ func Test_searchByIdentity(t *testing.T) { func Test_searchPrivateKey(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should get private key for BJJ", func(t *testing.T) { @@ -224,12 +209,7 @@ func Test_searchPrivateKey(t *testing.T) { func Test_getKeyMaterial(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should get key material for bjj", func(t *testing.T) { @@ -264,12 +244,7 @@ func Test_getKeyMaterial(t *testing.T) { func Test_deleteKeyMaterial(t *testing.T) { ctx := context.Background() - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should delete key material for bjj", func(t *testing.T) { diff --git a/internal/kms/kms.go b/internal/kms/kms.go index 97bd27df0..5577be5ae 100644 --- a/internal/kms/kms.go +++ b/internal/kms/kms.go @@ -68,10 +68,6 @@ type Config struct { BJJKeyProvider ConfigProvider ETHKeyProvider ConfigProvider SOLKeyProvider ConfigProvider - AWSAccessKey string - AWSSecretKey string - AWSRegion string - AWSURL string LocalStoragePath string Vault *api.Client PluginIden3MountPath string @@ -345,12 +341,7 @@ func createBJJKeyProvider(ctx context.Context, config Config) (KeyProvider, erro } if config.BJJKeyProvider == BJJAWSSecretManagerStorage { - provider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: config.AWSAccessKey, - SecretKey: config.AWSSecretKey, - Region: config.AWSRegion, - URL: config.AWSURL, - }) + provider, err := NewAwsSecretStorageProvider(ctx) if err != nil { return nil, fmt.Errorf("cannot create BabyJubJub aws key provider: %+v", err) } @@ -387,35 +378,23 @@ func createETHKeyProvider(ctx context.Context, config Config) (KeyProvider, erro } if config.ETHKeyProvider == ETHAWSSecretManagerStorage { - if config.AWSAccessKey == "" || config.AWSSecretKey == "" || config.AWSRegion == "" { - return nil, errors.New("AWS secret manager access key, secret key and region have to be provided") - } - provider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: config.AWSAccessKey, - SecretKey: config.AWSSecretKey, - Region: config.AWSRegion, - URL: config.AWSURL, - }) + provider, err := NewAwsSecretStorageProvider(ctx) + if err != nil { return nil, fmt.Errorf("cannot create Ethereum aws key provider: %+v", err) } + ethKeyProvider = NewLocalEthKeyProvider(KeyTypeEthereum, provider) log.Info(ctx, "Ethereum key provider created", "provider:", ETHAWSSecretManagerStorage) } if config.ETHKeyProvider == ETHAwsKmsKeyProvider { - if config.AWSAccessKey == "" || config.AWSSecretKey == "" || config.AWSRegion == "" { - return nil, errors.New("AWS KMS access key, secret key and region have to be provided") - } - ethKeyProvider, err = NewAwsKMSEthKeyProvider(ctx, KeyTypeEthereum, config.IssuerETHTransferKeyPath, AwKmsEthKeyProviderConfig{ - AccessKey: config.AWSAccessKey, - SecretKey: config.AWSSecretKey, - Region: config.AWSRegion, - URL: config.AWSURL, - }) + ethKeyProvider, err = NewAwsKMSEthKeyProvider(ctx, KeyTypeEthereum, config.IssuerETHTransferKeyPath) + if err != nil { return nil, fmt.Errorf("cannot create Ethereum aws kms key provider: %+v", err) } + log.Info(ctx, "Ethereum key provider created", "provider:", ETHAwsKmsKeyProvider) } @@ -440,12 +419,7 @@ func createSOLKeyProvider(ctx context.Context, config Config) (KeyProvider, erro } if config.SOLKeyProvider == SOLAWSSecretManagerStorage { - provider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: config.AWSAccessKey, - SecretKey: config.AWSSecretKey, - Region: config.AWSRegion, - URL: config.AWSURL, - }) + provider, err := NewAwsSecretStorageProvider(ctx) if err != nil { return nil, fmt.Errorf("cannot create SOL aws key provider: %+v", err) } diff --git a/internal/kms/local_bjj_key_provider_test.go b/internal/kms/local_bjj_key_provider_test.go index db378dba0..314825730 100644 --- a/internal/kms/local_bjj_key_provider_test.go +++ b/internal/kms/local_bjj_key_provider_test.go @@ -18,12 +18,7 @@ func Test_New_LocalBJJKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should generate a new keyID using local storage manager", func(t *testing.T) { localbbjKeyProvider := NewLocalBJJKeyProvider(KeyTypeBabyJubJub, ls) @@ -80,12 +75,7 @@ func Test_LinkToIdentity_LocalBJJKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should link key to identity using local storage manager", func(t *testing.T) { localbbjKeyProvider := NewLocalBJJKeyProvider(KeyTypeBabyJubJub, ls) @@ -179,12 +169,7 @@ func Test_ListByIdentity_LocalBJJKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should list keys by identity using local storage manager", func(t *testing.T) { localbbjKeyProvider := NewLocalBJJKeyProvider(KeyTypeBabyJubJub, ls) @@ -255,12 +240,7 @@ func Test_PublicKey_LocalBJJKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should get public key using local storage manager", func(t *testing.T) { @@ -296,12 +276,7 @@ func Test_Sign_LocalBJJKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should sign digest using local storage manager | linking did", func(t *testing.T) { @@ -387,12 +362,7 @@ func Test_DeleteKey_LocalBJJKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should get public key using local storage manager", func(t *testing.T) { diff --git a/internal/kms/local_ed25519_key_provider_test.go b/internal/kms/local_ed25519_key_provider_test.go index f6a0666bc..9b7fe4883 100644 --- a/internal/kms/local_ed25519_key_provider_test.go +++ b/internal/kms/local_ed25519_key_provider_test.go @@ -20,12 +20,7 @@ func Test_New_LocalEd25519Provider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should generate a new keyID using local storage manager", func(t *testing.T) { localEd25519KeyProvider := NewLocalEd25519KeyProvider(KeyTypeEd25519, ls) @@ -82,12 +77,7 @@ func Test_LinkToIdentity_LocalEd25519KeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should link key to identity using local storage manager", func(t *testing.T) { localEd25519KeyProvider := NewLocalEd25519KeyProvider(KeyTypeEd25519, ls) @@ -126,12 +116,7 @@ func Test_ListByIdentity_LocalEd25519KeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should list keys by identity using local storage manager", func(t *testing.T) { localEd25519KeyProvider := NewLocalEd25519KeyProvider(KeyTypeEd25519, ls) @@ -180,12 +165,7 @@ func Test_PublicKey_LocalEd25519KeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should get public key using local storage manager", func(t *testing.T) { @@ -237,12 +217,7 @@ func Test_Sign_LocalEd25519KeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) data := make([]byte, 32) diff --git a/internal/kms/local_eth_key_provider_test.go b/internal/kms/local_eth_key_provider_test.go index 28b524526..c87bef611 100644 --- a/internal/kms/local_eth_key_provider_test.go +++ b/internal/kms/local_eth_key_provider_test.go @@ -20,12 +20,7 @@ func Test_New_LocalETHProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should generate a new keyID using local storage manager", func(t *testing.T) { localETHKeyProvider := NewLocalEthKeyProvider(KeyTypeEthereum, ls) @@ -82,12 +77,7 @@ func Test_LinkToIdentity_LocalETHKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should link key to identity using local storage manager", func(t *testing.T) { localETHKeyProvider := NewLocalEthKeyProvider(KeyTypeEthereum, ls) @@ -126,12 +116,7 @@ func Test_ListByIdentity_LocalETHKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should list keys by identity using local storage manager", func(t *testing.T) { localETHKeyProvider := NewLocalEthKeyProvider(KeyTypeEthereum, ls) @@ -180,12 +165,7 @@ func Test_PublicKey_LocalETHKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) t.Run("should get public key using local storage manager", func(t *testing.T) { @@ -237,12 +217,7 @@ func Test_Sign_LocalETHKeyProvider(t *testing.T) { defer os.Remove(tmpFile.Name()) ls := NewFileStorageManager(tmpFile.Name()) - awsStorageProvider, err := NewAwsSecretStorageProvider(ctx, AwsSecretStorageProviderConfig{ - AccessKey: "access_key", - SecretKey: "secret_key", - Region: "local", - URL: "http://localhost:4566", - }) + awsStorageProvider, err := NewAwsSecretStorageProvider(ctx) require.NoError(t, err) data := make([]byte, 32) diff --git a/internal/kms/main_test.go b/internal/kms/main_test.go index 6307ae14e..3920f01a5 100644 --- a/internal/kms/main_test.go +++ b/internal/kms/main_test.go @@ -40,6 +40,14 @@ func TestMain(m *testing.M) { func testMain(m *testing.M) int { cfg = vaultTest() + + // stdlib testing has no beforeEach; package-wide env for AWS integration tests + // (LocalStack) so LoadAWSConfig does not use the default credential chain / metadata. + _ = os.Setenv("ISSUER_KMS_AWS_ACCESS_KEY", "test") + _ = os.Setenv("ISSUER_KMS_AWS_SECRET_KEY", "test") + _ = os.Setenv("ISSUER_KMS_AWS_REGION", "local") + _ = os.Setenv("ISSUER_KMS_AWS_URL", "http://localhost:4566") + return m.Run() }