Skip to content

Commit

Permalink
AWS Profile is passed through, role-name can be used instead of ARN
Browse files Browse the repository at this point in the history
AWS Profile is passed through, role-name can be used instead of ARN
  • Loading branch information
lnattrass authored Jan 13, 2022
2 parents 3a9c9b8 + b6b3d55 commit df23a17
Showing 3 changed files with 41 additions and 11 deletions.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -7,9 +7,9 @@ While this is possible using the aws cli, it's quite cumbersome:

```bash
ASSUME=$(aws sts assume-role --role-arn "${TARGET_ACCOUNT_ROLE}" --role-session-name="awsu-bash")
export AWS_ACCESS_KEY_ID=$(echo "$ASSUME" | jq '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo "$ASSUME" | jq '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo "$ASSUME" | jq '.Credentials.SessionToken')
export AWS_ACCESS_KEY_ID=$(echo "$ASSUME" | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo "$ASSUME" | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo "$ASSUME" | jq -r '.Credentials.SessionToken')
```

Furthermore, depending on the duration of your tokens, they may expire before you're finished using them.
@@ -18,6 +18,15 @@ AWSU is designed to handle this for you, including performing token renewals at

## Quickstart

Assume a role by name:

```base
$ awsu superman bash
2021/06/08 16:10:07 Running bash with assumedRole arn:aws:iam::468901978831:role/superman, renewal in 47m
$
```

Or assume a role by ARN:
```bash
$ awsu arn:aws:iam::468901978831:role/superman <command>
2021/06/08 16:10:07 Running bash with assumedRole arn:aws:iam::468901978831:role/superman, renewal in 47m
@@ -49,7 +58,7 @@ Flags:
## License

<pre>
Copyright 2021 Square Inc.
Copyright 2022 Square Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
17 changes: 16 additions & 1 deletion assumeRole.go
Original file line number Diff line number Diff line change
@@ -22,6 +22,16 @@ func (c *CLI) renewCredentials() error {
}

svc := sts.New(sess)

// Convert role name to role ARN
if !strings.HasPrefix(c.RoleArn, "arn:") {
callerIdentity, err := svc.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
return fmt.Errorf("failed to discover parent account caller identity: %w", err)
}
c.RoleArn = fmt.Sprintf("arn:aws:iam::%s:role/%s", *callerIdentity.Account, c.RoleArn)
}

req := &sts.AssumeRoleInput{
RoleArn: aws.String(c.RoleArn),
RoleSessionName: aws.String(c.SessionName),
@@ -75,7 +85,12 @@ func renderCredentials(dir string, creds *sts.Credentials) error {
}
defer cf.Close()

cf.WriteString("[default]\n")
awsProfile := os.Getenv("AWS_PROFILE")
if awsProfile == "" {
awsProfile = "default"
}

cf.WriteString(fmt.Sprintf("[%s]\n", awsProfile))
cf.WriteString(fmt.Sprintf("aws_access_key_id=%s\n", *creds.AccessKeyId))
cf.WriteString(fmt.Sprintf("aws_secret_access_key=%s\n", *creds.SecretAccessKey))
cf.WriteString(fmt.Sprintf("aws_session_token=%s\n", *creds.SessionToken))
18 changes: 12 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
@@ -17,19 +17,24 @@ var tempDir string
var credentialsRenew time.Time

type CLI struct {
SessionName string `name:"session-name" short:"s" help:"Session name of the role to assume" default:"awsu"`
SessionName string `name:"session-name" short:"s" help:"Session name of the role to assume" default:"awsu" env:"USER"`
ExternalID string `name:"external-id" short:"e" help:"ExternalID to authenticate the request"`
Duration int64 `name:"duration" short:"d" help:"Duration of the session" default:"3600"`
Verbose bool `name:"verbose" short:"v" help:"Verbose error logging"`
SessionTags map[string]string `name:"session-tags" short:"t" help:"Session tags to apply to the role-assumption (eg: -t tag1=batman)"`
TransitiveTags []string `name:"transitive-tags" short:"x" help:"Keys for session tags which are transitive (eg: -x tag1)"`
SourceIdentity string `name:"source-identity" short:"i" help:"Source identity to set for this session"`
RoleArn string `arg:""`
RoleArn string `arg:"" help:"The role name or ARN you want to assume"`
Command []string `arg:"" passthrough:""`
}

func main() {
ctx := kong.Parse(&CLI{})
ctx := kong.Parse(
&CLI{},
kong.Name("awsu"),
kong.Description("Switch-user for AWS"),
)

err := ctx.Run()
ctx.FatalIfErrorf(err)
}
@@ -71,10 +76,11 @@ func (c *CLI) Run(ctx *kong.Context) error {
cmd := exec.Command(c.Command[0], c.Command[1:]...)
cmd.Env = []string{fmt.Sprintf("AWS_SHARED_CREDENTIALS_FILE=%s", filepath.Join(tempDir, "credentials"))}

// We strip any AWS_ vars (except region vars), to ensure we have precedence over credentials
// We strip any AWS_ vars (except region vars, and profile), to ensure we have precedence over credentials
for _, e := range os.Environ() {
if strings.HasPrefix(e, "AWS_REGION") ||
strings.HasPrefix(e, "AWS_DEFAULT_REGION") ||
if strings.HasPrefix(e, "AWS_REGION=") ||
strings.HasPrefix(e, "AWS_DEFAULT_REGION=") ||
strings.HasPrefix(e, "AWS_PROFILE=") ||
!strings.HasPrefix(e, "AWS_") {
cmd.Env = append(cmd.Env, e)
}

0 comments on commit df23a17

Please sign in to comment.