How to give lambda the least privilege access to OpenSearch domain with basic auth

0

Hi, we use TS CDK to create an OpenSearch domain and connect it from a lambda. Here is the code:

this.domain = new opensearch.Domain(scope, domainId, {...})
this.domainLambda = new nodejs.NodejsFunction(this, `${domainId}-domain`, {...})
this.domain.grantReadWrite(this.domainLambda)

This was working fine until we enable basic auth:

this.domain = new opensearch.Domain(scope, domainId, {
  fineGrainedAccessControl: {
    masterUserName: pass.secretValueFromJson('username').toString(),
    masterUserPassword: pass.secretValueFromJson('password'),
  },
  ...
})

// Lambda handler code:
new Client({
      node: `https://${domainEndpoint}`,
      auth: { username: '', password: '' },
    })

We properly pass the username and password when creating the Client and we can successfully connect to domain when we have this access policy:

this.domain.addAccessPolicies(
      new iam.PolicyStatement({
        actions: ['es:*'],
        effect: iam.Effect.ALLOW,
        principals: [new iam.AnyPrincipal()],
        resources: [`${this.domain.domainArn}`, `${this.domain.domainArn}/*`],
      })
    )

But this is not following the least privilege principle, we don't want to give the access to any principal. I wonder why the following policies don't work:

// Just lambda
this.domain.addAccessPolicies(
      new iam.PolicyStatement({
        actions: ['es:*'],
        effect: iam.Effect.ALLOW,
        principals: [this.domainLambda.grantPrincipal],
        resources: [`${this.domain.domainArn}`, `${this.domain.domainArn}/*`],
      })
    )

// This also doesn't work
this.domain.grantReadWrite(this.domainLambda)

// Even just lambda service doesn't work
this.domain.addAccessPolicies(
      new iam.PolicyStatement({
        actions: ['es:*'],
        effect: iam.Effect.ALLOW,
        principals: [new iam.ServicePrincipal('lambda.amazonaws.com')],
        resources: [`${this.domain.domainArn}`, `${this.domain.domainArn}/*`],
      })
    )

Whats the best way to give lambda to connect an OpenSearch domain and perform indexing actions with some cluster settings requests.

1 Answer
0

The lambda function itself doesn't directly interact with the OpenSearch domain; rather, it runs within an execution role that grants it permissions to perform certain actions. Therefore, you need to grant permissions to the execution role associated with your Lambda function.

  1. Ensure that the execution role associated with your Lambda function has the necessary permissions to access the OpenSearch domain. You can achieve this by adding appropriate permissions to the execution role.
const role = new iam.Role(this, 'LambdaExecutionRole', {
    assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});

// Attach permissions to the execution role
this.domain.grantReadWrite(role);
  1. Modify your Lambda function to assume this role when executing. You can achieve this by specifying the role property when creating the Lambda function.
this.domainLambda = new nodejs.NodejsFunction(this, `${domainId}-domain`, {
    // other properties
    role: role,
});

By doing this, you're ensuring that your Lambda function assumes a role with the necessary permissions to access the OpenSearch domain, rather than directly granting permissions to the Lambda function itself.

Remember to replace // other properties with the appropriate properties you've been using for your Lambda function.

AWS
answered 2 months ago
profile picture
EXPERT
reviewed a month ago
  • Hey, thanks for the answer. When using this.domain.grantReadWrite(this.domainLambda) it adds the following statement to the lambda execution role: {"Action": ["es:ESHttpDelete", "es:ESHttpGet", "es:ESHttpHead", "es:ESHttpPatch", "es:ESHttpPost", "es:ESHttpPut"], "Resource": ["arn:aws:es:us-east-1:123:domain/search/*", "arn:aws:es:us-east-1:123:domain/search/*/*"], "Effect": "Allow"}. So I guess it already sets the execution role properly.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions