OCP on AWS - Simulate CredentialsRequests permissions
AWS Provides a service to simulate if policies are proper defined on resources (User, Group or Roles).
You can use the AWS CLI or AWS Console.
In this playbook I will describe how to simulate the actions defined on the policies Provided by CredentialsRequests are properly defined/created on the AWS IAM Role for the component Machine API.
Let's put the hands on:
- Get the actions defined on the CredentialsRequests
ACTIONS=$(oc get -n openshift-cloud-credential-operator -o json \
credentialsrequests openshift-machine-api-aws \
| jq -r '.spec.providerSpec.statementEntries[].action[]' \
| sort -u | tr '\n' ' ')
- Extract the IAM Role ARN from the MachineAPI secret created by CCO
MACHINE_API_ROLE_ARN=$(oc get secrets aws-cloud-credentials \
-n openshift-machine-api \
-o jsonpath='{.data.credentials}' |\
base64 -d |\
grep ^role_arn |\
awk '{print$3}')
- Now, let's call the AWS Simulate Principal Policy service, sending the actions and the IAM Role extracted on the steps above:
$ aws iam simulate-principal-policy \
--policy-source-arn ${MACHINE_API_ROLE_ARN} \
--action-names ${ACTIONS} \
| jq -r '(["EVAL_ACTION","EVAL_DECISION"] | (., map(length*"-"))),
(.EvaluationResults[] | [.EvalActionName, .EvalDecision ])
| @tsv' | column -t
EVAL_ACTION EVAL_DECISION
----------- -------------
ec2:CreateTags allowed
ec2:DescribeAvailabilityZones allowed
ec2:DescribeDhcpOptions allowed
ec2:DescribeImages allowed
ec2:DescribeInstances allowed
ec2:DescribeInternetGateways allowed
ec2:DescribeSecurityGroups allowed
ec2:DescribeSubnets allowed
ec2:DescribeVpcs allowed
ec2:RunInstances allowed
ec2:TerminateInstances allowed
elasticloadbalancing:DeregisterTargets allowed
elasticloadbalancing:DescribeLoadBalancers allowed
elasticloadbalancing:DescribeTargetGroups allowed
elasticloadbalancing:DescribeTargetHealth allowed
elasticloadbalancing:RegisterInstancesWithLoadBalancer allowed
elasticloadbalancing:RegisterTargets allowed
iam:CreateServiceLinkedRole allowed
iam:PassRole allowed
kms:CreateGrant implicitDeny
kms:Decrypt allowed
kms:DescribeKey allowed
kms:Encrypt allowed
kms:GenerateDataKey allowed
kms:GenerateDataKeyWithoutPlainText allowed
kms:ListGrants implicitDeny
kms:RevokeGrant implicitDeny
The collumn EVAL_DECISION
shows the result of the evaluation of the Action against the IAM Role Policies. If it's allowed
means that the IAM Role allows the action to be taken when the client calls the service API.
For the implicitDeny
means that the action is not allowed for that IAM Role, or it's missing permissions (our case). Let's check the action kms:CreateGrant
$ oc get -n openshift-cloud-credential-operator -o json \
credentialsrequests openshift-machine-api-aws \
| jq -r '.spec.providerSpec.statementEntries[]
| select (.action|any(. =="kms:CreateGrant"))
| .'
{
"action": [
"kms:RevokeGrant",
"kms:CreateGrant",
"kms:ListGrants"
],
"effect": "Allow",
"policyCondition": {
"Bool": {
"kms:GrantIsForAWSResource": true
}
},
"resource": "*"
}
We can see that the policyCondition
requires a field kms:GrantIsForAWSResource
to be set.
When calling the service, you should be able to see the required fields on MissingContextValues
:
ACTIONS="kms:CreateGrant"
aws iam simulate-principal-policy \
--policy-source-arn ${MACHINE_API_ROLE_ARN} \
--action-names "kms:CreateGrant"
{
"EvaluationResults": [
{
"EvalActionName": "kms:CreateGrant",
"EvalResourceName": "*",
"EvalDecision": "implicitDeny",
"MatchedStatements": [],
"MissingContextValues": [
"kms:GrantIsForAWSResource"
],
"OrganizationsDecisionDetail": {
"AllowedByOrganizations": true
}
}
]
}
Let's call the simulate policy fixing the fields setting the option --context-entries
:
ACTIONS="kms:CreateGrant kms:RevokeGrant kms:ListGrants"
aws iam simulate-principal-policy \
--policy-source-arn ${MACHINE_API_ROLE_ARN} \
--action-names ${ACTIONS} \
--context-entries "ContextKeyName='kms:GrantIsForAWSResource',ContextKeyValues=true,ContextKeyType=boolean" \
| jq -r '(["EVAL_ACTION","EVAL_DECISION"] | (., map(length*"-"))),
(.EvaluationResults[] | [.EvalActionName, .EvalDecision ])
| @tsv' | column -t
The expected results: