Skip to content

How to access fine-grained access control enabled (with cognito) OpenSearch domain from lambda

0

Hi all, I enabled fine grained access control with cognito for an OpenSearch domain. Cognito login works fine with master user role permissions. However I'm getting the following error when connecting to OpenSearch domain from Lambda. Error:

{ "type": "security_exception",
 "reason": "no permissions for [indices:admin/aliases, indices:admin/create] and User [name=arn:aws:iam::1234567890:role/ap-dev-lambda, backend_roles=[arn:aws:iam::1234567890:role/ap-dev-lambda], requestedTenant=null]" }

This is how I connect to OpenSearch:

import { Client } from '@opensearch-project/opensearch'
import { defaultProvider } from '@aws-sdk/credential-provider-node'
import { AwsSigv4Signer } from '@opensearch-project/opensearch/aws'

new Client({
      node: `https://${domainEndpoint}`,
      ...AwsSigv4Signer({
        region: process.env.AWS_REGION,
        getCredentials: () => defaultProvider()(),
      }),
    })

This is related domain CDK code:

this.domain = new opensearch.Domain(scope, domainId, {
...
fineGrainedAccessControl: {
        masterUserArn: this.cognito.masterUserRole.roleArn,
      },
      cognitoDashboardsAuth: {
        userPoolId: this.cognito.userPool.userPoolId,
        identityPoolId: this.cognito.identityPool.ref,
        role: this.cognito.openSearchCognitoAccessRole,
      },
...
})
    this.domain.addAccessPolicies(
      new iam.PolicyStatement({
        actions: ['es:ESHttp*'],
        principals: [new iam.AccountRootPrincipal()],
        resources: [`${this.domain.domainArn}/*`],
      })
    )
    this.cognito.masterUserRole.addToPolicy(
      new iam.PolicyStatement({
        effect: iam.Effect.ALLOW,
        actions: ['es:*'],
        resources: [`${this.domain.domainArn}/*`],
      })
    )

Lambda role arn:aws:iam::1234567890:role/ap-dev-lambda has this policy statement:

{
            "Action": [
                "*"
            ],
            "Resource": [
                "arn:aws:es:us-east-1:1234567890:domain/ap-dev-search",
                "arn:aws:es:us-east-1:1234567890:domain/ap-dev-search/*"
            ],
            "Effect": "Allow"
        }

But it works fine if I add lambda role arn:aws:iam::1234567890:role/ap-dev-lambda to the OpenSearch dashboard -> Security -> Roles -> all_access -> Mapped users.

I need to do this in CDK and Lambda code, but not sure how to do that.

Thank you!

1 Answer
0

Hello Halim,

To answer your question directly - You need to add the Lambda role in the "all_access" role or create another role with least privileges and map the lambda role to this newly created role in order for the lambda function to send requests to the domain.

[+] https://opensearch.org/docs/latest/security/access-control/users-roles/

Please note mapping users/roles to the backend pre-defined roles of the Opensearch cluster is not possible via CDK. However you can make Lambda role as the master role

FGAC auth and the error explanation

  • After a resource-based access policy allows a request to reach a domain endpoint, fine-grained access control evaluates the user credentials and either authenticates the user or denies the request. If fine-grained access control authenticates the user, it fetches all roles mapped to that user and uses the complete set of permissions to determine how to handle the request.

[+] https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html#fgac-access-policies [+] https://docs.aws.amazon.com/opensearch-service/latest/developerguide/search-example.html#search-example-perms

  • Currently using Cognito access you have allowed the cognito.masterUserRole access to the cluster, which maps this IAM role to "all_access" and "security_manager" predefined role in the backend.

  • Even though your Lambda role has the necessary permissions to access the Opensearch domain. This role is not mapped to any backend predefined roles.

  • Hence when your Lambda function makes a request to the cluster, fine-grained access control evaluates the user credentials and authenticates the user(since the role has permission to access the opensearch), however when it fetches all roles[predefined roles] mapped to that user, it observes the user does not have any permissions mapped and hence denies the API request, returning security exception.

Hope the above information clarifies why you needed to add the Lambda role in the "all_access" role and how the authentication takes place in AWS Opensearch.

answered a year ago

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.