AWS SCP Condition disallow iam user creation - amazon-web-services

I am trying to create an SCP policy to disallow creation of iam user in member accounts other than Admin (assumed role with SSO), however its not letting even the admin create the user, below is the policy I am using,
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Deny",
"Action": [
"iam:CreateUser",
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:DeleteUser"
],
"Resource": [
"*"
],
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:sts::*:assumed-role/AWSReservedSSO_AWSAdministratorAccess*/*"
]
}
}
}
]
}
Not sure what's wrong in it, please help

The PrincipalArn should be:
arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AWSAdministratorAccess*
To get an valid ARN for SSO assumed roles, you need to change arn:aws:sts::*:assumed-role by arn:aws:iam::*:role.
Additionally, this represents the SSO group, so you do not need to add /* after the group name. So the following ARN is incorrect and will not work:
arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AWSAdministratorAccess*
Reference:
Implement service control policy (SCP) for accounts in AWS Organizations

Related

sam pipeline bootstrap created an omnipotent role

In the CI/CD section of the AWS SAM tutorial workshop, when I ran
sam pipeline init --bootstrap and went through the configurations, a role was created with this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "*",
"Resource": "*",
"Effect": "Allow"
}
]
}
Doesn't this grant the role complete permission over my AWS account which is a big no no? Or is it fine because the permission is granted to an AWS service, and not a user?
This is the trust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "cloudformation.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Having a role that exists with those permissionsis fine.
When you create a vanilla AWS Account (in other words I am not including those created by enterprise landing zones like Control Tower) it comes with a policy called AdministratorAccess and a role called Administrator.
The best practice is in who or what you allow to use that policy and when.
Roles are preferred over users, since roles provide security credentials. With a user you have durable credentials you need to secure.
In this case you are allowing CloudFormation to assume this role. This makes sense since CloudFormation often needs to be able to create and modify any resources including IAM roles. If you know you will not be creating or modifying IAM resources you can user a more restrictive role (least privilege), for example using the PowerUserAccess policy which looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"NotAction": [
"iam:*",
"organizations:*",
"account:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:DeleteServiceLinkedRole",
"iam:ListRoles",
"organizations:DescribeOrganization",
"account:ListRegions"
],
"Resource": "*"
}
]
}

Trying to give IAM user rights to create and assign roles, but limit the type of policies available

I'm trying to give a user the rights to create Roles (since I'm not providing rights to create Access Keys).
I have figured out a Policy to allow the user to create and assign Roles.
The issue I have is that right now, the user can create a role with the Policy of "AdministratorAccess" even though they are not Administrator. Is there a way to deny certain policies in the list of options?
Below is the policy done via the wizard provided.
Thanks,
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:CreateInstanceProfile",
"iam:UpdateAssumeRolePolicy",
"iam:ListRoleTags",
"iam:UntagRole",
"iam:PutRolePermissionsBoundary",
"iam:TagRole",
"iam:RemoveRoleFromInstanceProfile",
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:ListInstanceProfilesForRole",
"iam:PassRole",
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:ListPolicies",
"iam:GetRole",
"iam:ListRoles",
"iam:DeleteRole",
"iam:UpdateRoleDescription",
"iam:CreateServiceLinkedRole",
"iam:UpdateRole",
"iam:DeleteServiceLinkedRole",
"iam:GetRolePolicy"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
EDIT: 26/6/20
I tried to use Permission Boundaries as suggested, but perhaps my understanding is still insufficient. I made a new policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAdmin",
"Effect": "Deny",
"Action": [
"iam:*"
],
"Resource": "*",
"Condition": {
"ArnEquals": {
"iam:PolicyArn": [
"arn:aws:iam::aws:policy/AdministratorAccess"
]
}
}
}
]
}
I would think that would mean Deny any/all iam actions when it concerns the AdministratorAccess Policy. However, the result is that all role assignments/creation are denied even when the policy being attached is NOT AdministratorAccess. However, if I setup a policy and add a Condition of ArnNotEquals the AdministratorAccess - then I seem to be able to do what I want(just using it as a policy, not as a Boundary)
Based on what I have seen, Permissions Boundary is probably the right way to go, but I cannot quite get it yet so I'm hesitant to mark it as "Correct Answer".
You can use AWS IAM Permissions Boundaries: Permissions Boundaries for IAM Entities - AWS Identity and Access Management
“A permissions boundary is an advanced feature for using a managed policy to set the maximum permissions that an identity-based policy can grant to an IAM entity. An entity's permissions boundary allows it to perform only the actions that are allowed by both its identity-based policies and its permissions boundaries.“
Here’s a step-by-step introduction on the AWS Security Blog: Delegate permission management to developers by using IAM permissions boundaries | AWS Security Blog
So using directions from John Rotenstein and finally realizing where I went wrong the way to get what I want is to add the following Permissions Boundary to the user:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BoundaryAllowAllNotAdminAccess",
"Effect": "Allow",
"Action": "*",
"Resource": "*",
"Condition": {
"ArnNotEquals": {
"iam:PolicyArn": [
"arn:aws:iam::aws:policy/AdministratorAccess"
]
}
}
}
]
}
Where I went wrong was thinking that I need to Deny, but the Boundary is an AND restraint so I can allow all as long as it is not AdministratorAccess, then the other policies will give the actual actions/resources and AWS will allow as long as it doesn't use the AdministratorAccess.

IAM policy variables

I am confused with the policy variable "${aws:username}" i.e. whether it is the IAM username from which i logged in the AWS account or
is it the tag value that i manually entered in tags while creating instances.
Actually, i wanted to achieve that only owner of the ec2 instance should be to perform actions & othershould be denied. should the below policy works?
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": [
"*"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Owner": "${aws:username}"
}
}
}
]
}
The policy variable ${aws:username} is replaced with the friendly name of the current IAM user when the policy is evaluated by IAM.
https://aws.amazon.com/premiumsupport/knowledge-center/iam-ec2-resource-tags/
Your policy should work.

AWS PowerUserAccess cannot list roles when creating VM, but policy shows it as allowed

I've assigned the policy PowerUserAccess to a group. The Policy for that is:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"NotAction": [
"iam:*",
"organizations:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:DeleteServiceLinkedRole",
"iam:ListRoles",
"organizations:DescribeOrganization"
],
"Resource": "*"
}
]
}
In the second permission, it appears iam:ListRoles is granted. However, when I attempt to create a VM, and try to view the roles I'd like to assign to it, I get the message "You do not have permissions to list any IAM roles. Contact your administrator, or check your IAM permissions."
Should I be able to assign a role to an EC2 instance as a power user? Is there another permission that needs to be granted?
No, the PowerUserAccess policy does not allow that. You need to include iam:ListInstanceProfiles to view the IAM roles which can be attached to EC2 instances and iam:Passrole to attach the role to instances.

S3 bucket policy, how to ALLOW a IAM group from another account?

I have one S3 bucket in one AWS account (say arn:aws:s3:::my-test-bucket), that needs to be accessed by a IAM group that is defined in another AWS account (say arn:aws:iam::1111222333444:group/mygroup). The following access policy refuses to save, and tells that arn:aws:s3:::my-test-bucket is an invalid principal.
{
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:List*",
"s3:Get*"
],
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111222333444:group/mygroup"
},
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Sid": "allow-put-for-dedicated-group"
}
],
}
I have tested by replacing the group with one of the users of the other account and this works:
{
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:List*",
"s3:Get*"
],
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111222333444:user/me"
},
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Sid": "allow-put-for-dedicated-user"
}
],
}
The group is existing, I do not understand why it says it is an invalid principal. In fact it does not accept any group of my other account.
Does anyone have an explanation (and possibly a solution) to this behaviour?
Thanks in advance,
Cheers
IAM groups are not valid principals in S3 bucket policies. See this AWS forum post and this SO post for more discussion.
Here's one idea: create an IAM role (for example cross-account-s3) in account #1 (the account with the S3 bucket). That role should have a policy that allows the appropriate S3 bucket access and it should have a trust relationship that says account #2 is trusted for sts:AssumeRole. Then in account #2, delegate permission to assume the cross-account-s3 role to the relevant IAM group. This requires you to trust the IAM admins in the 2nd account to not allow the wrong users to assume the cross-account-s3 role.
As jarmod said, IAM groups are not valid principles. Also jarmod's solution will work. However it is possible to reference the role that is assumed in the S3 bucket policy. This allows you to deny actions unless they are performed by that role, which then provides the visibility of who has access that you wanted or could be used to further limit the access provided. The role reference is via the Role ID, which can be obtained by the following AWS CLI command: aws iam get-role --role-name ROLE_NAME --profile PROFILE_NAME, where ROLE_NAME is the name of the role created with sts:AssumeRole and PROFILE_NAME is the AWS profile setup to access the role.
Something like the following could then be used for the S3 bucket policy:
{
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:List*",
"s3:Get*"
],
"Effect": "Deny",
"Principal": "*"
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Sid": "deny-put-for-anyone-but-dedicated-role",
"Condition": {
"StringNotLike": {
"aws:userId": [
"ROLE_ID:*"
]
}
}
}
],
}
More details about this can be found in this blog post, which includes using userId to limit access to a user.