aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.53k stars 3.86k forks source link

(aws-opensearchservice): grant_read does not grant all read operations permissons #17761

Open SamStephens opened 2 years ago

SamStephens commented 2 years ago

What is the problem?

aws-opensearchservice.Domain#grantRead grants permissions to use the GET and HEAD HTTP verbs.

However as per https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html [*], the search operations supports invocation via both GET and POST verbs. Further more the Opensearch Python client uses POST for search [**].

The end result being that grantRead does not actually provide the required permissions for basic read operations.

[*] I could not find the Opensearch version of this API reference page. [**] I've assigned a bug to the Opensearch-py library for this

Reproduction Steps

Too much code required to create a working repro here.

What did you expect to happen?

I would expect that grantRead would grant me permissions for all read operations. Failing that, I'd expect the documentation of the grant operations to talk about the limitations caused by the usage of HTTP verbs for IAM permissions purposes combined with Elasticsearch allowing usage of POST for read operations.

What actually happened?

grantRead does not grant permission for all read operations.

CDK CLI Version

1.134.0

Framework Version

No response

Node.js Version

14.17.0

OS

Windows 10 Professional: 10.0.19043 Build 19043

Language

Typescript, Python, .NET, Java, Go

Language Version

No response

Other information

No response

SamStephens commented 2 years ago

This is gnarlier than I realised, because POST is the only way to perform some operations that are technically part of a read. The main example is scroll, where you're posting to define a "search context" that you will then get consistent results from for a period of time.

POST is the correct verb, because you're setting state, but you're doing this as part of a "read" operation.

I think the core issue here is that it's a mistake to think you can use HTTP verbs to control access to Opensearch, and if you genuinely need read only access, you need FBAC.

As to what to do about this, I'm not sure; maybe just mention these limitations in the grant_* documentation.

bboure commented 1 year ago

Came across this today. Needed es:ESHttpPost, but did not want es:ESHttpDelete, etc (added by grantRedWrite())

Here is what I came up with, if that helps anyone:

    const readPolicy = new PolicyStatement({
      effect: Effect.ALLOW,
      actions: ["es:ESHttpPost", "es:ESHttpGet"],
      resources: [
        openSearchDomain.domainArn,
        Fn.join("", [openSearchDomain.domainArn, "/*"]),
      ],
    });
    myFunction.addToRolePolicy(readPolicy);