Skip to content

Commit

Permalink
Add GetAllowedActions PolicyDocument method
Browse files Browse the repository at this point in the history
  • Loading branch information
tbrisker committed Jun 16, 2022
1 parent c72dda5 commit e339151
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 29 deletions.
17 changes: 0 additions & 17 deletions pkg/aws/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package aws

import (
"fmt"
"reflect"

"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/iam"
Expand Down Expand Up @@ -78,19 +77,3 @@ func (c *awsClient) ValidateSCP(target *string, policies map[string]string) (boo

return true, nil
}

func getActionAllowed(action interface{}) []string {
var actionArr []string
switch reflect.TypeOf(action).Kind() {
case reflect.Slice:
value := reflect.ValueOf(action)
actionArr = make([]string, value.Len())
for i := 0; i < value.Len(); i++ {
actionArr[i] = value.Index(i).Interface().(string)
}
case reflect.String:
actionArr = make([]string, 1)
actionArr[0] = action.(string)
}
return actionArr
}
32 changes: 20 additions & 12 deletions pkg/aws/policy_document.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,32 @@ func (p *PolicyDocument) IsActionAllowed(wanted string) bool {
return false
}

func (p *PolicyDocument) GetAllowedActions() []string {
var actions []string
for _, statement := range p.Statement {
if statement.Effect != "Allow" {
continue
}
switch action := statement.Action.(type) {
case string:
actions = append(actions, action)
case []interface{}:
for _, el := range action {
actions = append(actions, el.(string))
}
}
}
return actions
}

// checkPermissionsUsingQueryClient will use queryClient to query whether the credentials in targetClient can perform
// the actions listed in the statementEntries. queryClient will need
// sts:GetCallerIdentity and iam:SimulatePrincipalPolicy
func (p *PolicyDocument) checkPermissionsUsingQueryClient(queryClient *awsClient, targetUserARN string,
params *SimulateParams) (bool, error) {
// Ignoring isRoot here since we only warn the user that its not best practice to use it.
// TODO: Add a check for isRoot in the initialize
allowList := []*string{}
for _, statement := range p.Statement {
actionArr := getActionAllowed(statement.Action)
for _, action := range actionArr {
allowList = append(allowList, aws.String(action))
}
}
allowList := aws.StringSlice(p.GetAllowedActions())

input := &iam.SimulatePrincipalPolicyInput{
PolicySourceArn: aws.String(targetUserARN),
Expand All @@ -150,19 +162,15 @@ func (p *PolicyDocument) checkPermissionsUsingQueryClient(queryClient *awsClient
})
}

// Either all actions are allowed and we'll return 'true', or it's a failure
allClear := true
// Collect all failed actions
var failedActions []string

err := queryClient.iamClient.SimulatePrincipalPolicyPages(input,
func(response *iam.SimulatePolicyResponse, lastPage bool) bool {
for _, result := range response.EvaluationResults {
if *result.EvalDecision != "allowed" {
// Don't bail out after the first failure, so we can log the full list
// of failed/denied actions
failedActions = append(failedActions, *result.EvalActionName)
allClear = false
}
}
return !lastPage
Expand All @@ -171,7 +179,7 @@ func (p *PolicyDocument) checkPermissionsUsingQueryClient(queryClient *awsClient
return false, fmt.Errorf("Error simulating policy: %v", err)
}

if !allClear {
if len(failedActions) > 0 {
return false, fmt.Errorf("Actions not allowed with tested credentials: %v", failedActions)
}

Expand Down

0 comments on commit e339151

Please sign in to comment.