I have an access policy that looks something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:123456789012:domain/es01-vpc01-prod-useast1/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"123.456.123.456"
]
}
}
}
]
}
From my understanding, this should give all es related permissions to anyone at the IP 123.456.123.456. This indeed works for most things: I can access ElasticSearch, and I can also execute CLI commands such as aws es describe-elasticsearch-domain --domain-name es01-vpc01-prod-useast1
However, for some reason I cannot modify the access policy from the CLI using a command like this:
aws es update-elasticsearch-domain-config --domain-name es01-vpc01-prod-useast1 --access-policies '{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"*\"},\"Action\": \"es:*\",\"Resource\": \"arn:aws:es:us-east-1:123456789012:domain/es01-vpc01-prod-useast1/*\",\"Condition\": {\"IpAddress\": {\"aws:SourceIp\": [\"123.456.123.456\"]}}}]}'
I receive an error such as:
An error occurred (AccessDeniedException) when calling the
UpdateElasticsearchDomainConfig operation: User:
arn:aws:iam::123456789012:user/MyUser is not authorized to
perform: es:UpdateElasticsearchDomainConfig on resource:
arn:aws:es:us-east-1:123456789012:domain/es01-vpc01-prod-useast1
I have tried variations on the access policy, such as adding the specific role to the access policy, e.g.
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/MyRole"
},
"Action": [
"es:UpdateElasticsearchDomainConfig"
],
"Resource": "arn:aws:es:us-east-1:123456789012:domain/es01-vpc01-prod-useast1"
}
But still no success. What is the trick to make this work?
I know this is an old topic, but in case anyone else has the same issue.
Note that IP address whitelisting for ES only works if the ES domain is outside the VPC.
The following command works for me, the main thing is that you don't need to escape the double quotes if you are surrounding the JSON in single quotes.
Change 'my-domain', the account ID of '1234567890' and the IP address of '127.0.0.1' to your own and it should work for you.
aws es update-elasticsearch-domain-config --domain-name my-domain --access-policies '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:1234567890:domain/my-domain/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "127.0.0.1"
}
}
}
]
}'
Related
I am trying to avoid having to implement fine-grained ElasticSearch policy until we absolutely need it since it is irreversible. So, I am implementing a Domain JSON defined access policy with the conditions noting the IpAddress allowed or denied. This is for requests through a browser to the Kibana dashboard, so this needs to work through unsigned requests.
Looking at Identity and Access Management in Amazon OpenSearch Service, I understand that I should be able to limit by domain, index, and documents by desired actions (i.e. GET, POST, PUT, etc) for whichever IpAddress. However, unless I have it wide open by domain, I keep getting the error message:
"User: anonymous is not authorized to perform: es:ESHttpGet because no
resource-based policy allows the es:ESHttpGet action"
My Access Policy doesn't look like it has any syntax error in it to me. I am wondering if there is a setting I need to set to allow this that I am missing. I haven't found any reference to any such thing so far, unless I overlooked it.
My Access Policy looks something like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:region:id:domain/domainname/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"123.123.123.123",
"456.456.456.456"
]
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:ESHttpGet",
"Resource": "arn:region:id:domain/domainname/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"789.789.789.789"
]
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:ESHttpGet",
"Resource": "arn:region:id:domain/domainname/indexname1/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"120.450.780.230"
]
}
}
},
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "es:ESHttpGet",
"Resource": "arn:region:id:domain/domainname/indexname2/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"120.450.780.230"
]
}
}
}
]
}
It is anything but the first Effect clause, which is wide open, that gives me the error message. I don't know what I am missing. It looks virtually identical to the documentation.
I am also trying to prevent the deletion of the indexes and data through this access policy and haven't found that syntax.
Thanks for your help in advance.
I am trying to give lambda execution access to select members within a group. Users are authenticated via PingFederate. I am having issue granting this selective access to federated user.
I have a custom IAM policy (allow-lambda-invocation-selective) attached to this role. Although the policy seems to pass validation and policy simulation shows access is allowed, when I try to execute the lambda function I get message
Calling the invoke API action failed with this message: User:arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234 is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:123456789012:function:my-lambda-function
Here is my policy: allow-lambda-invocation-selective
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction",
"lambda:InvokeAsync",
"lambda:ListVersionsByFunction",
"lambda:GetFunction",
"lambda:ListAliases"
],
"Resource": "arn:aws:lambda:*:123456789012:function:my-lambda-function",
"Condition": {
"StringEquals": {
"aws:userid": "arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"lambda:ListFunctions",
"lambda:ListEventSourceMappings",
"lambda:ListLayers",
"lambda:ListLayerVersions"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:userid": "arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234"
}
}
}
]
}
Am i missing something?
I'm trying to understand your problem. Correct me if I made a wrong supposition.
Every group/user already have its own role.
When you authenticate your users, they have their assumed role. myuser1234, when authenticated, will receive arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234 role, right? Is it possible to create one role for each group and remove the conditions property (check item 2 explaining why)?
// role-for-grp-l2
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction",
"lambda:InvokeAsync",
"lambda:ListVersionsByFunction",
"lambda:GetFunction",
"lambda:ListAliases"
],
"Resource": "arn:aws:lambda:*:123456789012:function:my-lambda-function"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"lambda:ListFunctions",
"lambda:ListEventSourceMappings",
"lambda:ListLayers",
"lambda:ListLayerVersions"
],
"Resource": "*"
}
]
}
The problem with aws:userid
Reading the docs about the key aws:userid we can find this key has the value given by role id:caller-specified-role-name,
where role id is the unique id of the role and the caller-specified-role-name is specified by the RoleSessionName parameter passed to the AssumeRole request.
So aws:userid has value like AIDAJQABLZS4A3QDU576Q:SomeNameYouGive. Because this, your condition never match arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234 and then user cannot assume that actions.
Using conditions another way
Assuming RoleSessionName is the user name, you can use conditions this way:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction",
"lambda:InvokeAsync",
"lambda:ListVersionsByFunction",
"lambda:GetFunction",
"lambda:ListAliases"
],
"Resource": "arn:aws:lambda:*:123456789012:function:my-lambda-function",
"Condition": {
"StringLike": {
"aws:userid": "*:myuser1234"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"lambda:ListFunctions",
"lambda:ListEventSourceMappings",
"lambda:ListLayers",
"lambda:ListLayerVersions"
],
"Resource": "*",
"Condition": {
"StringLike": {
"aws:userid": "*:myuser1234"
}
}
}
]
}
if you prefer, you may remove * wildcard getting role id using AWS CLI with the command:
aws iam get-role --role-name ROLE_NAME
and changing condition as follows:
"Condition": {
"StringEquals": {
"aws:userid": "ROLE_ID:myuser1234"
}
}
I want a user to be able to login to an aws account and start and stop ONE specific ec2-instance.
So far I found out that ec2 describe only works with a catch -all star "*" in the resources.
The user can login, sees all the instances BUT he can't start or stop the instance because a permission denied error shows up :(
This is my policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TheseActionsDontSupportResourceLevelPermissions",
"Effect": "Allow",
"Action": [
"ec2:Describe*"
],
"Resource": "*"
},
{
"Sid": "TheseActionsSupportResourceLevelPermissions",
"Effect": "Allow",
"Action": [
"ec2:TerminateInstances",
"ec2:StopInstances",
"ec2:StartInstances"
],
"Resource": "arn:aws:ec2:eu-central-1a:MY_ACCOUNT_ID:instance/MY_INSTANCE_ID"
}
]
}
The answer is, you can't.
The ec2:Stopinstances, ec2:StartInstances and ec2:TerminateInstances do indeed support resource level permissions, but not for the condition key of instance id. They support the condition keys:
ec2:AvailabilityZone
ec2:EbsOptimized
ec2:InstanceProfile
ec2:InstanceType
ec2:PlacementGroup
ec2:Region
ec2:ResourceTag/tag-key
ec2:RootDeviceType
ec2:Tenancy
This is highlighted in the documentation here. (Search for the API calls on the page)
The only potentially useful condition key is ec2:ResourceTag/tag-key. You could add a resource tag on the particular instance and allow the user permission to call these 3 API calls on instances with that tag.
However, unless you had the API calls related to tags denied, there would be nothing to stop the user adding the tag to another instance, and performing the API calls on that instance too. You'd need to establish if denying tagging suits your situation.
Hope this helps.
Let me provide a working example:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances"
],
"Resource": [
"arn:aws:ec2:ap-south-1:222222222222:instance/i-02222222222222ddb",
"arn:aws:ec2:ap-south-1:222222222222:security-group/sg-022222222abc"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Name": "my.dev-server.com"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeSecurityGroupRules",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeNetworkAcls",
"ec2:DescribeSecurityGroups",
"ec2:ModifySecurityGroupRules",
"ec2:DescribeInstanceStatus"
],
"Resource": "*"
}
]
}
I found this link also useful in understanding this answer.
I am trying to create an IAM Policy in Amazon AWS which will allow access to view or edit/modify a single security group. I have followed the AWS documentation, but am unsuccessfully able to make this policy work. The policy created is below:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt123456789123",
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroups",
"ec2:*"
],
"Resource": [
"arn:aws:ec2:us-east-1:000000000000:security-group/sg-a123a1a1"
]
}
]
}
Yes, I do realize that I have a redundant action, but I noticed you are able to specify Describe Security Group, but no option for Modify; therefore "*" was my only option; Thankfully, the resource should allow me to restrict this action to a single security group.
It is partly possible, please see https://serverfault.com/questions/575487/use-iam-to-allow-user-to-edit-aws-ec2-security-groups, it's actually possible to constrain editing to just one group, but I didn't get listing of just one group to work:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1413232782000",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstances",
"ec2:DescribeNetworkAcls",
"ec2:DescribeSecurityGroups"
],
"Resource": [
"*"
]
},
{
"Sid": "Stmt1413232782001",
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress"
],
"Resource": [
"arn:aws:ec2:us-east-1:<accountid>:security-group/sg-<id>"
]
}
]
}
Here is what I managed to put together and it works great!
Create the following policy and add it to a User Group or make one:
Update the items that are in {BRACKETS}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:DeleteSecurityGroup"
],
"Resource": "arn:aws:{REGION}:{ACCOUNT_NUMBER}:security-group/{NSG-ID}",
"Condition": {
"ArnEquals": {
"ec2:Vpc": "arn:aws:ec2:{REGION}:{ACCOUNT_NUMBER}:vpc/{VPC-ID}"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroupReferences",
"ec2:DescribeVpcs",
"ec2:DescribeSecurityGroups",
"ec2:DescribeStaleSecurityGroups"
],
"Resource": "*"
}
]
}
Well, it looks like the code formatter is not working right with this, but you can read the references here: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_ec2_securitygroups-vpc.html
Thanks!
You can add new rule to security group like
aws ec2 authorize-security-group-ingress --group-name MySecurityGroup --protocol tcp --port 3389 --cidr 203.0.113.0/24
And also change the tags as well.
I am trying to copy some files from my EC2 instance to S3 and using the following command
s3cmd put datafile s3://mybucket/datafile
and get the following error
ERROR: S3 error: Access Denied
I have the following IAM policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:*",
"s3:ListAllMyBuckets",
"s3:ListBucket"
],
"Resource": "*"
}
]
}
S3 Bucket Policy for mybucket
{
"Version": "2008-10-17",
"Id": "backupPolicy",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxx:user/xxxx"
},
"Action": [
"s3:ListBucket",
"s3:PutObjectAcl",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::mybucket/*",
"arn:aws:s3:::mybucket"
]
}
]
}
I am not sure what I am doing wrong. s3cmd ls s3://mybucket works fine.
I tried searching on SO for this issue, but all the posts basically ask you to add the IAM policy, which I already have.
I think you need to have write permissions for IAM in addition to List:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:*",
"s3:ListAllMyBuckets",
"s3:ListBucket"
],
"Resource": "*"
},
{
"Sid": "Stmt1406613887001",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
}
]
}
The user IAM policy needs the permissions to read/write, not (just) the bucket. AWS will always apply the more restrictive policies, and defaults to an implicit "deny".
I've found bucket policies are better suited for public access (ie. serving assets to the world), not restricting the principal. When you start combining bucket + user policies complications arise and it's often much easier to manage the user end.