AWS IAM role principal vs role session principal - amazon-web-services

AWS documentation for IAM role principals[1] states the following:
To specify the role ARN in the Principal element, use the following format:
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:role/role-name" }
However, when would an IAM policy use a Principal element with an IAM role principal, as shown in the snippet? Aren't all IAM actions performed by a role identity actually performed by role session principal[2]?
For instance, the following S3 bucket policy has a Principal element with an IAM role principal
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXXXX:role/MyRole"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
}
}
but it does not grant access to principals who assumed MyRole. To do that rather, the policy needs to use a role session principal:
"Principal": {
"AWS": "arn:aws:sts::XXXXXXXXXXXX:role:assumed-role/MyRole/MyRoleSession"
}
Alternatively, the policy can grant access to all MyRole role sessions, regardless of session name:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
"Condition": {
"ArnEquals": {
"aws:PrincipalArn": "arn:aws:iam::XXXXXXXXXXXX:role/MyRole"
}
}
}
}
Here, an IAM role principal is used in the Condition element. But returning to the question, is it ever applicable to use it in the Principal element?
References
IAM role principals. AWS JSON policy elements: Principal. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-roles
Role session principals. AWS JSON policy elements: Principal. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-role-session

Based on information in "Resource-based policies and implicit denies in other policy types (same account)",
Principal making the request
Resource-based policy
Identity-based policy
Permissions boundary
Session Policy
Result
Reason
IAM role
Not applicable
Not applicable
Not applicable
Not applicable
Not applicable
A role itself cannot make a request. Requests are made with the role session after a role is assumed.
It is impossible for an IAM role itself to make a request, and any policies using the IAM role principal in the Principal element
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXXXX:role/MyRole"
}
do not apply.

Related

Official example on AWS documentation on how to add a service principal on a resource based policy does not work

I several lambda functions on my account to be able to access a secret.
(I cannot use identity policies, don't ask why)
I am following this example from the official documentation so I am creating this resource based policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*",
"Condition": {
"ArnLike": {
"aws:sourceArn": "arn:aws:lambda::1234567891911:*"
},
"StringEquals": {
"aws:sourceAccount": "1234567891911"
}
}
}
]
}
My lambda invocation fails as follows:
"An error occurred (AccessDeniedException) when calling the GetSecretValue operation: User: arn:aws:sts::1234567891911:assumed-role/my-secret-name/my-lambda-name is not authorized to perform: secretsmanager:GetSecretValue on resource: ps-shield-token because no identity-based policy allows the secretsmanager:GetSecretValue action",
????
I don't see the problem. Your policy example is valid for services that support service-linked roles1. Lambda functions do not support service-linked roles. Therefore, the policy example is not valid for Lambda.
Service-linked roles, which are AWS-managed, are referenced by service name in resource-based policies, as in the OP. For instance, the principal { “Service”: “elasticloadbalancing.amazonaws.com” } refers to the AWS-managed ELB service-linked-role, which is called AWSServiceRoleForElasticLoadBalancing. Again, there's no equivalent lambda.amazon.aws option here, because Lambda has no service-linked role2.
Functions have user-managed execution roles. Execution roles (EC2 Instances and ECS Tasks have something similar) are referenced by the role ARN in the resource-based policy "Principal": { AWS: <Lambda Role Arn> }, as in #jellycsc's answer.
Although the docs could definitely be clearer, your Example: Service principal does refer to just to service-linked roles. The first link on the page, AWS Service Principal, refers to "service principal" as used "services that support service-linked roles".
Lambda#Edge does support service-linked roles.
It's not the lambda service that's getting the secret value. The lambda service first assumes the execution role which you set in your lambda function, and the execution role is the principle of the secretsmanager:GetSecretValue action. Therefore, the following policy should work.
{
"Version": "2012-10-17",
"Statement":
[
{
"Effect": "Allow",
"Principal":
{
"AWS": "arn:aws:iam::1234567891911:role/<lambda-execution-role-name>"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}
]
}

can IAM user assume a role, whose trust policy allows the user, without explicit AssumeRole permission

I have a IAM role with full ec2 access with below trust policy,
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::AccountA:user/dev"
]
},
"Action": "sts:AssumeRole"
}
]
}
IAM user, dev, does not have an associated AssumeRole policy, but still be able to switch to this role.
When I expand the principal to "Account Number", as expected, I need to attach explicit AssumeRole to user(s) to switch to that role.
can someone explain why a trust policy at user level is not enforcing explicit permission?

Why is this s3 Bucket policy invalid?

{
"Version": "2012-10-17",
"Id": "Policy1612574490300",
"Statement": [
{
"Sid": "Stmt1612574488073",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:ec2:us-east-1:258977512672:instance/i-041123c1993c370ba"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my_bucket",
"arn:aws:s3:::my_bucket/*"
]
}
]
}
response is Invalid Principal. I dont see why it's invalid.
An EC2 instance isn't a valid principal. I think what you actually need to do here is use the ARN of the IAM role assigned to the EC2 instance.
You can specify following Principal in a policy
AWS account and root user
IAM users
Federated users (using web identity or SAML federation)
IAM roles
Assumed-role sessions
AWS services
Anonymous users (not recommended)
S3 Documentation Principal
AWS JSON policy elements: Principal
If you wanna give that instant access to the bucket then you can use Instance profiles

API Gateway resource policy: specify IAM role as AWS principal

I am trying to setup an API Gateway endpoint with a resource policy, which allows access to a specific IAM role in my account. The IAM role is cross-account, setup with a trust policy which allows AssumeRole to a specific IAM user principal from another account.
In the API Gateway resource policy, when I set AWS principal to the role ARN: arn:aws:iam::********:role/myRole, I get the following 403 error when invoking the API:
User: arn:aws:sts::********:assumed-role/myRole/mySession is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-west-2:********:********/test/POST/echo
But, if I change the AWS principal to be the temporary STS user ARN: arn:aws:sts::********:assumed-role/myRole/mySession, then I can invoke the API successfully.
Here's the resource policy that doesn't work:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::********:role/myRole"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:********:********/*"
}
]
}
Here's the resource policy that works:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::********:assumed-role/myRole/mySession"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:********:********/*"
}
]
}
Can IAM roles be used as AWS principals for API Gateway resource policy?
Based on the documentation https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-policy-language-overview.html,
Principal – The account or user who is allowed access to the actions
and resources in the statement. In a resource policy, the principal is
the IAM user or account who is the recipient of this permission.
Looks like roles cannot be added as a principal.
P.S: Spent two days trying to restrict access using roles, but couldn't get it to work.

Allow selected IAM users to switch role

I have two AWS accounts(Account A & B). I want to allow few IAM users of Account B to access resources of Account A via AWS IAM roles.
I have created the role and it works fine. However, I see that any IAM user who gets hold of the role name is able to switch roles and access the resources.
Is there a way to allow only specific users of Account B to be able to switch to the role?
The trust policy statement is as follows-
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account-B:root"
},
"Action": "sts:AssumeRole"
}
]
}
You can add the users who should be restricted to assume the role to a group. Then you can attach IAM policy to the IAM group with an explicit Deny.
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Deny",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::Account_A_ID:role/Rolename"
}
}
http://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html#tutorial_cross-account-with-roles.html#tutorial_cross-account-with-roles-2