@@ -98,6 +98,9 @@ type Plugin struct {
9898
9999 // set externalID for assume role
100100 ExternalID string
101+
102+ // set OIDC ID Token to retrieve temporary credentials
103+ IdToken string
101104}
102105
103106// Exec runs the plugin
@@ -431,31 +434,55 @@ func (p *Plugin) downloadS3Objects(client *s3.S3, sourceDir string) error {
431434
432435// createS3Client creates and returns an S3 client based on the plugin configuration
433436func (p * Plugin ) createS3Client () * s3.S3 {
434- conf := & aws.Config {
435- Region : aws .String (p .Region ),
436- Endpoint : & p .Endpoint ,
437- DisableSSL : aws .Bool (strings .HasPrefix (p .Endpoint , "http://" )),
438- S3ForcePathStyle : aws .Bool (p .PathStyle ),
439- }
440-
441- if p .Key != "" && p .Secret != "" {
442- conf .Credentials = credentials .NewStaticCredentials (p .Key , p .Secret , "" )
443- } else if p .AssumeRole != "" {
444- conf .Credentials = assumeRole (p .AssumeRole , p .AssumeRoleSessionName , p .ExternalID )
445- } else {
446- log .Warn ("AWS Key and/or Secret not provided (falling back to ec2 instance profile)" )
447- }
448-
449- sess , _ := session .NewSession (conf )
450- client := s3 .New (sess )
451-
452- if len (p .UserRoleArn ) > 0 {
453- confRoleArn := aws.Config {
454- Region : aws .String (p .Region ),
455- Credentials : stscreds .NewCredentials (sess , p .UserRoleArn ),
456- }
457- client = s3 .New (sess , & confRoleArn )
458- }
459-
460- return client
437+ conf := & aws.Config {
438+ Region : aws .String (p .Region ),
439+ Endpoint : & p .Endpoint ,
440+ DisableSSL : aws .Bool (strings .HasPrefix (p .Endpoint , "http://" )),
441+ S3ForcePathStyle : aws .Bool (p .PathStyle ),
442+ }
443+
444+ sess , err := session .NewSession (conf )
445+ if err != nil {
446+ log .Fatalf ("failed to create AWS session: %v" , err )
447+ }
448+
449+ if p .Key != "" && p .Secret != "" {
450+ conf .Credentials = credentials .NewStaticCredentials (p .Key , p .Secret , "" )
451+ } else if p .IdToken != "" && p .AssumeRole != "" {
452+ creds , err := assumeRoleWithWebIdentity (sess , p .AssumeRole , p .AssumeRoleSessionName , p .IdToken )
453+ if err != nil {
454+ log .Fatalf ("failed to assume role with web identity: %v" , err )
455+ }
456+ conf .Credentials = creds
457+ } else if p .AssumeRole != "" {
458+ conf .Credentials = assumeRole (p .AssumeRole , p .AssumeRoleSessionName , p .ExternalID )
459+ } else {
460+ log .Warn ("AWS Key and/or Secret not provided (falling back to ec2 instance profile)" )
461+ }
462+
463+ client := s3 .New (sess , conf )
464+
465+ if len (p .UserRoleArn ) > 0 {
466+ confRoleArn := aws.Config {
467+ Region : aws .String (p .Region ),
468+ Credentials : stscreds .NewCredentials (sess , p .UserRoleArn ),
469+ }
470+ client = s3 .New (sess , & confRoleArn )
471+ }
472+
473+ return client
461474}
475+
476+ func assumeRoleWithWebIdentity (sess * session.Session , roleArn , roleSessionName , idToken string ) (* credentials.Credentials , error ) {
477+ svc := sts .New (sess )
478+ input := & sts.AssumeRoleWithWebIdentityInput {
479+ RoleArn : aws .String (roleArn ),
480+ RoleSessionName : aws .String (roleSessionName ),
481+ WebIdentityToken : aws .String (idToken ),
482+ }
483+ result , err := svc .AssumeRoleWithWebIdentity (input )
484+ if err != nil {
485+ log .Fatalf ("failed to assume role with web identity: %v" , err )
486+ }
487+ return credentials .NewStaticCredentials (* result .Credentials .AccessKeyId , * result .Credentials .SecretAccessKey , * result .Credentials .SessionToken ), nil
488+ }
0 commit comments