Skip to content

Commit

Permalink
Merge pull request #97 from common-fate/jackmeyer/cf-624-issue-69-pro…
Browse files Browse the repository at this point in the history
…blems-with-assuming-roles

problems with assuming roles
  • Loading branch information
meyerjrr authored Mar 11, 2022
2 parents 6290127 + 1c58440 commit a74362a
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 70 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"request": "launch",
"mode": "auto",
"program": "cmd/assume/main.go",
"args": ["demo-sandbox1"],
"args": ["cf-testing", "-c"],
"env": {
"FORCE_NO_ALIAS": true,
"AWS_PROFILE": "demo-sandbox1"
Expand Down
1 change: 1 addition & 0 deletions pkg/assume/assume.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ func AssumeCommand(c *cli.Context) error {

return nil
}

openBrower := assumeFlags.Bool("console") || assumeFlags.Bool("active-role")
if openBrower {
// these are just labels for the tabs so we may need to updates these for the sso role context
Expand Down
2 changes: 1 addition & 1 deletion pkg/assume/unset.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ func UnsetAction(c *cli.Context) error {
//interacts with scripts to unset all the aws environment variables
fmt.Print("GrantedDesume")
green := color.New(color.FgGreen)
green.Fprintf(color.Error, "\nSession credentials revoked\n\n")
green.Fprintf(color.Error, "\nEnvironment variables cleared\n\n")
return nil
}
14 changes: 12 additions & 2 deletions pkg/browsers/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ var ServiceMap = map[string]string{
"iam": "iamv2",
}

var globalServiceMap = map[string]bool{
"iam": true,
"route53": true,
"r53": true,
}

func OpenWithChromiumProfile(url string, labels RoleLabels, selectedBrowser Browser) error {
cfg, err := config.Load()
if err != nil {
Expand Down Expand Up @@ -284,9 +290,13 @@ func makeDestinationURL(service string, region string) (string, error) {

dest := prefix + serv + "/home"

//NOTE here: excluding iam here and possibly others as the region isnt in the uri of the webpage on the console
if region != "" || serv != "iam" {
//excluding region here if the service is apart of the global service list
//incomplete list of global services
_, global := globalServiceMap[service]
hasRegion := region != ""
if !global && hasRegion {
dest = dest + "?region=" + region

}

return dest, nil
Expand Down
10 changes: 4 additions & 6 deletions pkg/cfaws/assumer_aws_azure_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,13 @@ func (aal *AwsAzureLoginAssumer) AssumeTerminal(ctx context.Context, c *CFShared
return aws.Credentials{}, err
}
// reload the profile from disk to check for the new credentials
cfg, err := c.AwsConfig(ctx, false)
cfg, err := config.LoadDefaultConfig(ctx,
config.WithSharedConfigProfile(c.Name),
)
if err != nil {
return aws.Credentials{}, err
}
creds, err = aws.NewCredentialsCache(cfg.Credentials).Retrieve(ctx)
if err != nil {
return aws.Credentials{}, err
}
return creds, nil
return aws.NewCredentialsCache(cfg.Credentials).Retrieve(ctx)
}

func (aal *AwsAzureLoginAssumer) AssumeConsole(ctx context.Context, c *CFSharedConfig, args []string) (aws.Credentials, error) {
Expand Down
12 changes: 5 additions & 7 deletions pkg/cfaws/assumer_aws_iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ type AwsIamAssumer struct {
// Default behaviour is to use the sdk to retrieve the credentials from the file
// For launching the console there is an extra step GetFederationToken that happens after this to get a session token
func (aia *AwsIamAssumer) AssumeTerminal(ctx context.Context, c *CFSharedConfig, args []string) (aws.Credentials, error) {
cfg, err := c.AwsConfig(ctx, false)
if err != nil {
return aws.Credentials{}, err
}
creds, err := aws.NewCredentialsCache(cfg.Credentials).Retrieve(ctx)
creds, err := aws.NewCredentialsCache(&CredProv{Credentials: c.AWSConfig.Credentials}).Retrieve(ctx)
if err != nil {
return aws.Credentials{}, err
}
Expand Down Expand Up @@ -51,11 +47,13 @@ func (aia *AwsIamAssumer) ProfileMatchesType(rawProfile configparser.Dict, parse

// GetFederationToken is used when launching a console session with longlived IAM credentials profiles
func getFederationToken(ctx context.Context, c *CFSharedConfig) (aws.Credentials, error) {
cfg, err := c.AwsConfig(ctx, false)
cfg := aws.NewConfig()
r, _, err := c.Region(ctx)
if err != nil {
return aws.Credentials{}, err
}
client := sts.NewFromConfig(cfg)
cfg.Region = r
client := sts.NewFromConfig(*cfg)
out, err := client.GetFederationToken(ctx, &sts.GetFederationTokenInput{Name: aws.String("Granted@" + c.Name)})
if err != nil {
return aws.Credentials{}, err
Expand Down
16 changes: 10 additions & 6 deletions pkg/cfaws/assumer_aws_sso.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,20 @@ func (c *CFSharedConfig) SSOLogin(ctx context.Context) (aws.Credentials, error)
requiresAssuming := false
if len(c.Parents) > 0 {
rootProfile = c.Parents[0]

requiresAssuming = true
}

ssoTokenKey := rootProfile.AWSConfig.SSOStartURL
cfg, err := rootProfile.AwsConfig(ctx, true)
if err != nil {
return aws.Credentials{}, err
}
cfg := aws.NewConfig()
cfg.Region = rootProfile.AWSConfig.SSORegion

cachedToken := GetValidCachedToken(ssoTokenKey)
var err error
newToken := false
if cachedToken == nil {
newToken = true
cachedToken, err = SSODeviceCodeFlow(ctx, cfg, rootProfile)
cachedToken, err = SSODeviceCodeFlow(ctx, *cfg, rootProfile)
if err != nil {
return aws.Credentials{}, err
}
Expand All @@ -66,8 +67,9 @@ func (c *CFSharedConfig) SSOLogin(ctx context.Context) (aws.Credentials, error)
if newToken {
StoreSSOToken(ssoTokenKey, *cachedToken)
}

// create sso client
ssoClient := sso.NewFromConfig(cfg)
ssoClient := sso.NewFromConfig(*cfg)
res, err := ssoClient.GetRoleCredentials(ctx, &sso.GetRoleCredentialsInput{AccessToken: &cachedToken.AccessToken, AccountId: &rootProfile.AWSConfig.SSOAccountID, RoleName: &rootProfile.AWSConfig.SSORoleName})
if err != nil {
var unauthorised *ssotypes.UnauthorizedException
Expand All @@ -94,9 +96,11 @@ func (c *CFSharedConfig) SSOLogin(ctx context.Context) (aws.Credentials, error)
// in order to support profiles which do not specify a region, we use the default region when assuming the role

stsClient := sts.New(sts.Options{Credentials: aws.NewCredentialsCache(credProvider), Region: region})

stsRes, err := stsClient.AssumeRole(ctx, &sts.AssumeRoleInput{
RoleArn: &p.AWSConfig.RoleARN,
RoleSessionName: &p.Name,
TokenCode: &p.AWSConfig.MFASerial,
})
if err != nil {
return aws.Credentials{}, err
Expand Down
7 changes: 2 additions & 5 deletions pkg/cfaws/creds.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ func GetEnvCredentials(ctx context.Context) aws.Credentials {

func GetCredentialsCreds(ctx context.Context, c *CFSharedConfig) (aws.Credentials, error) {
//check to see if the creds are already exported
cfg, err := c.AwsConfig(ctx, false)
if err != nil {
return aws.Credentials{}, err
}
creds, _ := aws.NewCredentialsCache(cfg.Credentials).Retrieve(ctx)
creds, _ := aws.NewCredentialsCache(&CredProv{Credentials: c.AWSConfig.Credentials}).Retrieve(ctx)

//check creds are valid - return them if they are
if creds.HasKeys() && !creds.Expired() {
return creds, nil
Expand Down
42 changes: 0 additions & 42 deletions pkg/cfaws/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/bigkevmcd/go-configparser"
"github.com/common-fate/granted/pkg/debug"
"github.com/fatih/color"
Expand Down Expand Up @@ -141,51 +140,10 @@ func (c CFSharedConfigs) ProfileNames() []string {
return names
}

// func (c *CFSharedConfig) AwsConfig(ctx context.Context, useSSORegion bool) config.SharedConfig {
// if useSSORegion {
// // With region forces this config to use the profile region, ignoring region configured with environment variables
// opts = append(opts, config.WithRegion(c.AWSConfig.SSORegion))
// } else if c.AWSConfig.Region != "" {
// // With region forces this config to use the profile region, ignoring region configured with environment variables
// // if region is not configured for this profile, use the aws_default_region
// opts = append(opts, config.WithRegion(c.AWSConfig.Region))
// }
// }

func (c *CFSharedConfig) AssumeConsole(ctx context.Context, args []string) (aws.Credentials, error) {
return AssumerFromType(c.ProfileType).AssumeConsole(ctx, c, args)
}

func (c *CFSharedConfig) AssumeTerminal(ctx context.Context, args []string) (aws.Credentials, error) {
return AssumerFromType(c.ProfileType).AssumeTerminal(ctx, c, args)
}

func (c *CFSharedConfig) AwsConfig(ctx context.Context, useSSORegion bool) (aws.Config, error) {

opts := []func(*config.LoadOptions) error{
// load the config profile
config.WithSharedConfigProfile(c.Name),
}

if useSSORegion {
// With region forces this config to use the profile region, ignoring region configured with environment variables
opts = append(opts, config.WithRegion(c.AWSConfig.SSORegion))
} else if c.AWSConfig.Region != "" {
// With region forces this config to use the profile region, ignoring region configured with environment variables
// if region is not configured for this profile, use the aws_default_region
opts = append(opts, config.WithRegion(c.AWSConfig.Region))
}

return config.LoadDefaultConfig(ctx,
opts...,
)
}

func (c *CFSharedConfig) CallerIdentity(ctx context.Context) (*sts.GetCallerIdentityOutput, error) {
cfg, err := c.AwsConfig(ctx, false)
if err != nil {
return nil, err
}
client := sts.NewFromConfig(cfg)
return client.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
}

0 comments on commit a74362a

Please sign in to comment.