Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions Makefile

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes can brake local setups for users who use envs: ISSUER_KMS_AWS_ACCESS_KEY, ISSUER_KMS_AWS_SECRET_KEY, ISSUER_KMS_AWS_REGION

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AWS_ACCESS_KEY_ID and the others are consumed by AWS lib by default 🤔

Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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

Expand Down
70 changes: 8 additions & 62 deletions cmd/kms_priv_key_importer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -153,33 +146,11 @@ func main() {
}

if issuerKMSETHProviderToUse == config.AWSSM {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we reuse AwsSecretsManager from internal/kms/aws.go?

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
Expand All @@ -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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to enable localstack without the env?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same ...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

	cfg, err := kms.LoadAWSConfig(ctx)``` is loading the the priorities as we discussed


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
Expand Down Expand Up @@ -253,36 +214,21 @@ 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,
Origin: types.OriginTypeExternal,
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
Expand All @@ -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)
}
Expand Down
1 change: 1 addition & 0 deletions internal/api/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
24 changes: 5 additions & 19 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down Expand Up @@ -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 == "" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do all these checks at startup so that we get errors at startup instead of at runtime?

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)
}
}

Expand Down Expand Up @@ -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,
Expand Down
3 changes: 0 additions & 3 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
89 changes: 89 additions & 0 deletions internal/kms/aws.go
Original file line number Diff line number Diff line change
@@ -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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code duplication. Can we put the LoadAWSConfig to common place?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible panic if url == nil, because options[0] will be nil in this case.

}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible panic if url == nil

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

}
34 changes: 6 additions & 28 deletions internal/kms/aws_kms_eth_key_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
}
Expand Down
Loading