I have a cloudformation template up in an S3 bucket (the url follows the pattern but is not exactly equal to: https://s3.amazonaws.com/bucket-name/cloudform.yaml). I need to be able to access it from CLI for a bash script. I'd prefer that everybody in an organization (all in this single account) has access to this template but other people outside of the organization don't have access to the template. A bucket policy I've tried looks like:
{
"Version": "2012-10-17",
"Id": "Policy11111111",
"Statement": [
{
"Sid": "Stmt111111111",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::7777777777:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
}
With this policy, I and a couple other people in my office are unable to access the url. Even when I'm logged in with the root account I'm getting Access Denied.
Also, this change (only setting Principal to *) makes the bucket accessible to anybody:
{
"Version": "2012-10-17",
"Id": "Policy11111111",
"Statement": [
{
"Sid": "Stmt111111111",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
}
Obviously the signs point to my Principal field being misconfigured. 777777777 is the replacement for the Account ID I see under the My Account page.
So, do I need to worry about this on the IAM front? Considering that I am logged in as the root user, I'd guess I should have access to this as long as I put in a bucket policy. Any help would be much appreciated.
Short and sweet:
The bucket policy doesn't allow you to do what you want because of a wildcard limitation of the Principal element. Your best bet is to create an IAM group and put all IAM users into that group if they need access.
Long version:
Just to make it clear, any request to https://s3.amazonaws.com/bucket-name/cloudform.yaml MUST be signed and have the necessary authentication parameters or the request will be rejected with Access Denied. The only exception is if the bucket policy or the bucket ACL allows public access, but it doesn't sound like this is what you want.
When you say "everybody in an organization (all in this single account)" I assume you mean IAM users under the account who are accessing the file from the AWS console, or IAM users who are using some other code or tool (e.g. AWS CLI) to access the file.
So what it sounds like what you want is the ability to specify the Principal as
"Principal": {
"AWS": "arn:aws:iam::777777777777:user/*"
}
since that is what the pattern would be for any IAM user under the 777777777777 account id. Unfortunately this is not allowed because no wildcard is allowed in the Principal unless you use the catch-all wildcard "*". In other words "*" is allowed, but either "prefix*" or "*suffix" is not. (I wish AWS documented this better.)
You could specify every IAM user you have in the bucket policy like so:
"Principal": {
"AWS": [
"arn:aws:iam::777777777777:user/alice",
"arn:aws:iam::777777777777:user/bob",
"arn:aws:iam::777777777777:user/carl",
...
"arn:aws:iam::777777777777:user/zed",
}
But you probably don't want to update the policy for every new user.
It would be easiest to create an IAM group that grants access to that file. Then you would add all IAM users to that group. If you add new users then you'll have to manually add them to that group, so it is not as convenient as what you originally wanted.
Related
I'm trying to follow the instructions in How can I allow a Group to assume a Role?, but run into the following error when I try to switch roles:
Invalid information in one or more fields. Check your information or contact your administrator.
In this scenario I have three AWS Accounts with example ids
CompanyMain - 000000000001
CompanyProd - 000000000002
CompanyDev - 000000000003
Where the main account has an organization that includes the the prod and dev accounts
What I'd like to do is set up a single set of IAM users on the main account and allow them to login and switch between either of the two subaccounts, instead of forcing everyone to have three separate logins.
Here's what I've done so far all on the CompanyMain account:
Create Role for accessing Prod Account
Set trusted Entity to "Another AWS Account"
Set Permission Policy to AdministratorAccess
So when I go to Role > "Trust Relationship" > Show Policy Document - it looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000002:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
With the name "company-prod-admin" so the ARN is like this:
arn:aws:iam::000000000001:role/company-prod-admin
This also comes with the link to switch roles as follows:
https://signin.aws.amazon.com/switchrole?roleName=company-prod-admin&account=000000000001
Create a Policy to Assume this Role
Service: STS
Actions: AssumeRole
Role ARN: arn:aws:iam::000000000001:role/company-prod-admin
So the Policy Document looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::000000000002:root"
}
]
}
Create Admin Group
Create a group on the main account called admin and attach the policy we just created
Create IAM User
Create user on the main account and place in admin group
Sign in as IAM User
I can now sign in as an IAM user against the main account
From there, I'd like to switch roles by using the role link or going to https://signin.aws.amazon.com/switchrole and entering the account / role info
However, I get the error that the following info is invalid
Org Setup Question
How can I create roles that across organizations? I'm a little confused as to where the role / permission needs to originate between the three accounts, but ideally I'd like to have a way for someone to login to one set of permissions for the whole organization.
You need to do the IAM policy the other way around if you want to be able to access the CompanyProd from CompanyMain then you need to create a IAM policy in the CompanyProd like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000001:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
Next you login into the MainCompany and go to switch role.
in the Account, you write 000000000002, in the Role field you write root.
I am new to AWS and find it unnecessarily disorganized and complicated.
I would like to give a developer access to the account at the AdministratorAccess level but limit that access by not allowing him to create additional users or groups. Without limiting this, he can create a user that has access to billing. I want to make sure no one has access to billing or can create users that can access billing.
How do I do that?
You can create a customer managed IAM policy based on Administrator Access and add an explicit Deny statement similar to the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"iam:CreateGroup",
"iam:CreateUser",
...
],
"Resource": "*"
}
]
}
Note: The above restrictions will not be sufficient, they only demonstrate the general principle. To effectively restrict users you would also have to deny actions that attach managed policies or put inline policies to users or groups and actions that change already attached policies.
In general, it is advisable to follow the Principle of Least Privilege and give users only the permissions that they actually need. Only in rare cases you should start with AdministratorAccess and then incrementally restrict the permissions. It is considered best practice to start with no permissions and then incrementally add what is needed.
P.S.: You could also implement a mechanism that automatically attaches the following policy to all users to effectively deny all cost explorer and billing-related actions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"aws-portal:*Billing",
"aws-portal:*Usage",
"aws-portal:*PaymentMethods",
"ce:UpdatePreferences",
"ce:CreateReport",
"ce:UpdateReport",
"ce:DeleteReport",
"ce:CreateNotificationSubscription",
"ce:UpdateNotificationSubscription",
"ce:DeleteNotificationSubscription",
"cur:DescribeReportDefinitions",
"cur:PutReportDefinition",
"cur:ModifyReportDefinition",
"cur:DeleteReportDefinition",
"purchase-orders:*PurchaseOrders"
],
"Resource": "*"
}
]
}
I'm trying to use the react-native-s3-upload package to upload files to an S3 bucket in my React Native App. This only works if I set "Block public access" to 'off' in S3. Otherwise I get <Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>. The access key and secret key provided with put requests are for an IAM user that belongs to a group with AmazonS3FullAccess. I also have this policy attached to the bucket:
{
"Version": "2012-10-17",
"Id": "Policyxxxxxxx",
"Statement": [
{
"Sid": "Stmtxxxxxxx",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxx:user/<user name>"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::<bucket name>"
}
]
}
I've tried all sorts of solutions but nothing seems to work. If I replace the secret key and access keys with dummy text then it returns <Error><Code>InvalidAccessKeyId</Code><Message> so it's definitely signing me in with the keys but seems to be ignoring the permissions.
If your IAM user has AmazonS3FullAccess policy, it should connect to bucket just fine.
I think that the problem is that default object acl is public,
https://www.npmjs.com/package/react-native-s3-upload
acl - The Access Control List of this object. Defaults to public-read
You need to set it to private.
Is it possible to create an IAM rule or an SCP (organization rule) to enforce MFA for all users in a certain group or with certain rights (e.g. administrators or power user)?
To the best of my knowledge you can attach a deny portion to any policy or create a deny policy and attach it to any group.
For example you have "Administrators" group that has many roles added as well as "MultifactorAuthForce" policy:
Example of "MultifactorAuthForce":
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllWithoutMFA",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
Update:
Just tested it on my account and the policy works. Created an account without MFA, added password and assigned to the group above. When logged as that user I was denied all actions on all resources. After, I added MFA to the user and logged in again. I was able to see the resources.
I am trying to write an IAM policy which will control access to EC2 instances. All EC2 instances will have a custom tag called username and only if the tag value matches the logged in user's user name, will that user have access to that EC2 instance. This is what I came up with:
{
"Version": "2012-10-12",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/username": "arn:aws:iam::account-number-without-hyphens:user/username1"
}
}
}
]
}
I am sure you see the problem here. I don't want to hard code the username value on the right hand side. I want to be able to get that information at runtime or policy evaluation time.
Is it possible to do so?
The IAM user can be referred to in policy documents by ${aws:username}.
There is a list of other IAM policy variables and their uses here:
http://docs.aws.amazon.com/IAM/latest/UserGuide/PolicyVariables.html