Simulate Principal Policy using assumed role - amazon-web-services

I was wondering how to use simulate-principal-policy using the AWS CLI for an assumed role.
To provide some context, as part of my application's startup, I want to ensure that the application has the necessary permissions to access all the AWS resources it needs. I do this by getting the caller identity using aws sts get-caller-identity and use the returned caller identity as the policy source arn for the simulate-principal-policy request.
When our application runs on EC2, it uses an assumed role. so, get-caller-identity returns an assumed role arn.
If I try to execute simulate-principal-policy using my user arn as the policy source arn, the command works fine.
aws iam simulate-principal-policy --action-names "sqs:Receivemessage" --policy-source-arn "arn:aws:sts::123456789021:user/divesh"
However, trying to execute the command above by using an assumed role reports an error.
aws iam simulate-principal-policy --action-names "sqs:Receivemessage" --policy-source-arn "arn:aws:sts::123456789021:assumed-role/development/development-session"
An error occurred (InvalidInput) when calling the SimulatePrincipalPolicy operation: Invalid Entity Arn: arn:aws:sts::123456789021:assumed-role/development/development-session does not clearly define entity type and name.
Our application runs on a Kubernetes cluster and uses kiam to associate IAM roles to pods.

The problem with your request is that you are using the "Profile ARN" instead of the "Role ARN". To get the Role Arn, you can do the following:
Pull the Role Name from the Instance Profile Arn:
arn:aws:sts::123456789021:assumed-role/development/development-session becomes development/development-session
Get the instance profile based on that name:
aws iam get-instance-profile --instance-profile-name Instance Profile Arn
Find the Role Arn in the resulting document:
{
"InstanceProfile":{
"Roles":[
{
"Arn":"arn:aws:iam::992863558783:role/YourRole"
}
]
}
}
Use this ARN in simulate-principal-policy
aws iam simulate-principal-policy --action-names "sqs:Receivemessage" --policy-source-arn "arn:aws:iam::992863558783:role/YourRole"
In Python, the script would look like this:
import boto3
iam= boto3.client('iam')
profileArn = 'arn:aws:sts::123456789021:assumed-role/development/development-session'
iamProfileName = iamInstanceProfileArn.split(':assumed-role/')[1]
profile = iam.get_instance_profile(InstanceProfileName=iamProfileName)
policySourceArns = []
for role in profile['InstanceProfile']['Roles']:
policySourceArns.append(role['Arn'])
retval = iam.simulate_principal_policy(
PolicySourceArn = policySourceArns[0],
ActionNames = ['sqs:Receivemessage']
)

Related

How to query Assumed Role

My application generates this error message:
arn:aws:sts::123456789012:assumed-role/my-service-role/aws-sdk-1111111111111 is not authorized to perform: secretsmanager:GetSecretValue
How can I see more information about which roles or permissions are attached to this assumed role?
I have tried querying for this with the AWS CLI using aws iam get-user / list-users / get-role / list-roles but neither exist. I looked at querying under STS but couldn't see an appropriate option.
I couldn't find this role in the AWS console.
How can I see more information about which roles or permissions are attached to this assumed role?
You can access this information a number of ways, if you know the name of the role you can use the IAM service, here is a boto3 example:
import boto3
iam = boto3.resource('iam')
role = iam.Role('AWSServiceRoleForRDS')
for pol in role.attached_policies.iterator():
print(pol)
For me this gives:
iam.Policy(arn='arn:aws:iam::aws:policy/aws-service-role/AmazonRDSServiceRolePolicy')
The sole policy I have attached to this role. Obviously, you'll need to substitute the role name you are interested in here in place of 'AWSServiceRoleForRDS'
In general this will print out all the policies attached to the role (to stdout).
In order to do make this query you need to be authenticated as a user or role that has permissions to access the IAM role (or user).
Update: How to find the name of the role from an ARN?
following the aws docs for IAM identifies you can identify the role name from the arn for sts assumed roles they follow this format:
arn:aws:sts::account:assumed-role/role-name/role-session-name
Based on what was posted:
arn:aws:sts::123456789012:assumed-role/my-service-role/aws-sdk-1111111111111 is not authorized to perform: secretsmanager:GetSecretValue
it looks like my-service-role is the name of the assumed role.

Allow ECS task to AssumeRole into another account

I've looked at this question and this one but I'm not able to deploy a role into a child account which allows an ECS task running in the parent account to AssumeRole into it.
Terraform code:
data "aws_iam_policy_document" "cross-account-assume-role-child" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = [
"arn:aws:sts::${var.master_account_ID}:assumed-role/${var.cross_account_role_name}"
]
}
}
}
When I try to run terraform the plan succeeds but the apply fails with such an error:
Error: failed creating IAM Role (ECS-cross-account-child-role):
MalformedPolicyDocument: Invalid principal in policy:
"AWS":"arn:aws:sts::<AWS Account ID>:assumed-role/ECS-cross-account-master-role"
I get the same error if I try to manually update the policy like above in the AWS console so this isn't due to terraform.
What am I doing wrong?
The arn you need to specify in the policy is the one of the IAM role, not of the assumed credentials:
arn:aws:iam::${var.master_account_ID}:role/${var.cross_account_role_name}
Instead of of sts and assumed-role

aws cli fails to return a role policy

I am copying the name of a policy a created (and attached to a role) and running the following command:
▶ aws iam get-role-policy --role-name MyRole --policy-name MyPolicy
however I am getting:
An error occurred (NoSuchEntity) when calling the GetRolePolicy operation: The role policy with name MyPolicy cannot be found.
The policy is right there, I am copying the name from the AWS console.
What is the issue here?
I have also tried the following, that does list the policy
$ aws iam list-attached-role-policies --role-name MyRole
{
"AttachedPolicies": [
{
"PolicyName": "MyPolicy",
"PolicyArn": "arn:aws:iam::123456789:policy/MyPolicy"
}
]
}
(END)
list-attached-role-policies lists all managed policies attached to a role and get-role-policy retrieves an inline policy. In order to retrieve a managed policy you'll want to use get-policy, get the policy version from there and retrieve it using get-policy-version.

How to attach CloudWatchLogsFullAccess to the IAM role of EKS EC2 instance

I use the module, terraform-aws-modules/eks/aws provision EKS. By default, the module provisions three policies to the EKS EC2 IAM role, AmazonEKSWorkerNodePolicy, AmazonEC2ContainerRegistryReadOnly and AmazonEKS_CNI_Policy. I would like to attach an additional policy, CloudWatchLogsFullAccess to the IAM role. I read the doc. I did not find a way to attach it. I had to logon to the AWS console, manually attach CloudWatchLogsFullAccess to the IAM role. Is there a way to use terraform code to attach it when I use this EKS module provisioning EKS?
I added the code below.
resource "aws_iam_role_policy_attachment" "cloudWatch" {
role = module.eks.cluster_iam_role_arn
policy_arn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
}
But, it complains "The specified value for roleName is invalid".
Error: Error attaching policy arn:aws:iam::aws:policy/CloudWatchLogsFullAccess to IAM Role arn:aws:iam::678515134618:role/my-eks20210303061731134400000005: ValidationError: The specified value for roleName is invalid. It must contain only alphanumeric characters and/or the following: +=,.#_-
status code: 400, request id: aee57a35-ae72-499e-8653-e61e795818e4
Once you create your eks cluster, you can get cluster_iam_role_arn_from its outputs. Having the ARN you can attach extra policies to it using aws_iam_role_policy_attachment:
resource "aws_iam_role_policy_attachment" "test-attach" {
role = module.myeks.cluster_iam_role_arn
policy_arn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
}

Is it possible to query the AWS SDK to determine the IAM role for the current credentials?

I would like to be able to query the AWS SDK to check what the IAM role of the current credentials is. I want to check if I am running using a particular role, and if not, then try to assume that role.
Is it possible to do this? I am using the AWS SDK for JavaScript for node.js. In the AWS.config.credentials, I have access to my keys, but not to which role they belong.
I think the method you want is GetCallerIdentity on the STS (Security Token Service) API:
API reference
JS example
This returns either nice user info (if no role in effect):
{
Account: "123456789012",
Arn: "arn:aws:iam::123456789012:user/Alice",
UserId: "AKIAI44QH8DHBEXAMPLE"
}
or info on the temporary session/user and role (if a role is in effect):
{
Account: "123456789012",
Arn: "arn:aws:sts::123456789012:assumed-role/my-role-name/my-role-session-name",
UserId: "AKIAI44QH8DHBEXAMPLE:my-role-session-name"
}
As noted, IAM().GetUser() (to return info on the current user) only works in the first instance, if no role is assumed. It fails if there is a role, so code defensively, but it's worth considering as when no role is in effect it returns a nicely formatted objects (though you could just regex-parse the arn:aws:iam::(.*):user/(.*) ARN from the GetCallerIdentity):
{
User: {
Arn: "arn:aws:iam::123456789012:user/Bob",
CreateDate: <Date Representation>,
Path: "/",
UserId: "AKIAIOSFODNN7EXAMPLE",
UserName: "Bob"
}
}
I suspect GetUser fails when a role is used because from what I can tell you are allocated a temporary user, I could see it being problematic to revert that role-assumption on the server, which would be necessary in order to make GetUser work in that case. And in some cases (instance profiles?) I think there isn't any real user account to revert back to.
To get the username of a user based on a set of keys you can use:
var iam = new AWS.IAM();
iam.getUser().User.UserName;
The API docs give the full details.
To get the role arn of an instance you'd probably have to use the instance metadata API endpoint as there is no method available in the SDK.
This answer and this one give details on different ways to query instance metadata.
Using just the AWS CLI:
aws sts get-caller-identity
The AWS Security Token Service (STS) returns something like:
{
"UserId": "ABBBCCC123123DDDDEEEE",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/bob"
}
(the username is within the Arn value, after the last :)
I will provide example how to do it in AWS CLI and you can convert it into NodeJS code:
aws sts get-caller-identity
get ARN from the response and get the user name from there (everything that comes after user/)
aws iam list-groups-for-user --user-name UserNameFromPreviousResponse
Then for each group you can dive in to the policies that are builtin or attached to that group:
aws iam list-group-policies --group-name GroupName
aws iam list-attached-group-policies --group-name GroupName
from here you can dive in into the policies to get their ARN if needed but I believe at this level it already should satisfy your needs.