diff --git a/router/internal/persistedoperation/s3/client.go b/router/internal/persistedoperation/s3/client.go index 121b1ffa58..82b7bb7509 100644 --- a/router/internal/persistedoperation/s3/client.go +++ b/router/internal/persistedoperation/s3/client.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + "io" + "net/http" + "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "github.com/wundergraph/cosmo/router/internal/persistedoperation" @@ -11,7 +14,6 @@ import ( "go.opentelemetry.io/otel/codes" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" - "io" ) type Option func(*Client) @@ -43,8 +45,26 @@ func NewClient(endpoint string, options *Options) (persistedoperation.Client, er ), } + // The providers credential chain is used to allow multiple authentication methods. + providers := []credentials.Provider{ + // Static credentials allow setting the access key and secret access key directly. + &credentials.Static{ + Value: credentials.Value{ + AccessKeyID: options.AccessKeyID, + SecretAccessKey: options.SecretAccessKey, + SignerType: credentials.SignatureV4, + }, + }, + // IAM credentials are retrieved from the EC2 nodes assumed role. + &credentials.IAM{ + Client: &http.Client{ + Transport: http.DefaultTransport, + }, + }, + } + minioClient, err := minio.New(endpoint, &minio.Options{ - Creds: credentials.NewStaticV4(options.AccessKeyID, options.SecretAccessKey, ""), + Creds: credentials.NewChainCredentials(providers), Region: options.Region, Secure: options.UseSSL, }) diff --git a/router/pkg/config/config.schema.json b/router/pkg/config/config.schema.json index c0a9ce654f..c0b718417c 100644 --- a/router/pkg/config/config.schema.json +++ b/router/pkg/config/config.schema.json @@ -54,6 +54,7 @@ }, "s3": { "type": "array", + "description": "The configuration for the S3 storage provider. If no access key and secret key are provided, the provider will attempt to retreieve IAM credentials from the EC2 service.", "items": { "type": "object", "required": ["bucket", "id"], diff --git a/router/pkg/routerconfig/s3/client.go b/router/pkg/routerconfig/s3/client.go index 740042d61f..1099667786 100644 --- a/router/pkg/routerconfig/s3/client.go +++ b/router/pkg/routerconfig/s3/client.go @@ -3,14 +3,15 @@ package s3 import ( "context" "errors" + "io" + "net/http" + "time" + "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "github.com/wundergraph/cosmo/router/pkg/controlplane/configpoller" "github.com/wundergraph/cosmo/router/pkg/execution_config" "github.com/wundergraph/cosmo/router/pkg/routerconfig" - "io" - "net/http" - "time" ) type Option func(*Client) @@ -30,13 +31,30 @@ type ClientOptions struct { } func NewClient(endpoint string, options *ClientOptions) (routerconfig.Client, error) { - client := &Client{ options: options, } + // The providers credential chain is used to allow multiple authentication methods. + providers := []credentials.Provider{ + // Static credentials allow setting the access key and secret access key directly. + &credentials.Static{ + Value: credentials.Value{ + AccessKeyID: options.AccessKeyID, + SecretAccessKey: options.SecretAccessKey, + SignerType: credentials.SignatureV4, + }, + }, + // IAM credentials are retrieved from the EC2 nodes assumed role. + &credentials.IAM{ + Client: &http.Client{ + Transport: http.DefaultTransport, + }, + }, + } + minioClient, err := minio.New(endpoint, &minio.Options{ - Creds: credentials.NewStaticV4(options.AccessKeyID, options.SecretAccessKey, ""), + Creds: credentials.NewChainCredentials(providers), Region: options.Region, Secure: options.Secure, })