-
Notifications
You must be signed in to change notification settings - Fork 105
Feature/use default aws credentials #951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
|
@@ -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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How to enable localstack without the env?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's the same ...
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| 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,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 | ||
|
|
@@ -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) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 == "" { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -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, | ||
|
|
||
| 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) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Code duplication. Can we put the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possible panic if |
||
| } | ||
|
|
||
| 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possible panic if
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
| } | ||
There was a problem hiding this comment.
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_REGIONThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AWS_ACCESS_KEY_IDand the others are consumed by AWS lib by default 🤔