Access Policy-Getting Error "User:anonymous is not authorized to perform:es:ESHttpGet because no resource-based policy allows the es:ESHttpGet action" - elasticsearch

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.

Related

Does AWSSecretsManagerRotationPolicy policy apply to all secrets?

I'm trying to use an AWS lambda function (deployed with SAM) to rotate a secret. Reading AWSSecretsManagerRotationPolicy description says:
Gives permission to rotate a secret in AWS Secrets Manager. Source
Based on that, this is applied to a single secret, but seeing the Policy definition seems like it permits all secrets for a given Partition, Region, and AccountId:
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:DescribeSecret",
"secretsmanager:GetSecretValue",
"secretsmanager:PutSecretValue",
"secretsmanager:UpdateSecretVersionStage"
],
"Resource": {
"Fn::Sub": "arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:*"
},
"Condition": {
"StringEquals": {
"secretsmanager:resource/AllowRotationLambdaArn": {
"Fn::Sub": [
"arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:${functionName}",
{
"functionName": {
"Ref": "FunctionName"
}
}
]
}
}
}
},
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetRandomPassword"
],
"Resource": "*"
}
]
Is the description misleading, or did I misinterpret something?

How to provide selective access for lambda execution to a federated user in AWS IAM policy?

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"
}
}

Unable to update ElasticSearch access policy using CLI

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"
}
}
}
]
}'

Use of AWS null condition to prevent empty or missing tags?

The goal of my policy document:
Prevent resource creation if it does not have proper tags
Require that certain values be given to specific tags (e.g. env tag must either be dev OR stg OR prd, etc)
No. 2 works as expected; however, if the user creates an EC2 instance with the tag empty or simply forgets to add it, the policy still allows the user to create the instance.
I tried the null operator (referenced here), but it doesn't seem to work.
Another attempt was to use a condition matching aws:tag-keys values (referenced here), but it only appears to work when checking one single value with a StringLike comparison operator
This is prerequisite for a Lambda function to turn off dev instances.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RequireEnvTags",
"Effect": "Deny",
"Action": [
"ec2:RunInstances"
],
"Condition": {
"ForAnyValue:StringNotEquals": {
"ec2:ResourceTag/env": [
"dev",
"stg",
"prd",
"dev-noshutdown"
]
}
},
"Resource": [
"*"
]
},
{
"Sid": "RequireDataSensitivity1",
"Effect": "Deny",
"Action": [
"ec2:RunInstances"
],
"Condition": {
"ForAnyValue:StringNotEquals": {
"ec2:ResourceTag/data-sensitivity": [
"public",
"internal",
"confidential",
"highly confidential"
]
}
},
"Resource": [
"*"
]
},
{
"Sid": "NullChecksDontSeemToWork0",
"Effect": "Deny",
"Action": [
"ec2:RunInstances"
],
"Condition": {
"Null": {
"ec2:ResourceTag/Name": "true"
}
},
"Resource": [
"*"
]
},
{
"Sid": "NullChecksDontSeemToWork1",
"Effect": "Deny",
"Action": [
"ec2:RunInstances"
],
"Condition": {
"Null": {
"ec2:ResourceTag/team": "true"
}
},
"Resource": [
"*"
]
}
]
}
After working with this I found that it just needed to be tweaked a little. For some reason explicitly allowing the action in the same policy document (even though another policy document attached to the same user explicitly states an ALLOW) is required for AWS to implement the intended policy correctly:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*::image/ami-*",
"arn:aws:ec2:*:ACCOUNT_ID:subnet/*",
"arn:aws:ec2:*:ACCOUNT_ID:network-interface/*",
"arn:aws:ec2:*:ACCOUNT_ID:volume/*",
"arn:aws:ec2:*:ACCOUNT_ID:key-pair/*",
"arn:aws:ec2:*:ACCOUNT_ID:security-group/*"
],
"Sid": "AllowRunInstances"
},
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:ACCOUNT_ID:instance/*",
"Condition": {
"StringNotLike": {
"aws:RequestTag/env": [
"dev",
"stg",
"prd",
"dev-noshutdown",
"trn",
"tst"
]
}
},
"Sid": "RequireSpecificEnvTags"
}
]
}
And it works!
A quick note: currently this policy does not appear to allow Spot Instances to be created (Because of the differences in how spot requests handle tags). I filed a feature request with AWS.

IAM Policy for AWS EC2 start/stop instance

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.

Resources