Skip to content

Update IsAdmin check to iterate through policies attached to roles #1920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 1, 2021
Merged
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
2 changes: 1 addition & 1 deletion cli/cmd/lib_aws_creds.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func warnIfNotAdmin(awsClient *aws.Client) {
}

if !awsClient.IsAdmin() {
fmt.Println(fmt.Sprintf("warning: your IAM user%s does not have administrator access. This may prevent this command from executing correctly, so it is recommended to attach the AdministratorAccess policy to your IAM user.", accessKeyMsg), "", "")
fmt.Println(fmt.Sprintf("warning: your IAM user or assumed role%s does not have administrator access. This may prevent this command from executing correctly, so it is recommended to attach the AdministratorAccess policy to your IAM user or role.", accessKeyMsg), "", "")
}
}

Expand Down
67 changes: 60 additions & 7 deletions pkg/lib/aws/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ import (
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/cortexlabs/cortex/pkg/lib/errors"
)

const _administratorAccessARN = "arn:aws:iam::aws:policy/AdministratorAccess"

func (c *Client) GetUser() (iam.User, error) {
getUserOutput, err := c.IAM().GetUser(nil)
if err != nil {
Expand Down Expand Up @@ -87,12 +90,7 @@ func (c *Client) GetManagedPoliciesForUser(userName string) ([]iam.AttachedPolic
return policies, nil
}

func (c *Client) IsAdmin() bool {
user, err := c.GetUser()
if err != nil {
return false
}

func (c *Client) isAdminUser(user iam.User) bool {
// Root users may not have a user name
if user.UserName == nil {
return true
Expand All @@ -109,14 +107,69 @@ func (c *Client) IsAdmin() bool {
}

for _, policy := range policies {
if *policy.PolicyArn == "arn:aws:iam::aws:policy/AdministratorAccess" {
if *policy.PolicyArn == _administratorAccessARN {
return true
}
}

return false
}

func (c *Client) isRoleAdmin() bool {
identity, err := c.STS().GetCallerIdentity(nil)
if err != nil {
return false
}

arn := identity.Arn
if arn == nil {
return false
}

if !strings.Contains(*arn, ":assumed-role/") {
return false
}

// expected to be in form arn:aws:sts::account-id:assumed-role/role-name/role-session-name
arnSplit := strings.Split(*arn, "/")
if len(arnSplit) < 2 {
return false
}
roleName := arnSplit[1]

isAdmin := false
c.IAM().ListAttachedRolePoliciesPages(&iam.ListAttachedRolePoliciesInput{
RoleName: &roleName,
}, func(policies *iam.ListAttachedRolePoliciesOutput, lastPage bool) bool {
for _, policy := range policies.AttachedPolicies {
if *policy.PolicyArn == _administratorAccessARN {
isAdmin = true
return false
}
}

return !lastPage
})
return isAdmin
}

func (c *Client) IsAdmin() bool {
user, err := c.GetUser()
if err != nil {
awsErr, ok := errors.CauseOrSelf(err).(awserr.Error)
if !ok {
return false
}

// this particular error is returned if GetUser() is invoked using credentials that are not for users
if awsErr.Code() == "ValidationError" && strings.Contains(strings.ToLower(err.Error()), strings.ToLower("calling with non-User credentials")) {
return c.isRoleAdmin()
}
return false
}
return c.isAdminUser(user)
}

// delete non default policy versions and then delete the policy (as required by aws)
func (c *Client) DeletePolicy(policyARN string) error {
policyVersionList, err := c.IAM().ListPolicyVersions(&iam.ListPolicyVersionsInput{
Expand Down