AWS Elastic search change policy using lambda function - amazon-web-services

I am trying to change the elastic search access policy through lambda function using node js currently access policy looks like bellow
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:XXXX:domain/YYY/*"
}
]
}
the code which i have tried in lambda
var params = {
DomainName: 'YYYY'
};
const es = new AWS.ES();
es.upgradeElasticsearchDomain(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
this always throw error
is not authorized to perform: es:UpdateElasticsearchDomainConfig on resource with error code "code": "AccessDeniedException",
in the param i will add AccessPolicies this is same as the policy added in my question but the Effect will be Deny

After discussing it further with the OP, it turned out it was the lack of permissions on the IAM role attached to the Lambda function.
For others facing the same issue, make sure to attach ESFullAccess to the Lambda function that is playing with ElasticSearch.
To do so, go to IAM -> Roles and select the role attached to your Lambda function.
Click on attach policies and attach ESFullAccess, like the image below:

Related

Unable to get OpenSearch to publish alerts to Amazon SNS

I am having great difficulties in getting OpenSearch to publish alerts to Amazon SNS. I have set up the SNS topic and permissions properly, and set up the role for the SNS destination in OpenSearch per this link which I called “test-OpenSearch-Role”, but when the trigger activates and tries to send an alert I get the following error in the alert:
“Error: Failed running action: User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/cp-sts-grant-role/swift-us-west-2-prod-xxxxxxxxxxxx is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::xxxxxxxxxxxx:role/Test-OpenSearch-Role (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: 78e679a3-7373-4fe8-b1c1-a9b5d0d9dcda; Proxy: null)”
I’m not sure what this “User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/cp-sts-grant-role/swift-us-west-2-prod-xxxxxxxxxxxx” is and I haven’t been able to get it to obtain the permissions in the “test-OpenSearch-Role” to publish to SNS. I’m not very experienced when it comes to AWS inline policies for roles but here is the JSON of the test-OpenSearch-Role:
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: “sts:AssumeRole”,
“Resource”: “*"
},
{
“Effect”: “Allow”,
“Action”: “sns:Publish”,
“Resource”: "*”
}
]
}
What am I doing wrong? Any help or suggestions would be greatly appreciated.
I had the same error message when trying to send alerts from OpenSearch (and Elastic Search). As suggested above, I think the issue in your case may be the lack of a trust relationship.
I got it to work by setting the role used for alerts on OpenSearch / ElasticSearch (naviation: Kibana / Dashboard => alerting => destinations => edit) up with permissions (AWS => IAM => roles => find role => permissions) using this policy for publishing to SNS:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "*"
}
]
}
(for resources on the sns:publish policy, you can be more specific by putting the SNS ARN instead of "*": e.g. arn:aws:sns:<region>:<accountnumber>:<name>)
I also had to add this policy to the same role:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "*"
}
]
}
Then I needed "trust relationships" (next tab from permissions in IAM) like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "es.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Furthermore, make sure you copy the correct ARN from the role created into the OpenSearch (Elastic Search) alert settings: I wasted much time by mistakenly putting the "Instance profile ARN" from the top-right of the role summary instead of the "ARN" (in the middle). I.e. use arn:aws:iam::<accountnumber>:role/<rolename> and not arn:aws:iam::<accountnumber>:instance-profile/<rolename>.
My error message was something like this:
User: arn:aws:sts::444444143907:assumed-role/cp-sts-grant-role/swift-eu-central-1-prod-005555733555
is not authorized to perform: sts:AssumeRole on resource:
arn:aws:iam::005555733555:role/<myrolename>
(Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied;
Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxx; Proxy: null)"
...where 005555733555 is approximately my account number and 444444143907 some other account number. I didn't need to do anything particular with the other account number (such as explicitly allowing access from it)

AWS assumed-role unable to perform secretsmanager:GetSecretValue in serverless project

I have a serverless project written with node.js.
This service defines an IAM role for use at runtime with the following policy:
{
"Version": "2012-10-17",
"Statement": [
// statement to allow logging omitted
// statement for VPC stuff omitted (CreateNetworkInterface, etc)
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:eu-west-1:*:secret:my_secret_name-*"
}
]
}
I have a lambda that then tries to read that secrets:
import SecretsManager from 'aws-sdk/clients/secretsmanager' // v2
...
export const handler: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (event, context: any) => {
try {
const sm = new SecretsManager({ region }) // region is defined as "eu-west-1"
const secret = await sm.getSecretValue({
SecretId: 'my_secret_name'
})
} catch (e) {
console.error(e)
}
This errors with the following:
AccessDeniedException: User: arn:aws:sts::{accountId}:assumed-role/my-service-lambda-role/my-service-my-stage-my-function is not authorized to perform: secretsmanager:GetSecretValue
I'm not sure why the permissions would not allow me to retrieve the secret. I'm further not sure why this is using sts and using an assumed-role rather than just using the serverless lambda role directly. Can someone explain this to me and how to fix this?
NOTE: using the policysimulator, I can confirm the role created with the above policy does have access to read the defined secret, so this must be to do with assumed roles?

Not allowed: no-auth-role/CognitoIdentityCredentials is not authorized to perform: geo:ListGeofences on resource: xxxxx

I'm trying to use some of the new Amazon Location Service endpoints from the SDK itself (Location) and I have run into some inconsistent errors.
Even with everything allowed in the IAM Role geo:* (same for every resource), I always find errors of not authorization for functions like locationClient.listGeofences.
Arbitrarily, some other functions like getMapStyleDescriptor, searchPlaceIndexForText or calculateRoute do not give problems. Those functions are using their respective policies within geo:..., so it's pretty confusing to me to see how it detects some policies and others not.
The error is pretty common, it shows the following and the policy it's already allowed:
Uncaught (in promise) AccessDeniedException: User: arn:aws:sts::xxxx:assumed-role/AmazonLocationTestRole/CognitoIdentityCredentials is not authorized to perform: geo:ListGeofences on resource: arn:aws:geo:eu-west-1:xxxx:*
Note that the acess is for unauthenticated users withing an indentity pool in Cognito, but that shouldn't be the problem.
const client = new AWS.Location({
credentials: credentials,
region: AWS.config.region
});
console.log(await client.listGeofences({
CollectionName: "explore.geofence-collection"
}).promise())
console.log(await client.getMapStyleDescriptor({
MapName: mapName
}).promise());
Just in case, the trust relationships in the IAM role look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "eu-west-1:xxxx"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "unauthenticated"
}
}
}
]
}
And every policy for every resource in Amazon Location Service it's already allowed.
Do you have any idea what could be happening?
Many thanks!
According to https://docs.aws.amazon.com/location/latest/developerguide/authenticating-using-cognito.html#cognito-create-user-pool unauthenticated identities have access only to the following operations:
geo:GetMap*
geo:SearchPlaceIndex*
geo:BatchUpdateDevicePosition
geo:CalculateRoute

IAM tag policy with condition to prevent resource creation

My IAM user has the below two policies attached to it.
I created the below IAM policy that prevents lambda from being created if it does not have the Project tag.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": "lambda:*",
"Resource": "*",
"Condition": {
"Null": {
"aws:RequestTag/Project": "true"
}
}
}
]
}
I also need to attach/create a new execution role when creating lambda so I added below
Iam policy to my IAM user.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "iam:*",
"Resource": "*"
}
]
}
I logged into aws console using that IAM user's credentials and tried to create the lambda function without the tag, but it did'nt block the resource creation.I was able to create the lambda function without the required tag but with the following errors.
You are not authorized to perform: cloudformation:DescribeStackResources.
You are not authorized to perform: lambda:GetFunctionEventInvokeConfig.
User: arn:aws:iam::****:user/testuser is not authorized to perform: lambda:ListEventSourceMappings on resource: * with an explicit deny (Service: AWSLambda; Status Code: 403; Error Code: AccessDeniedException; Request ID: 199433ed*****)
How can I completely block the resource creation?
https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_example-scps.html#example-require-tag-on-create
Eventually I want to try aws:RequestTag/{TageKey} for all supported aws resources.
Not all AWS services/resources support aws:RequestTag as a condition key.
For lambda it is not allowed. Currently the supported condition keys on lambda:CreateFuncion Action are:
lambda:Layer
lambda:VpcIds
lambda:SubnetIds
lambda:SecurityGroupIds
lambda:CodeSigningConfigArn
As specified on table "Actions defined by AWS Lambda" on column "Condition keys".
https://docs.aws.amazon.com/service-authorization/latest/reference/list_awslambda.html#awslambda-actions-as-permissions
You can check that link and review any other service and validate if a specific Action support the Condition that you need.
For example, for EC2:RunInstances https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html supported conditions are:
aws:RequestTag/${TagKey}
aws:TagKeys
ec2:AvailabilityZone
ec2:EbsOptimized
ec2:InstanceMarketType
ec2:InstanceProfile
ec2:InstanceType
ec2:IsLaunchTemplateResource
ec2:LaunchTemplate
ec2:MetadataHttpEndpoint
ec2:MetadataHttpPutResponseHopLimit
ec2:MetadataHttpTokens
ec2:PlacementGroup
ec2:Region
ec2:RootDeviceType
ec2:Tenancy
So in that case you can restrict creation on new EC2 instances based on the presence of Tags but for Lambda it is not supported (for now).

AWS/Cognito/IAM Error with Unauth role

This message was originally posted on the AWS Developer Forums, but it seems like the AWS crowd is on SO, so I'm duplicating it here.
Hi there, I'm an absolute AWS beginner so I'll try to be as clear as possible.
I'm trying to use the JS API to allow any user on my site to upload videos to S3 (this works well) and then convert the uploaded files to other formats (with Elastic Transcoder).
I've set up:
an input (not public) and an output (public) buckets on S3. The input receives the user-submitted videos, that part works :)
an Elastic Transcoder pipeline (video-converter-test-pipeline-01)
a federated identity on Cognito (video_converter_test_02)
matching Auth and Unauth roles on IAM (Cognito_video_converter_test_02Auth_Role and Cognito_video_converter_test_02Unauth_Role)
The pipeline has the following permission summary: "The following IAM roles have been granted access to this pipeline: arn:aws:iam::529773801731:role/Elastic_Transcoder_Default_Role"
Cognito_video_converter_test_02Unauth_Role has two attached policies:
oneClick_Cognito_video_converter_test_02Unauth_Role_1522923667877
video-converter-policy, that I made myself.
Here's its JSON representation:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "elastictranscoder:CreateJob",
"Resource": [
"arn:aws:elastictranscoder:*:*:pipeline/*",
"arn:aws:elastictranscoder:*:*:preset/*"
]
}
]
}
Here's how I try to create a transcoding job using the JS API:
function createJob(uploadedFileKey) {
console.log("Create job", uploadedFileKey);
var params = {
PipelineId: PipelineId,
Input: {
Key: uploadedFileKey
},
Output: {
PresetId: PresetId
}
};
elastictranscoder.createJob(params, function (err, data) {
if (err) console.error(err, err.stack); // an error occurred
else console.log(data); // successful response
});
}
When executing it, I get the following error:
Error: User: arn:aws:sts::529773801731:assumed-role/Cognito_video_converter_test_02Unauth_Role/CognitoIdentityCredentials is not authorized to perform: elastictranscoder:CreateJob on resource: arn:aws:elastictranscoder:eu-west-1:529773801731:pipeline/1522763370759-mmowmr
I tried using IAM Policy Simulator to understand what was wrong, but when doing so with the same parameters, I get "allowed"...
I'm sure I'm doing something wrong here, but can't understand what. I've tried many things but nothing worked. Any help would be appreciated :)
Thanks in advance, bye!
I contacted AWS Developer Support and the solution seems to be to have these in the IAM Policy:
{
"Sid": "VisualEditor3",
"Effect": "Allow",
"Action": "cognito-sync:*",
"Resource": "*"
},
{
"Sid": "VisualEditor3",
"Effect": "Allow",
"Action": "mobileanalytics:PutEvents",
"Resource": "*"
}