Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Support external-ids when authenticating by STS:AssumeRole #826

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,20 +203,24 @@ or until there are only resources with errors left.

### AWS Credentials

There are two ways to authenticate *aws-nuke*. There are static credentials and
profiles. The later one can be configured in the shared credentials file (ie
There are three ways to authenticate *aws-nuke*. There are static credentials,
assuming roles and profiles. The first two methods are passed in at the
command line. The third can be configured in the shared credentials file (ie
Comment on lines +207 to +208
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assuming roles and profiles. The first two methods are passed in at the
command line. The third can be configured in the shared credentials file (ie
assuming roles and profiles. The first two methods are passed in at the
command line. The third can be configured in the shared credentials file (ie

Is there a reason for the two spaces between sentences?

`~/.aws/credentials`) or the shared config file (ie `~/.aws/config`).

To use *static credentials* the command line flags `--access-key-id` and
`--secret-access-key` are required. The flag `--session-token` is only required
for temporary sessions.

To use *assumed roles* the command line flag `--assume-role-arn` is required.
If you rely on a secret
[external ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html)
field for your role assumption, you can supply it with the command line flag `--external-id`.

To use *shared profiles* the command line flag `--profile` is required. The
profile must be either defined with static credentials in the [shared
credential
file](https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html)
or in [shared config
file](https://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html) with an
profile must be either defined with static credentials in the
[shared credential file](https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html)
or in [shared config file](https://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html) with an
assuming role.

### Using custom AWS endpoint
Expand Down
5 changes: 5 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ func NewRootCommand() *cobra.Command {
"AWS IAM role arn to assume. "+
"The credentials provided via --access-key-id or --profile must "+
"be allowed to assume this role. ")
command.PersistentFlags().StringVar(
&creds.ExternalId, "external-id", "",
"AWS STS External ID parameter. "+
"If your assumed role is secured with an External ID string, "+
"pass this parameter. ")
command.PersistentFlags().StringVar(
&defaultRegion, "default-region", "",
"Custom default region name.")
Expand Down
15 changes: 14 additions & 1 deletion pkg/awsutil/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Credentials struct {
SecretAccessKey string
SessionToken string
AssumeRoleArn string
ExternalId string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ExternalId string
ExternalID string

I would kindly ask you to write ID in uppercase. I know we are not consistent, but we try to 😄


Credentials *credentials.Credentials

Expand All @@ -52,6 +53,10 @@ func (c *Credentials) HasAwsCredentials() bool {
return c.Credentials != nil
}

func (c *Credentials) HasExternalId() bool {
return strings.TrimSpace(c.ExternalId) != ""
}

func (c *Credentials) HasKeys() bool {
return strings.TrimSpace(c.AccessKeyID) != "" ||
strings.TrimSpace(c.SecretAccessKey) != "" ||
Expand Down Expand Up @@ -114,7 +119,15 @@ func (c *Credentials) rootSession() (*session.Session, error) {

// if given a role to assume, overwrite the session credentials with assume role credentials
if c.AssumeRoleArn != "" {
sess.Config.Credentials = stscreds.NewCredentials(sess, c.AssumeRoleArn)
if c.HasExternalId() {
log.Debugf("assuming role %s, externalID found", c.AssumeRoleArn)
sess.Config.Credentials = stscreds.NewCredentials(sess, c.AssumeRoleArn, func(p *stscreds.AssumeRoleProvider) {
p.ExternalID = &c.ExternalId
})
} else {
log.Debugf("assuming role %s with no externalID", c.AssumeRoleArn)
sess.Config.Credentials = stscreds.NewCredentials(sess, c.AssumeRoleArn)
}
}

c.session = sess
Expand Down