From cfbaf3e7311dec19bf245ce76c49fea96a17c6bb Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:20:56 +0530 Subject: [PATCH 1/9] Update plugin.go --- plugin.go | 58 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/plugin.go b/plugin.go index 4b461e7..fef57ea 100644 --- a/plugin.go +++ b/plugin.go @@ -441,33 +441,65 @@ func (p *Plugin) createS3Client() *s3.S3 { S3ForcePathStyle: aws.Bool(p.PathStyle), } - sess, err := session.NewSession(conf) - if err != nil { - log.Fatalf("failed to create AWS session: %v", err) - } - + // Set credentials before creating the session if p.Key != "" && p.Secret != "" { conf.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "") } else if p.IdToken != "" && p.AssumeRole != "" { - creds, err := assumeRoleWithWebIdentity(sess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) + // Create a temporary session for assuming the role + tempSess, err := session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create temporary AWS session: %v", err) + } + + creds, err := assumeRoleWithWebIdentity(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) if err != nil { log.Fatalf("failed to assume role with web identity: %v", err) } + + // Update the credentials in the config conf.Credentials = creds } else if p.AssumeRole != "" { - conf.Credentials = assumeRole(p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) + // Create a temporary session for assuming the role + tempSess, err := session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create temporary AWS session: %v", err) + } + + creds := assumeRole(p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) + + // Update the credentials in the config + conf.Credentials = creds } else { - log.Warn("AWS Key and/or Secret not provided (falling back to ec2 instance profile)") + log.Warn("AWS Key and/or Secret not provided (falling back to EC2 instance profile or environment variables)") + } + + // Now create the session with the credentials + sess, err := session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create AWS session: %v", err) } - client := s3.New(sess, conf) + // Create the S3 client using the session + client := s3.New(sess) + // Optionally assume another role if UserRoleArn is provided if len(p.UserRoleArn) > 0 { - confRoleArn := aws.Config{ + log.WithFields(log.Fields{ + "UserRoleArn": p.UserRoleArn, + }).Info("Assuming user role ARN") + + creds := stscreds.NewCredentials(sess, p.UserRoleArn) + // Create a new session with the new credentials + confWithUserRole := &aws.Config{ Region: aws.String(p.Region), - Credentials: stscreds.NewCredentials(sess, p.UserRoleArn), + Credentials: creds, + } + sessWithUserRole, err := session.NewSession(confWithUserRole) + if err != nil { + log.Fatalf("failed to create AWS session with user role: %v", err) } - client = s3.New(sess, &confRoleArn) + + client = s3.New(sessWithUserRole) } return client @@ -485,4 +517,4 @@ func assumeRoleWithWebIdentity(sess *session.Session, roleArn, roleSessionName, log.Fatalf("failed to assume role with web identity: %v", err) } return credentials.NewStaticCredentials(*result.Credentials.AccessKeyId, *result.Credentials.SecretAccessKey, *result.Credentials.SessionToken), nil -} \ No newline at end of file +} From 179e1fee16881df40ec40082d07b932a95e6bb5c Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:28:22 +0530 Subject: [PATCH 2/9] Update plugin.go --- plugin.go | 166 +++++++++++++++++++++++++++--------------------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/plugin.go b/plugin.go index fef57ea..729fd5c 100644 --- a/plugin.go +++ b/plugin.go @@ -99,7 +99,7 @@ type Plugin struct { // set externalID for assume role ExternalID string - // set OIDC ID Token to retrieve temporary credentials + // set OIDC ID Token to retrieve temporary credentials IdToken string } @@ -280,8 +280,7 @@ func matchExtension(match string, stringMap map[string]string) string { return "" } -func assumeRole(roleArn, roleSessionName, externalID string) *credentials.Credentials { - sess, _ := session.NewSession() +func assumeRole(sess *session.Session, roleArn, roleSessionName, externalID string) *credentials.Credentials { client := sts.New(sess) duration := time.Hour * 1 stsProvider := &stscreds.AssumeRoleProvider{ @@ -434,87 +433,88 @@ func (p *Plugin) downloadS3Objects(client *s3.S3, sourceDir string) error { // createS3Client creates and returns an S3 client based on the plugin configuration func (p *Plugin) createS3Client() *s3.S3 { - conf := &aws.Config{ - Region: aws.String(p.Region), - Endpoint: &p.Endpoint, - DisableSSL: aws.Bool(strings.HasPrefix(p.Endpoint, "http://")), - S3ForcePathStyle: aws.Bool(p.PathStyle), - } - - // Set credentials before creating the session - if p.Key != "" && p.Secret != "" { - conf.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "") - } else if p.IdToken != "" && p.AssumeRole != "" { - // Create a temporary session for assuming the role - tempSess, err := session.NewSession(conf) - if err != nil { - log.Fatalf("failed to create temporary AWS session: %v", err) - } - - creds, err := assumeRoleWithWebIdentity(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) - if err != nil { - log.Fatalf("failed to assume role with web identity: %v", err) - } - - // Update the credentials in the config - conf.Credentials = creds - } else if p.AssumeRole != "" { - // Create a temporary session for assuming the role - tempSess, err := session.NewSession(conf) - if err != nil { - log.Fatalf("failed to create temporary AWS session: %v", err) - } - - creds := assumeRole(p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) - - // Update the credentials in the config - conf.Credentials = creds - } else { - log.Warn("AWS Key and/or Secret not provided (falling back to EC2 instance profile or environment variables)") - } - - // Now create the session with the credentials - sess, err := session.NewSession(conf) - if err != nil { - log.Fatalf("failed to create AWS session: %v", err) - } - - // Create the S3 client using the session - client := s3.New(sess) - - // Optionally assume another role if UserRoleArn is provided - if len(p.UserRoleArn) > 0 { - log.WithFields(log.Fields{ - "UserRoleArn": p.UserRoleArn, - }).Info("Assuming user role ARN") - - creds := stscreds.NewCredentials(sess, p.UserRoleArn) - // Create a new session with the new credentials - confWithUserRole := &aws.Config{ - Region: aws.String(p.Region), - Credentials: creds, - } - sessWithUserRole, err := session.NewSession(confWithUserRole) - if err != nil { - log.Fatalf("failed to create AWS session with user role: %v", err) - } - - client = s3.New(sessWithUserRole) - } - - return client + conf := &aws.Config{ + Region: aws.String(p.Region), + Endpoint: &p.Endpoint, + DisableSSL: aws.Bool(strings.HasPrefix(p.Endpoint, "http://")), + S3ForcePathStyle: aws.Bool(p.PathStyle), + } + + // Set credentials before creating the session + if p.Key != "" && p.Secret != "" { + // Use static credentials + conf.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "") + } else if p.IdToken != "" && p.AssumeRole != "" { + // Assume role with web identity + tempSess, err := session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create temporary AWS session: %v", err) + } + + creds, err := assumeRoleWithWebIdentity(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) + if err != nil { + log.Fatalf("failed to assume role with web identity: %v", err) + } + + // Update the credentials in the config + conf.Credentials = creds + } else if p.AssumeRole != "" { + // Standard AssumeRole + tempSess, err := session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create temporary AWS session: %v", err) + } + + creds := assumeRole(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) + + // Update the credentials in the config + conf.Credentials = creds + } else { + log.Warn("AWS Key and/or Secret not provided (falling back to EC2 instance profile or environment variables)") + } + + // Now create the main session with the credentials + sess, err := session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create AWS session: %v", err) + } + + // Create the S3 client using the session + client := s3.New(sess) + + // Optionally assume another role if UserRoleArn is provided + if len(p.UserRoleArn) > 0 { + log.WithFields(log.Fields{ + "UserRoleArn": p.UserRoleArn, + }).Info("Assuming user role ARN") + + creds := stscreds.NewCredentials(sess, p.UserRoleArn) + // Create a new session with the new credentials + confWithUserRole := &aws.Config{ + Region: aws.String(p.Region), + Credentials: creds, + } + sessWithUserRole, err := session.NewSession(confWithUserRole) + if err != nil { + log.Fatalf("failed to create AWS session with user role: %v", err) + } + + client = s3.New(sessWithUserRole) + } + + return client } func assumeRoleWithWebIdentity(sess *session.Session, roleArn, roleSessionName, idToken string) (*credentials.Credentials, error) { - svc := sts.New(sess) - input := &sts.AssumeRoleWithWebIdentityInput{ - RoleArn: aws.String(roleArn), - RoleSessionName: aws.String(roleSessionName), - WebIdentityToken: aws.String(idToken), - } - result, err := svc.AssumeRoleWithWebIdentity(input) - if err != nil { - log.Fatalf("failed to assume role with web identity: %v", err) - } - return credentials.NewStaticCredentials(*result.Credentials.AccessKeyId, *result.Credentials.SecretAccessKey, *result.Credentials.SessionToken), nil + svc := sts.New(sess) + input := &sts.AssumeRoleWithWebIdentityInput{ + RoleArn: aws.String(roleArn), + RoleSessionName: aws.String(roleSessionName), + WebIdentityToken: aws.String(idToken), + } + result, err := svc.AssumeRoleWithWebIdentity(input) + if err != nil { + log.Fatalf("failed to assume role with web identity: %v", err) + } + return credentials.NewStaticCredentials(*result.Credentials.AccessKeyId, *result.Credentials.SecretAccessKey, *result.Credentials.SessionToken), nil } From fceb5fe2b4d2a82f3b3536f791354177825386ec Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Sun, 15 Sep 2024 00:03:50 +0530 Subject: [PATCH 3/9] Update plugin.go --- plugin.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/plugin.go b/plugin.go index 729fd5c..9b78e69 100644 --- a/plugin.go +++ b/plugin.go @@ -440,10 +440,14 @@ func (p *Plugin) createS3Client() *s3.S3 { S3ForcePathStyle: aws.Bool(p.PathStyle), } + var creds *credentials.Credentials + var err error + // Set credentials before creating the session if p.Key != "" && p.Secret != "" { // Use static credentials - conf.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "") + creds = credentials.NewStaticCredentials(p.Key, p.Secret, "") + conf.Credentials = creds } else if p.IdToken != "" && p.AssumeRole != "" { // Assume role with web identity tempSess, err := session.NewSession(conf) @@ -451,7 +455,7 @@ func (p *Plugin) createS3Client() *s3.S3 { log.Fatalf("failed to create temporary AWS session: %v", err) } - creds, err := assumeRoleWithWebIdentity(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) + creds, err = assumeRoleWithWebIdentity(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) if err != nil { log.Fatalf("failed to assume role with web identity: %v", err) } @@ -465,7 +469,7 @@ func (p *Plugin) createS3Client() *s3.S3 { log.Fatalf("failed to create temporary AWS session: %v", err) } - creds := assumeRole(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) + creds = assumeRole(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) // Update the credentials in the config conf.Credentials = creds @@ -482,18 +486,21 @@ func (p *Plugin) createS3Client() *s3.S3 { // Create the S3 client using the session client := s3.New(sess) - // Optionally assume another role if UserRoleArn is provided + // Only attempt to assume UserRoleArn if it's provided if len(p.UserRoleArn) > 0 { log.WithFields(log.Fields{ "UserRoleArn": p.UserRoleArn, }).Info("Assuming user role ARN") - creds := stscreds.NewCredentials(sess, p.UserRoleArn) + // Create new credentials by assuming the UserRoleArn + creds = stscreds.NewCredentials(sess, p.UserRoleArn) + // Create a new session with the new credentials confWithUserRole := &aws.Config{ Region: aws.String(p.Region), Credentials: creds, } + sessWithUserRole, err := session.NewSession(confWithUserRole) if err != nil { log.Fatalf("failed to create AWS session with user role: %v", err) From 8f28375469d362d81227ae3d43f849aa3746c8d7 Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Sun, 15 Sep 2024 01:52:29 +0530 Subject: [PATCH 4/9] Update plugin.go --- plugin.go | 156 +++++++++++++++++++++++------------------------------- 1 file changed, 66 insertions(+), 90 deletions(-) diff --git a/plugin.go b/plugin.go index 9b78e69..d59e4dd 100644 --- a/plugin.go +++ b/plugin.go @@ -29,6 +29,7 @@ type Plugin struct { AssumeRoleSessionName string Bucket string UserRoleArn string + UserRoleExternalID string // if not "", enable server-side encryption // valid values are: @@ -99,7 +100,7 @@ type Plugin struct { // set externalID for assume role ExternalID string - // set OIDC ID Token to retrieve temporary credentials + // set OIDC ID Token to retrieve temporary credentials IdToken string } @@ -280,7 +281,8 @@ func matchExtension(match string, stringMap map[string]string) string { return "" } -func assumeRole(sess *session.Session, roleArn, roleSessionName, externalID string) *credentials.Credentials { +func assumeRole(roleArn, roleSessionName, externalID string) *credentials.Credentials { + sess, _ := session.NewSession() client := sts.New(sess) duration := time.Hour * 1 stsProvider := &stscreds.AssumeRoleProvider{ @@ -433,95 +435,69 @@ func (p *Plugin) downloadS3Objects(client *s3.S3, sourceDir string) error { // createS3Client creates and returns an S3 client based on the plugin configuration func (p *Plugin) createS3Client() *s3.S3 { - conf := &aws.Config{ - Region: aws.String(p.Region), - Endpoint: &p.Endpoint, - DisableSSL: aws.Bool(strings.HasPrefix(p.Endpoint, "http://")), - S3ForcePathStyle: aws.Bool(p.PathStyle), - } - - var creds *credentials.Credentials - var err error - - // Set credentials before creating the session - if p.Key != "" && p.Secret != "" { - // Use static credentials - creds = credentials.NewStaticCredentials(p.Key, p.Secret, "") - conf.Credentials = creds - } else if p.IdToken != "" && p.AssumeRole != "" { - // Assume role with web identity - tempSess, err := session.NewSession(conf) - if err != nil { - log.Fatalf("failed to create temporary AWS session: %v", err) - } - - creds, err = assumeRoleWithWebIdentity(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) - if err != nil { - log.Fatalf("failed to assume role with web identity: %v", err) - } - - // Update the credentials in the config - conf.Credentials = creds - } else if p.AssumeRole != "" { - // Standard AssumeRole - tempSess, err := session.NewSession(conf) - if err != nil { - log.Fatalf("failed to create temporary AWS session: %v", err) - } - - creds = assumeRole(tempSess, p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) - - // Update the credentials in the config - conf.Credentials = creds - } else { - log.Warn("AWS Key and/or Secret not provided (falling back to EC2 instance profile or environment variables)") - } - - // Now create the main session with the credentials - sess, err := session.NewSession(conf) - if err != nil { - log.Fatalf("failed to create AWS session: %v", err) - } - - // Create the S3 client using the session - client := s3.New(sess) - - // Only attempt to assume UserRoleArn if it's provided - if len(p.UserRoleArn) > 0 { - log.WithFields(log.Fields{ - "UserRoleArn": p.UserRoleArn, - }).Info("Assuming user role ARN") - - // Create new credentials by assuming the UserRoleArn - creds = stscreds.NewCredentials(sess, p.UserRoleArn) - - // Create a new session with the new credentials - confWithUserRole := &aws.Config{ - Region: aws.String(p.Region), - Credentials: creds, - } - - sessWithUserRole, err := session.NewSession(confWithUserRole) - if err != nil { - log.Fatalf("failed to create AWS session with user role: %v", err) - } - - client = s3.New(sessWithUserRole) - } - - return client + conf := &aws.Config{ + Region: aws.String(p.Region), + Endpoint: &p.Endpoint, + DisableSSL: aws.Bool(strings.HasPrefix(p.Endpoint, "http://")), + S3ForcePathStyle: aws.Bool(p.PathStyle), + } + + sess, err := session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create AWS session: %v", err) + } + + if p.Key != "" && p.Secret != "" { + conf.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "") + } else if p.IdToken != "" && p.AssumeRole != "" { + creds, err := assumeRoleWithWebIdentity(sess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) + if err != nil { + log.Fatalf("failed to assume role with web identity: %v", err) + } + conf.Credentials = creds + } else if p.AssumeRole != "" { + conf.Credentials = assumeRole(p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) + } else { + log.Warn("AWS Key and/or Secret not provided (falling back to ec2 instance profile)") + } + + client := s3.New(sess, conf) + + if len(p.UserRoleArn) > 0 { + // Create new credentials by assuming the UserRoleArn (with ExternalID when provided) + creds := stscreds.NewCredentials(sess, p.UserRoleArn, func(provider *stscreds.AssumeRoleProvider) { + if p.UserRoleExternalID != "" { + provider.ExternalID = aws.String(p.UserRoleExternalID) + } + }) + + // Create a new session with the new credentials + confWithUserRole := &aws.Config{ + Region: aws.String(p.Region), + Credentials: creds, + } + + sessWithUserRole, err := session.NewSession(confWithUserRole) + if err != nil { + log.Fatalf("failed to create AWS session with user role: %v", err) + } + + client = s3.New(sessWithUserRole) + } + + return client } func assumeRoleWithWebIdentity(sess *session.Session, roleArn, roleSessionName, idToken string) (*credentials.Credentials, error) { - svc := sts.New(sess) - input := &sts.AssumeRoleWithWebIdentityInput{ - RoleArn: aws.String(roleArn), - RoleSessionName: aws.String(roleSessionName), - WebIdentityToken: aws.String(idToken), - } - result, err := svc.AssumeRoleWithWebIdentity(input) - if err != nil { - log.Fatalf("failed to assume role with web identity: %v", err) - } - return credentials.NewStaticCredentials(*result.Credentials.AccessKeyId, *result.Credentials.SecretAccessKey, *result.Credentials.SessionToken), nil + svc := sts.New(sess) + input := &sts.AssumeRoleWithWebIdentityInput{ + RoleArn: aws.String(roleArn), + RoleSessionName: aws.String(roleSessionName), + WebIdentityToken: aws.String(idToken), + } + result, err := svc.AssumeRoleWithWebIdentity(input) + if err != nil { + log.Fatalf("failed to assume role with web identity: %v", err) + } + return credentials.NewStaticCredentials(*result.Credentials.AccessKeyId, *result.Credentials.SecretAccessKey, *result.Credentials.SessionToken), nil } From 415d47ebde8ba89132b9e36e80985356bc3b3169 Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Sun, 15 Sep 2024 01:56:55 +0530 Subject: [PATCH 5/9] Update main.go --- main.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 6cf56a8..628963d 100644 --- a/main.go +++ b/main.go @@ -52,6 +52,11 @@ func main() { Usage: "AWS user role", EnvVar: "PLUGIN_USER_ROLE_ARN,AWS_USER_ROLE_ARN", }, + cli.StringFlag{ + Name: "user-role-external-id", + Usage: "external ID to use when assuming secondary role", + EnvVar: "PLUGIN_USER_ROLE_EXTERNAL_ID", + }, cli.StringFlag{ Name: "bucket", Usage: "aws bucket", @@ -166,6 +171,7 @@ func run(c *cli.Context) error { AssumeRoleSessionName: c.String("assume-role-session-name"), Bucket: c.String("bucket"), UserRoleArn: c.String("user-role-arn"), + UserRoleExternalID: c.String("user-role-external-id"), Region: c.String("region"), Access: c.String("acl"), Source: c.String("source"), @@ -181,7 +187,7 @@ func run(c *cli.Context) error { PathStyle: c.Bool("path-style"), DryRun: c.Bool("dry-run"), ExternalID: c.String("external-id"), - IdToken: c.String("oidc-token-id"), + IdToken: c.String("oidc-token-id"), } return plugin.Exec() From 02939109b250543c6589ee2d24a7b0f507e24fc5 Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Sun, 15 Sep 2024 01:59:38 +0530 Subject: [PATCH 6/9] Update plugin.go --- plugin.go | 126 +++++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/plugin.go b/plugin.go index d59e4dd..4d1584d 100644 --- a/plugin.go +++ b/plugin.go @@ -100,7 +100,7 @@ type Plugin struct { // set externalID for assume role ExternalID string - // set OIDC ID Token to retrieve temporary credentials + // set OIDC ID Token to retrieve temporary credentials IdToken string } @@ -435,69 +435,69 @@ func (p *Plugin) downloadS3Objects(client *s3.S3, sourceDir string) error { // createS3Client creates and returns an S3 client based on the plugin configuration func (p *Plugin) createS3Client() *s3.S3 { - conf := &aws.Config{ - Region: aws.String(p.Region), - Endpoint: &p.Endpoint, - DisableSSL: aws.Bool(strings.HasPrefix(p.Endpoint, "http://")), - S3ForcePathStyle: aws.Bool(p.PathStyle), - } - - sess, err := session.NewSession(conf) - if err != nil { - log.Fatalf("failed to create AWS session: %v", err) - } - - if p.Key != "" && p.Secret != "" { - conf.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "") - } else if p.IdToken != "" && p.AssumeRole != "" { - creds, err := assumeRoleWithWebIdentity(sess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) - if err != nil { - log.Fatalf("failed to assume role with web identity: %v", err) - } - conf.Credentials = creds - } else if p.AssumeRole != "" { - conf.Credentials = assumeRole(p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) - } else { - log.Warn("AWS Key and/or Secret not provided (falling back to ec2 instance profile)") - } - - client := s3.New(sess, conf) - - if len(p.UserRoleArn) > 0 { - // Create new credentials by assuming the UserRoleArn (with ExternalID when provided) - creds := stscreds.NewCredentials(sess, p.UserRoleArn, func(provider *stscreds.AssumeRoleProvider) { - if p.UserRoleExternalID != "" { - provider.ExternalID = aws.String(p.UserRoleExternalID) - } - }) - - // Create a new session with the new credentials - confWithUserRole := &aws.Config{ - Region: aws.String(p.Region), - Credentials: creds, - } - - sessWithUserRole, err := session.NewSession(confWithUserRole) - if err != nil { - log.Fatalf("failed to create AWS session with user role: %v", err) - } - - client = s3.New(sessWithUserRole) - } - - return client + conf := &aws.Config{ + Region: aws.String(p.Region), + Endpoint: &p.Endpoint, + DisableSSL: aws.Bool(strings.HasPrefix(p.Endpoint, "http://")), + S3ForcePathStyle: aws.Bool(p.PathStyle), + } + + sess, err := session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create AWS session: %v", err) + } + + if p.Key != "" && p.Secret != "" { + conf.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "") + } else if p.IdToken != "" && p.AssumeRole != "" { + creds, err := assumeRoleWithWebIdentity(sess, p.AssumeRole, p.AssumeRoleSessionName, p.IdToken) + if err != nil { + log.Fatalf("failed to assume role with web identity: %v", err) + } + conf.Credentials = creds + } else if p.AssumeRole != "" { + conf.Credentials = assumeRole(p.AssumeRole, p.AssumeRoleSessionName, p.ExternalID) + } else { + log.Warn("AWS Key and/or Secret not provided (falling back to ec2 instance profile)") + } + + client := s3.New(sess, conf) + + if len(p.UserRoleArn) > 0 { + // Create new credentials by assuming the UserRoleArn (with ExternalID when provided) + creds := stscreds.NewCredentials(sess, p.UserRoleArn, func(provider *stscreds.AssumeRoleProvider) { + if p.UserRoleExternalID != "" { + provider.ExternalID = aws.String(p.UserRoleExternalID) + } + }) + + // Create a new session with the new credentials + confWithUserRole := &aws.Config{ + Region: aws.String(p.Region), + Credentials: creds, + } + + sessWithUserRole, err := session.NewSession(confWithUserRole) + if err != nil { + log.Fatalf("failed to create AWS session with user role: %v", err) + } + + client = s3.New(sessWithUserRole) + } + + return client } func assumeRoleWithWebIdentity(sess *session.Session, roleArn, roleSessionName, idToken string) (*credentials.Credentials, error) { - svc := sts.New(sess) - input := &sts.AssumeRoleWithWebIdentityInput{ - RoleArn: aws.String(roleArn), - RoleSessionName: aws.String(roleSessionName), - WebIdentityToken: aws.String(idToken), - } - result, err := svc.AssumeRoleWithWebIdentity(input) - if err != nil { - log.Fatalf("failed to assume role with web identity: %v", err) - } - return credentials.NewStaticCredentials(*result.Credentials.AccessKeyId, *result.Credentials.SecretAccessKey, *result.Credentials.SessionToken), nil + svc := sts.New(sess) + input := &sts.AssumeRoleWithWebIdentityInput{ + RoleArn: aws.String(roleArn), + RoleSessionName: aws.String(roleSessionName), + WebIdentityToken: aws.String(idToken), + } + result, err := svc.AssumeRoleWithWebIdentity(input) + if err != nil { + log.Fatalf("failed to assume role with web identity: %v", err) + } + return credentials.NewStaticCredentials(*result.Credentials.AccessKeyId, *result.Credentials.SecretAccessKey, *result.Credentials.SessionToken), nil } From acd69f4ffb3afc86a69d497590692375af8509e7 Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:17:29 +0530 Subject: [PATCH 7/9] Update plugin.go --- plugin.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugin.go b/plugin.go index 4d1584d..332da77 100644 --- a/plugin.go +++ b/plugin.go @@ -29,7 +29,6 @@ type Plugin struct { AssumeRoleSessionName string Bucket string UserRoleArn string - UserRoleExternalID string // if not "", enable server-side encryption // valid values are: @@ -461,10 +460,19 @@ func (p *Plugin) createS3Client() *s3.S3 { log.Warn("AWS Key and/or Secret not provided (falling back to ec2 instance profile)") } + sess, err = session.NewSession(conf) + if err != nil { + log.Fatalf("failed to create AWS session: %v", err) + } + client := s3.New(sess, conf) if len(p.UserRoleArn) > 0 { - // Create new credentials by assuming the UserRoleArn (with ExternalID when provided) + log.WithFields(log.Fields{ + "UserRoleArn": p.UserRoleArn, + }).Info("Assuming user role ARN") + + // Create new credentials by assuming the UserRoleArn with ExternalID creds := stscreds.NewCredentials(sess, p.UserRoleArn, func(provider *stscreds.AssumeRoleProvider) { if p.UserRoleExternalID != "" { provider.ExternalID = aws.String(p.UserRoleExternalID) From d426c64ab1e69e289a9f578ae00960f3fd314de0 Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:25:53 +0530 Subject: [PATCH 8/9] Update plugin.go --- plugin.go | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin.go b/plugin.go index e4cb0f7..7a7301e 100644 --- a/plugin.go +++ b/plugin.go @@ -29,6 +29,7 @@ type Plugin struct { AssumeRoleSessionName string Bucket string UserRoleArn string + UserRoleExternalID string // New field for UserRoleArn ExternalID // if not "", enable server-side encryption // valid values are: From 8813c3d87649c57cb1cc1abd326c0df418252748 Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:53:09 +0530 Subject: [PATCH 9/9] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 35fa789..7fa7c6d 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ docker: Error response from daemon: Container command Execute from the working directory: -* For upload +* For Upload ``` docker run --rm \ -e PLUGIN_SOURCE= \ @@ -61,7 +61,7 @@ docker run --rm \ plugins/s3 --dry-run ``` -* For download +* For Download ``` docker run --rm \ -e PLUGIN_SOURCE= \