From daf139c12d9b44e7c00c74d137944ce64a4061e5 Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Sat, 6 Jun 2026 09:00:04 +0200 Subject: [PATCH] Use aws-sdk-go-v2/config to load AWS config Replace the hand-rolled credential chain (static, ECS endpoint, EC2 role) with config.LoadDefaultConfig, which handles the full standard AWS credential resolution chain automatically. Co-authored-by: Neil McGibbon Signed-off-by: Bryan Frimin --- go.mod | 8 ++++- pkg/awsconfig/config.go | 69 ++++++++++++----------------------------- pkg/probod/probod.go | 5 ++- 3 files changed, 30 insertions(+), 52 deletions(-) diff --git a/go.mod b/go.mod index 30b7623b0..5ac090455 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,8 @@ require ( github.com/99designs/gqlgen v0.17.90 github.com/anthropics/anthropic-sdk-go v1.45.0 github.com/aws/aws-sdk-go-v2 v1.41.7 + github.com/aws/aws-sdk-go-v2/config v1.32.14 github.com/aws/aws-sdk-go-v2/credentials v1.19.17 - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.52.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.101.0 github.com/brianvoe/gofakeit/v7 v7.15.0 @@ -57,6 +57,12 @@ require ( github.com/ProtonMail/go-crypto v1.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/atotto/clipboard v0.1.4 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect diff --git a/pkg/awsconfig/config.go b/pkg/awsconfig/config.go index 0ae33ebfb..49ca24293 100644 --- a/pkg/awsconfig/config.go +++ b/pkg/awsconfig/config.go @@ -16,16 +16,12 @@ package awsconfig import ( "context" + "fmt" "net/http" - "net/url" - "os" - "time" "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/credentials/ec2rolecreds" - "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" "go.gearno.de/kit/httpclient" "go.gearno.de/kit/log" ) @@ -45,15 +41,11 @@ const ( DefaultSessionName = "go.probo.inc/probo" ) -func NewConfig(logger *log.Logger, httpClient *http.Client, opts Options) aws.Config { +func NewConfig(logger *log.Logger, httpClient *http.Client, opts Options) (aws.Config, error) { if opts.Region == "" { opts.Region = DefaultRegion } - if opts.SessionName == "" { - opts.SessionName = "" - } - logger = logger.Named( "aws.client", log.WithAttributes( @@ -67,52 +59,29 @@ func NewConfig(logger *log.Logger, httpClient *http.Client, opts Options) aws.Co httpClient = httpclient.DefaultPooledClient(httpclient.WithLogger(logger)) } - cfg := aws.NewConfig() - cfg.HTTPClient = httpClient - cfg.Region = opts.Region - // cfg.Logger = logger TODO: add logger interface for aws + loadOpts := []func(*config.LoadOptions) error{ + config.WithRegion(opts.Region), + config.WithHTTPClient(httpClient), + } if opts.AccessKeyID != "" && opts.SecretAccessKey != "" { - // Use static credentials if provided - cfg.Credentials = credentials.NewStaticCredentialsProvider( - opts.AccessKeyID, - opts.SecretAccessKey, - opts.SessionName, - ) - } else { - imdsClient := imds.New(imds.Options{HTTPClient: httpClient}) + loadOpts = append(loadOpts, config.WithCredentialsProvider( + credentials.NewStaticCredentialsProvider( + opts.AccessKeyID, + opts.SecretAccessKey, + opts.SessionName, + ), + )) + } - ec2Provider := ec2rolecreds.New(func(options *ec2rolecreds.Options) { - options.Client = imdsClient - }) - - ecsCredentialsURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") - ecsEndpoint, _ := url.JoinPath("http://169.254.170.2", ecsCredentialsURI) - ecsProvider := endpointcreds.New( - ecsEndpoint, - func(options *endpointcreds.Options) { - options.HTTPClient = httpClient - }, - ) - - cfg.Credentials = aws.NewCredentialsCache( - aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) { - creds, err := ecsProvider.Retrieve(ctx) - if err == nil { - return creds, nil - } - - return ec2Provider.Retrieve(ctx) - }), - func(o *aws.CredentialsCacheOptions) { - o.ExpiryWindow = 10 * time.Minute - }, - ) + cfg, err := config.LoadDefaultConfig(context.Background(), loadOpts...) + if err != nil { + return aws.Config{}, fmt.Errorf("cannot load AWS config: %w", err) } if opts.Endpoint != "" { cfg.BaseEndpoint = new(opts.Endpoint) } - return cfg.Copy() + return cfg, nil } diff --git a/pkg/probod/probod.go b/pkg/probod/probod.go index 978289707..2d291f5af 100644 --- a/pkg/probod/probod.go +++ b/pkg/probod/probod.go @@ -245,7 +245,7 @@ func (impl *Implm) Run( return fmt.Errorf("cannot get cookie secret bytes: %w", err) } - awsConfig := awsconfig.NewConfig( + awsConfig, err := awsconfig.NewConfig( l, httpclient.DefaultPooledClient( httpclient.WithLogger(l), @@ -259,6 +259,9 @@ func (impl *Implm) Run( Endpoint: impl.cfg.AWS.Endpoint, }, ) + if err != nil { + return fmt.Errorf("cannot initialize AWS config: %w", err) + } html2pdfConverter := html2pdf.NewConverter( impl.cfg.ChromeDPAddr,