Feature/use default aws credentials#951
Conversation
| } | ||
| } | ||
|
|
||
| return secretsmanager.NewFromConfig(cfg, options...), nil |
There was a problem hiding this comment.
Possible panic if url == nil, because options[0] will be nil in this case.
| } | ||
| } | ||
|
|
||
| return kms.NewFromConfig(cfg, options...), nil |
There was a problem hiding this comment.
Possible panic if url == nil
| var options []func(*awskms.Options) | ||
| if strings.ToLower(awsRegion) == "local" { | ||
| options = make([]func(*awskms.Options), 1) | ||
| options := make([]func(*awskms.Options), 1) |
| return nil | ||
| } | ||
|
|
||
| func LoadAWSConfig(ctx context.Context) (aws.Config, error) { |
There was a problem hiding this comment.
Code duplication. Can we put the LoadAWSConfig to common place?
| "github.com/aws/aws-sdk-go-v2/service/secretsmanager" | ||
| ) | ||
|
|
||
| func LoadAWSConfig(ctx context.Context) (aws.Config, error) { |
There was a problem hiding this comment.
Code duplication. Can we put the LoadAWSConfig to common place?
| cfg, err := LoadAWSConfig(ctx) | ||
|
|
||
| if err != nil { | ||
| return nil, fmt.Errorf("unable to load SDK config, %v", err) |
There was a problem hiding this comment.
Use %w to wrapper the error.
| cfg, err := LoadAWSConfig(ctx) | ||
|
|
||
| if err != nil { | ||
| return nil, fmt.Errorf("unable to load SDK config, %v", err) |
| client, err := AwsKms(ctx) | ||
|
|
||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to create AWS KMS client: %v", err) |
| o.BaseEndpoint = aws.String(conf.URL) | ||
| } | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to create AWS Secrets Manager client: %v", err) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
AWS_ACCESS_KEY_ID and the others are consumed by AWS lib by default 🤔
68ad6b2 to
f91e2ea
Compare
| @@ -153,32 +147,26 @@ func main() { | |||
| } | |||
|
|
|||
| if issuerKMSETHProviderToUse == config.AWSSM { | |||
There was a problem hiding this comment.
Can we reuse AwsSecretsManager from internal/kms/aws.go?
| awsconfig.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(awsAccessKey, awsSecretKey, "")), | ||
| ) | ||
| func createEmptyKey(ctx context.Context, privateKeyAlias string) (*string, error) { | ||
| cfg, err := kms.LoadAWSConfig(ctx) |
There was a problem hiding this comment.
Can we reuse AwsKMS from internal/kms/aws.go?
There was a problem hiding this comment.
Pull request overview
This PR refactors the KMS AWS integrations to rely on the AWS SDK’s default credential/region resolution (and a shared helper), removing explicit AWS access key/secret/region wiring through the application config.
Changes:
- Introduces centralized AWS SDK client creation helpers (
AwsSecretsManager,AwsKms,LoadAWSConfig) and switches AWS KMS/Secrets Manager providers to use them. - Removes AWS credential/region fields from KMS/config plumbing and updates KMS/provider constructors accordingly.
- Updates multiple tests to use the new constructors (but they now require explicit env setup for LocalStack/CI stability).
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 30 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/kms/aws.go | New helper functions for AWS SDK config + Secrets Manager/KMS clients. |
| internal/kms/aws_secret_storage_provider.go | Uses shared AWS Secrets Manager client helper. |
| internal/kms/aws_kms_eth_key_provider.go | Uses shared AWS KMS client helper. |
| internal/kms/kms.go | Stops passing explicit AWS config into providers; uses new constructors. |
| internal/config/config.go | Removes AWS access/secret; changes region env tag; leaves AWS URL/region fields present. |
| internal/config/config_test.go | Removes assertions for removed AWS config fields (but other expectations remain). |
| cmd/kms_priv_key_importer/main.go | Uses shared AWS client helpers instead of inline AWS SDK config. |
| internal/kms/*_test.go | Updates provider construction to new AWS constructors (now env-dependent). |
| Makefile | Falls back to standard AWS_* env vars when ISSUER_KMS_* are unset. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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) | ||
|
|
There was a problem hiding this comment.
This test creates an AWS-backed storage provider without configuring LocalStack endpoint/region/credentials via env vars. Set AWS_REGION, AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, and ISSUER_KMS_AWS_URL in the test setup (t.Setenv) or mark as integration.
| 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) | ||
|
|
There was a problem hiding this comment.
NewAwsSecretStorageProvider(ctx) now relies on default AWS config; without explicit env vars this test is not hermetic and can fail in CI. Configure AWS_REGION + dummy creds + ISSUER_KMS_AWS_URL using t.Setenv before creating the provider.
| if accessKey != "" && secretKey != "" && region != "" { | ||
| return config.LoadDefaultConfig( | ||
| ctx, | ||
| config.WithCredentialsProvider( | ||
| credentials.NewStaticCredentialsProvider(accessKey, secretKey, ""), | ||
| ), | ||
| config.WithRegion(region), | ||
| ) |
There was a problem hiding this comment.
LoadAWSConfig only applies the deprecated ISSUER_KMS_AWS_ACCESS_KEY/SECRET_KEY when ISSUER_KMS_AWS_REGION is also set. If users set the deprecated access/secret vars but migrate region to AWS_REGION (or shared config), these credentials will be silently ignored and the SDK will fall back to the default chain (possibly using different credentials). Consider using the deprecated static credentials provider whenever access+secret are set, and only override the region when ISSUER_KMS_AWS_REGION is present.
| if accessKey != "" && secretKey != "" && region != "" { | |
| return config.LoadDefaultConfig( | |
| ctx, | |
| config.WithCredentialsProvider( | |
| credentials.NewStaticCredentialsProvider(accessKey, secretKey, ""), | |
| ), | |
| config.WithRegion(region), | |
| ) | |
| if accessKey != "" && secretKey != "" { | |
| opts := []func(*config.LoadOptions){ | |
| config.WithCredentialsProvider( | |
| credentials.NewStaticCredentialsProvider(accessKey, secretKey, ""), | |
| ), | |
| } | |
| if region != "" { | |
| opts = append(opts, config.WithRegion(region)) | |
| } | |
| return config.LoadDefaultConfig(ctx, opts...) |
| 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) | ||
|
|
There was a problem hiding this comment.
The provider construction here now relies on external AWS config; without setting LocalStack env vars this test will be non-deterministic and likely fail in CI. Add t.Setenv for AWS_REGION, AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, ISSUER_KMS_AWS_URL (and optionally AWS_EC2_METADATA_DISABLED) before creating the provider.
| @@ -143,12 +123,7 @@ func Test_ListByIdentityInAWSKMS(t *testing.T) { | |||
|
|
|||
| func Test_SignInAWSKMS(t *testing.T) { | |||
There was a problem hiding this comment.
This test will perform real AWS KMS calls unless LocalStack/region/credentials env vars are set. Add t.Setenv for AWS_REGION, AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, and ISSUER_KMS_AWS_URL before constructing the provider (or mark these as integration tests) to avoid accidental real-AWS usage and CI flakiness.
| func Test_SignInAWSKMS(t *testing.T) { | |
| func Test_SignInAWSKMS(t *testing.T) { | |
| t.Setenv("AWS_REGION", "us-east-1") | |
| t.Setenv("AWS_ACCESS_KEY_ID", "test") | |
| t.Setenv("AWS_SECRET_ACCESS_KEY", "test") | |
| t.Setenv("ISSUER_KMS_AWS_URL", "http://localhost:4566") |
There was a problem hiding this comment.
- add Setenv for all tests taht use aws.
| 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) | ||
|
|
There was a problem hiding this comment.
This test uses the default AWS credential chain but doesn't configure region/endpoint/credentials for LocalStack. Please set env vars in-test (t.Setenv) or skip when not configured to avoid flaky CI and accidental calls to real AWS.
| 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) | ||
|
|
There was a problem hiding this comment.
This test initializes the AWS-backed storage provider with no LocalStack/AWS env setup, which can break CI and/or hit real AWS. Configure AWS_REGION, AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, ISSUER_KMS_AWS_URL using t.Setenv before creating the provider.
| 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) |
There was a problem hiding this comment.
NewAwsSecretStorageProvider(ctx) now depends on the default AWS SDK chain and ISSUER_KMS_AWS_URL. This test doesn't set env vars, so it can fail in CI or hit real AWS. Set AWS_REGION + dummy creds + ISSUER_KMS_AWS_URL via t.Setenv before creating the provider (or gate as integration).
| 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) | ||
|
|
There was a problem hiding this comment.
This test case creates a real AWS Secrets Manager client via the default credential chain but doesn't set the environment expected for LocalStack. As a result, it can call real AWS or fail in CI. Please set AWS_REGION + dummy creds + ISSUER_KMS_AWS_URL in the test setup (or gate behind an integration test flag).
| @@ -12,12 +12,7 @@ import ( | |||
|
|
|||
| func Test_SaveKeyMaterial(t *testing.T) { | |||
There was a problem hiding this comment.
These tests now construct the AWS Secrets Manager provider via the default AWS config chain, but they don't set AWS_REGION/AWS credentials or ISSUER_KMS_AWS_URL. In CI this will attempt real AWS (or fail resolving the region) instead of using LocalStack at localhost:4566. Set required env vars in the test (e.g., t.Setenv for AWS_REGION, AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, ISSUER_KMS_AWS_URL, and optionally AWS_EC2_METADATA_DISABLED) or skip when LocalStack isn't available, so the tests remain deterministic.
| func Test_SaveKeyMaterial(t *testing.T) { | |
| func Test_SaveKeyMaterial(t *testing.T) { | |
| t.Setenv("AWS_REGION", "us-east-1") | |
| t.Setenv("AWS_ACCESS_KEY_ID", "test") | |
| t.Setenv("AWS_SECRET_ACCESS_KEY", "test") | |
| t.Setenv("AWS_EC2_METADATA_DISABLED", "true") | |
| t.Setenv("ISSUER_KMS_AWS_URL", "http://localhost:4566") |
|
Yep. I'm totally agree with copilot review. We have to modify our test to use localstack, because by default we use AWS credentials. |
968b6d6 to
b59fb55
Compare
b59fb55 to
650cf9a
Compare
No description provided.