From ecb70b88a8d04896a6c741588f1a605efa856b8c Mon Sep 17 00:00:00 2001 From: grant-higgins-0 <92458368+grant-higgins-0@users.noreply.github.com> Date: Wed, 15 Jan 2025 09:44:09 -0600 Subject: [PATCH] add support for assumed role credentials in the s3 backend (#219) * add support for assumed role credentials in the s3 backend * respond to pr comments * formatting --- CHANGELOG.md | 2 ++ backend/s3/options.go | 8 ++++++++ backend/s3/options_test.go | 13 +++++++++++++ docs/s3.md | 22 +++++++++++++++++----- 4 files changed, 40 insertions(+), 5 deletions(-) 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 } ```