diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b7e46b7..214079da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Add support for role based authentication in s3 backend. ## [6.25.1] - 2025-01-09 ### Fixed diff --git a/backend/s3/options.go b/backend/s3/options.go index f859a07a..356b1a27 100644 --- a/backend/s3/options.go +++ b/backend/s3/options.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/defaults" "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/request" @@ -22,6 +23,7 @@ type Options struct { SecretAccessKey string `json:"secretAccessKey,omitempty"` SessionToken string `json:"sessionToken,omitempty"` Region string `json:"region,omitempty"` + RoleARN string `json:"roleARN,omitempty"` Endpoint string `json:"endpoint,omitempty"` ACL string `json:"acl,omitempty"` ForcePathStyle bool `json:"forcePathStyle,omitempty"` @@ -76,6 +78,12 @@ func getClient(opt Options) (s3iface.S3API, error) { return nil, err } + if opt.RoleARN != "" { + // Create role credentials + creds := stscreds.NewCredentials(s, opt.RoleARN) + return s3.New(s, &aws.Config{Credentials: creds}), nil + } + // return client instance return s3.New(s), nil } diff --git a/backend/s3/options_test.go b/backend/s3/options_test.go index 0ae6a9fe..1fdf7817 100644 --- a/backend/s3/options_test.go +++ b/backend/s3/options_test.go @@ -44,6 +44,19 @@ func (o *optionsTestSuite) TestGetClient() { o.NoError(err) o.NotNil(client, "client is set") o.Equal("set-by-envvar", *client.(*s3.S3).Config.Region, "region is set by env var") + + // role ARN set + opts = Options{ + AccessKeyID: "mykey", + SecretAccessKey: "mysecret", + Region: "some-region", + RoleARN: "arn:aws:iam::123456789012:role/my-role", + } + client, err = getClient(opts) + o.NoError(err) + o.NotNil(client, "client is set") + o.Equal("some-region", *client.(*s3.S3).Config.Region, "region is set") + o.NotNil(client.(*s3.S3).Config.Credentials, "credentials are set") } func TestOptions(t *testing.T) { diff --git a/docs/s3.md b/docs/s3.md index 95a2c277..8d117672 100644 --- a/docs/s3.md +++ b/docs/s3.md @@ -90,6 +90,9 @@ found: 1. RemoteCredProvider - default remote endpoints such as EC2 or ECS IAM Roles 1. EC2RoleProvider - credentials from the EC2 service, and keeps track if those credentials are expired +If the 'RoleARN' option is set for the filesystem then the backend will attempt to assume the given role granting the permissions associated with it. For more information regarding role based credentials: +https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html + See the following for more auth info: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html and https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html @@ -451,11 +454,20 @@ Volume returns the bucket the location is contained in. ```go type Options struct { - AccessKeyID string `json:"accessKeyId,omitempty"` - SecretAccessKey string `json:"secretAccessKey,omitempty"` - SessionToken string `json:"sessionToken,omitempty"` - Region string `json:"region,omitempty"` - Endpoint string `json:"endpoint,omitempty"` + AccessKeyID string `json:"accessKeyId,omitempty"` + SecretAccessKey string `json:"secretAccessKey,omitempty"` + SessionToken string `json:"sessionToken,omitempty"` + Region string `json:"region,omitempty"` + RoleARN string `json:"roleARN,omitempty"` + Endpoint string `json:"endpoint,omitempty"` + ACL string `json:"acl,omitempty"` + ForcePathStyle bool `json:"forcePathStyle,omitempty"` + DisableServerSideEncryption bool `json:"disableServerSideEncryption,omitempty"` + Retry request.Retryer + MaxRetries int + FileBufferSize int + DownloadPartitionSize int64 + UploadPartitionSize int64 } ```