opensearch-project / security

🔐 Secure your cluster with TLS, numerous authentication backends, data masking, audit logging as well as role-based access control on indices, documents, and fields
https://opensearch.org/docs/latest/security-plugin/index/
Apache License 2.0
189 stars 271 forks source link

[Bug] Bad parsing on DLS custom JWT attribute #4267

Open dbanshee opened 8 months ago

dbanshee commented 8 months ago

Describe the bug

he parsing of a JWT token field in a Document Leven Security role is not being done correctly.

Being this field a comma-separated, quoted list of user backend roles. Internal OpenSearch parsing appears to lost list item string quotes.

JWT field:

{
...
  "opensearch_roles": [
    "Ingest Management",
    "Platform WF Designer",
    "Platform Admin",
    "LowCode WF Viewer",
    "LowCode WF Designer",
    "Tenant Admin",
    "Site Admin",
    "Devel",
    "Shared Site Admin",
    "Tedial Ops",
    "offline_access",
    "Monitoring Management",
    "uma_authorization",
    "default-roles-tedial",
    "opensearch_search_site_malaga_role"
  ],
...
}

DLS on Role:

"dls": """{
  "terms": {
    "group_permissions.keyword": ${attr.jwt.opensearch_roles}
  }

Runtime Error:

Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'Ingest': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
opensearch-node1         |  at [Source: (String)"{
opensearch-node1         |   "terms": {
opensearch-node1         |     "group_permissions.keyword": [Ingest Management, Platform WF Designer, Platform Admin, LowCode WF Viewer, LowCode WF Designer, Tenant Admin, Site Admin, Devel, Shared Site Admin, Tedial Ops, offline_access, Monitoring Management, uma_authorization, default-roles-tedial, opensearch_search_site_malaga_role]
opensearch-node1         |   }
opensearch-node1         | }"; line: 3, column: 41]

Related component

Other

To Reproduce

Being this field a comma-separated, quoted list of user backend roles.

Containing my JWT Token opensearch_roles a list of quoted strings

...
  "azp": "smartwork-ui",
  "auth_time": 1702975960,
  "scope": "openid opensearch_scope tenant_id email profile",
  "exp": 1702976561,
  "session_state": "aebc1fdd-b85b-407c-982d-8be520beaa79",
  "iat": 1702975961,
  "jti": "b8e591d0-3116-4df1-9412-8f3a8ab8acb7",
  "email": "onamaya@tedial.com",
  "email_verified": false,
  "opensearch_roles": [
    "Ingest Management",
    "Platform WF Designer",
    "Platform Admin",
    "LowCode WF Viewer",
    "LowCode WF Designer",
    "Tenant Admin",
    "Site Admin",
    "Devel",
    "Shared Site Admin",
    "Tedial Ops",
    "offline_access",
    "Monitoring Management",
    "uma_authorization",
    "default-roles-tedial",
    "opensearch_search_site_malaga_role"
  ],
...

I'm trying to use a Doc Level Security (DLS) using this opensearch_roles files. But I encountered strange behaviour.

Acording to documentation

https://opensearch.org/docs/latest/security/access-control/document-level-security/#parameter-substitution

I can use a custom JWT field as

${attr.<TYPE>.<NAME>}   An attribute with name <NAME> defined for a user. <TYPE> is internal, jwt, proxy or ldap

I defined my role as

PUT _plugins/_security/api/roles/opensearch_search_site_malaga_role
{
    "cluster_permissions": [],
    "index_permissions": [
      {
        "index_patterns": [
          "test_acls_malaga"
        ],
        "dls": """{
  "terms": {
    "group_permissions.keyword": ${attr.jwt.opensearch_roles}
  }
}""",
        "fls": [],
        "masked_fields": [],
        "allowed_actions": [
          "search"
        ]
      }
    ],
    "tenant_permissions": []
  }

Additionally this role is mapped with a backend_role to match this role at searching stage.

GET _plugins/_security/api/rolesmapping/opensearch_search_site_malaga_role

{
  "opensearch_search_site_malaga_role": {
    "hosts": [],
    "users": [],
    "reserved": false,
    "hidden": false,
    "backend_roles": [
      "opensearch_search_site_malaga_role"
    ],
    "and_backend_roles": []
  }
}

Finally executing a search:

JWT_TOKEN='eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI2MTZhMDFiYS0zNjQ3LTRiYTQtYjBlMy1jYzdhNDI0ZTkzYzgiLCJ0ZW5hbnRfaWQiOiJ0ZWRpYWxfc3dvcmtkZXYwMiIsIkdyb3VwIjpbImV2ZXJ5b25lIl0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1hcHBsaWNhdGlvbnMiLCJ2aWV3LWNvbnNlbnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsIm1hbmFnZS1jb25zZW50IiwiZGVsZXRlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX19LCJhbGxvd2VkLW9yaWdpbnMiOlsiKiJdLCJpc3MiOiJ2b3lhZ2VyLWd3IiwidHlwIjoiQmVhcmVyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoib25hbWF5YSIsInNpZCI6ImMzZDNhMDE1LTk0N2UtNDNmMC1iN2JiLTM2MTUxZDJhMDczZSIsImFjciI6ImRlZmF1bHQiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiSW5nZXN0IE1hbmFnZW1lbnQiLCJQbGF0Zm9ybSBXRiBEZXNpZ25lciIsIlBsYXRmb3JtIEFkbWluIiwiTG93Q29kZSBXRiBWaWV3ZXIiLCJMb3dDb2RlIFdGIERlc2lnbmVyIiwiVGVuYW50IEFkbWluIiwiU2l0ZSBBZG1pbiIsIkRldmVsIiwiU2hhcmVkIFNpdGUgQWRtaW4iLCJUZWRpYWwgT3BzIiwib2ZmbGluZV9hY2Nlc3MiLCJNb25pdG9yaW5nIE1hbmFnZW1lbnQiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtdGVkaWFsIiwib3BlbnNlYXJjaF9zZWFyY2hfc2l0ZV9tYWxhZ2Ffcm9sZSJdfSwiYXpwIjoic21hcnR3b3JrLXVpIiwiYXV0aF90aW1lIjoxNzAyOTc2NjEzLCJzY29wZSI6Im9wZW5pZCBvcGVuc2VhcmNoX3Njb3BlIHRlbmFudF9pZCBlbWFpbCBwcm9maWxlIiwiZXhwIjoxNzAyOTc3MjE0LCJzZXNzaW9uX3N0YXRlIjoiYzNkM2EwMTUtOTQ3ZS00M2YwLWI3YmItMzYxNTFkMmEwNzNlIiwiaWF0IjoxNzAyOTc2NjE0LCJqdGkiOiI3Y2EwZDQ2My1jYjQ3LTQ2ZjMtYTFmNi1mN2M2MzgzNTNlYzEiLCJlbWFpbCI6Im9uYW1heWFAdGVkaWFsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwib3BlbnNlYXJjaF9yb2xlcyI6WyJJbmdlc3QgTWFuYWdlbWVudCIsIlBsYXRmb3JtIFdGIERlc2lnbmVyIiwiUGxhdGZvcm0gQWRtaW4iLCJMb3dDb2RlIFdGIFZpZXdlciIsIkxvd0NvZGUgV0YgRGVzaWduZXIiLCJUZW5hbnQgQWRtaW4iLCJTaXRlIEFkbWluIiwiRGV2ZWwiLCJTaGFyZWQgU2l0ZSBBZG1pbiIsIlRlZGlhbCBPcHMiLCJvZmZsaW5lX2FjY2VzcyIsIk1vbml0b3JpbmcgTWFuYWdlbWVudCIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy10ZWRpYWwiLCJvcGVuc2VhcmNoX3NlYXJjaF9zaXRlX21hbGFnYV9yb2xlIl0sImdpdmVuX25hbWUiOiJvc2NhciIsIm5vbmNlIjoiZDMzZjQ4N2ItYzc0YS00NTdkLWE0ZjMtYmVjNzNkYzhkNzJlIiwiYXVkIjpbImFjY291bnQiXSwibmFtZSI6Im9zY2FyIGFtYXlhIiwiZmFtaWx5X25hbWUiOiJhbWF5YSIsInVzZXIiOnsiaWQiOjAsIm5hbWUiOiJvbmFtYXlhIiwiZGVzY3JpcHRpb24iOm51bGwsImVtYWlsIjoib25hbWF5YUB0ZWRpYWwuY29tIiwidGVuYW50IjoidGVkaWFsX3N3b3JrZGV2MDIiLCJzaXRlIjoiIiwicm9sZXMiOlsiZXZlcnlvbmUiLCJJbmdlc3QgTWFuYWdlbWVudCIsIlBsYXRmb3JtIFdGIERlc2lnbmVyIiwiUGxhdGZvcm0gQWRtaW4iLCJMb3dDb2RlIFdGIFZpZXdlciIsIkxvd0NvZGUgV0YgRGVzaWduZXIiLCJUZW5hbnQgQWRtaW4iLCJTaXRlIEFkbWluIiwiRGV2ZWwiLCJTaGFyZWQgU2l0ZSBBZG1pbiIsIlRlZGlhbCBPcHMiLCJvZmZsaW5lX2FjY2VzcyIsIk1vbml0b3JpbmcgTWFuYWdlbWVudCIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy10ZWRpYWwiLCJvcGVuc2VhcmNoX3NlYXJjaF9zaXRlX21hbGFnYV9yb2xlIl19LCJyb2xlcyI6ImV2ZXJ5b25lLEluZ2VzdCBNYW5hZ2VtZW50LFBsYXRmb3JtIFdGIERlc2lnbmVyLFBsYXRmb3JtIEFkbWluLExvd0NvZGUgV0YgVmlld2VyLExvd0NvZGUgV0YgRGVzaWduZXIsVGVuYW50IEFkbWluLFNpdGUgQWRtaW4sRGV2ZWwsU2hhcmVkIFNpdGUgQWRtaW4sVGVkaWFsIE9wcyxvZmZsaW5lX2FjY2VzcyxNb25pdG9yaW5nIE1hbmFnZW1lbnQsdW1hX2F1dGhvcml6YXRpb24sZGVmYXVsdC1yb2xlcy10ZWRpYWwsb3BlbnNlYXJjaF9zZWFyY2hfc2l0ZV9tYWxhZ2Ffcm9sZSIsInRlbmFudCI6InRlZGlhbF9zd29ya2RldjAyIiwic2l0ZSI6IiJ9.IQBNY3EEM1cMyDbLTnQUvz6ckJ0liDz_RYx3rOLx4IlwOtqyQjzEvs3dlyzlmGMWlFtB1aUPew1RISLLzpC0jw'

curl -XPOST "http://localhost:9200/test_acls_malaga/_search" --insecure -H 'Content-Type: application/json' -H "Authorization: Bearer ${JWT_TOKEN}" -v -i

* Connection #0 to host l left intact
{"error":{"root_cause":[{"type":"security_exception","reason":"Unexpected exception indices:data/read/search"}],"type":"security_exception","reason":"Unexpected exception indices:data/read/search"},"status":500}

Examining opensearch log i found this error.

opensearch-node1         |      at java.lang.Thread.run(Thread.java:833) [?:?]
opensearch-node1         | Caused by: java.lang.RuntimeException: Error while parsing {
opensearch-node1         |   "terms": {
opensearch-node1         |     "group_permissions.keyword": [Ingest Management, Platform WF Designer, Platform Admin, LowCode WF Viewer, LowCode WF Designer, Tenant Admin, Site Admin, Devel, Shared Site Admin, Tedial Ops, offline_access, Monitoring Management, uma_authorization, default-roles-tedial, opensearch_search_site_malaga_role]
opensearch-node1         |   }
opensearch-node1         | }
opensearch-node1         |      at org.opensearch.security.configuration.DlsQueryParser.parse(DlsQueryParser.java:124) ~[opensearch-security-2.8.0.0.jar:2.8.0.0]
opensearch-node1         |      at org.opensearch.security.configuration.DlsQueryParser.lambda$containsTermLookupQuery$1(DlsQueryParser.java:149) ~[opensearch-security-2.8.0.0.jar:2.8.0.0]
opensearch-node1         |      at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4853) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      ... 76 more
opensearch-node1         | Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'Ingest': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
opensearch-node1         |  at [Source: (String)"{
opensearch-node1         |   "terms": {
opensearch-node1         |     "group_permissions.keyword": [Ingest Management, Platform WF Designer, Platform Admin, LowCode WF Viewer, LowCode WF Designer, Tenant Admin, Site Admin, Devel, Shared Site Admin, Tedial Ops, offline_access, Monitoring Management, uma_authorization, default-roles-tedial, opensearch_search_site_malaga_role]
opensearch-node1         |   }
opensearch-node1         | }"; line: 3, column: 41]
opensearch-node1         |      at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2477) ~[jackson-core-2.15.1.jar:2.15.1]
opensearch-node1         |      at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:760) ~[jackson-core-2.15.1.jar:2.15.1]
opensearch-node1         |      at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:3041) ~[jackson-core-2.15.1.jar:2.15.1]
opensearch-node1         |      at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:3019) ~[jackson-core-2.15.1.jar:2.15.1]
opensearch-node1         |      at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchToken(ReaderBasedJsonParser.java:2793) ~[jackson-core-2.15.1.jar:2.15.1]
opensearch-node1         |      at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:2066) ~[jackson-core-2.15.1.jar:2.15.1]
opensearch-node1         |      at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:808) ~[jackson-core-2.15.1.jar:2.15.1]
opensearch-node1         |      at org.opensearch.common.xcontent.json.JsonXContentParser.nextToken(JsonXContentParser.java:65) ~[opensearch-x-content-2.8.0.jar:2.8.0]
opensearch-node1         |      at org.opensearch.index.query.TermsQueryBuilder.parseValues(TermsQueryBuilder.java:438) ~[opensearch-2.8.0.jar:2.8.0]
opensearch-node1         |      at org.opensearch.index.query.TermsQueryBuilder.fromXContent(TermsQueryBuilder.java:387) ~[opensearch-2.8.0.jar:2.8.0]
opensearch-node1         |      at org.opensearch.search.SearchModule.lambda$registerQuery$19(SearchModule.java:1270) ~[opensearch-2.8.0.jar:2.8.0]
opensearch-node1         |      at org.opensearch.core.xcontent.NamedXContentRegistry.parseNamedObject(NamedXContentRegistry.java:171) ~[opensearch-core-2.8.0.jar:2.8.0]
opensearch-node1         |      at org.opensearch.core.xcontent.AbstractXContentParser.namedObject(AbstractXContentParser.java:429) ~[opensearch-core-2.8.0.jar:2.8.0]
opensearch-node1         |      at org.opensearch.index.query.AbstractQueryBuilder.parseInnerQueryBuilder(AbstractQueryBuilder.java:330) ~[opensearch-2.8.0.jar:2.8.0]
opensearch-node1         |      at org.opensearch.security.configuration.DlsQueryParser$1.call(DlsQueryParser.java:117) ~[opensearch-security-2.8.0.0.jar:2.8.0.0]
opensearch-node1         |      at org.opensearch.security.configuration.DlsQueryParser$1.call(DlsQueryParser.java:111) ~[opensearch-security-2.8.0.0.jar:2.8.0.0]
opensearch-node1         |      at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4853) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache.get(LocalCache.java:3951) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4848) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at org.opensearch.security.configuration.DlsQueryParser.parse(DlsQueryParser.java:111) ~[opensearch-security-2.8.0.0.jar:2.8.0.0]
opensearch-node1         |      at org.opensearch.security.configuration.DlsQueryParser.lambda$containsTermLookupQuery$1(DlsQueryParser.java:149) ~[opensearch-security-2.8.0.0.jar:2.8.0.0]
opensearch-node1         |      at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4853) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      ... 76 more
opensearch-node1         | [2023-12-19T09:03:55,383][WARN ][r.suppressed             ] [opensearch-node1] path: /test_acls_malaga/_search, params: {index=test_acls_malaga}

In particular:

opensearch-node1         | Caused by: java.lang.RuntimeException: Error while parsing {
opensearch-node1         |   "terms": {
opensearch-node1         |     "group_permissions.keyword": [Ingest Management, Platform WF Designer, Platform Admin, LowCode WF Viewer, LowCode WF Designer, Tenant Admin, Site Admin, Devel, Shared Site Admin, Tedial Ops, offline_access, Monitoring Management, uma_authorization, default-roles-tedial, opensearch_search_site_malaga_role]
opensearch-node1         |   }
opensearch-node1         | }

The parser sustitution appears to has lost the string quotes on JWT list elements.

Another test including '[]' on DLS doesn't work either. Only wrap the previous value on '[...]'

opensearch-node1         | Caused by: java.lang.RuntimeException: Error while parsing {
opensearch-node1         |   "terms": {
opensearch-node1         |     "group_permissions.keyword": [[Ingest Management, Platform WF Designer, Platform Admin, LowCode WF Viewer, LowCode WF Designer, Tenant Admin, Site Admin, Devel, Shared Site Admin, Tedial Ops, offline_access, Monitoring Management, uma_authorization, default-roles-tedial, opensearch_search_site_malaga_role]]
opensearch-node1         |   }
opensearch-node1         | }
opensearch-node1         |      at org.opensearch.security.configuration.DlsQueryParser.parse(DlsQueryParser.java:124) ~[opensearch-security-2.8.0.0.jar:2.8.0.0]
opensearch-node1         |      at org.opensearch.security.configuration.DlsQueryParser.lambda$containsTermLookupQuery$1(DlsQueryParser.java:149) ~[opensearch-security-2.8.0.0.jar:2.8.0.0]
opensearch-node1         |      at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4853) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) ~[guava-30.0-jre.jar:?]
opensearch-node1         |      ... 76 more
opensearch-node1         | Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'Ingest': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
opensearch-node1         |  at [Source: (String)"{
opensearch-node1         |   "terms": {
opensearch-node1         |     "group_permissions.keyword": [[Ingest Management, Platform WF Designer, Platform Admin, LowCode WF Viewer, LowCode WF Designer, Tenant Admin, Site Admin, Devel, Shared Site Admin, Tedial Ops, offline_access, Monitoring Management, uma_authorization, default-roles-tedial, opensearch_search_site_malaga_role]]
opensearch-node1         |   }
opensearch-node1         | }"; line: 3, column: 42]

Expected behavior

DLS use the custom list attribute to filter de documents on search.

Additional Details

Plugins

opensearch-node2 opensearch-alerting                  2.8.0.0
opensearch-node2 opensearch-anomaly-detection         2.8.0.0
opensearch-node2 opensearch-asynchronous-search       2.8.0.0
opensearch-node2 opensearch-cross-cluster-replication 2.8.0.0
opensearch-node2 opensearch-geospatial                2.8.0.0
opensearch-node2 opensearch-index-management          2.8.0.0
opensearch-node2 opensearch-job-scheduler             2.8.0.0
opensearch-node2 opensearch-knn                       2.8.0.0
opensearch-node2 opensearch-ml                        2.8.0.0
opensearch-node2 opensearch-neural-search             2.8.0.0
opensearch-node2 opensearch-notifications             2.8.0.0
opensearch-node2 opensearch-notifications-core        2.8.0.0
opensearch-node2 opensearch-observability             2.8.0.0
opensearch-node2 opensearch-performance-analyzer      2.8.0.0
opensearch-node2 opensearch-reports-scheduler         2.8.0.0
opensearch-node2 opensearch-security                  2.8.0.0
opensearch-node2 opensearch-security-analytics        2.8.0.0
opensearch-node2 opensearch-sql                       2.8.0.0
opensearch-node1 opensearch-alerting                  2.8.0.0
opensearch-node1 opensearch-anomaly-detection         2.8.0.0
opensearch-node1 opensearch-asynchronous-search       2.8.0.0
opensearch-node1 opensearch-cross-cluster-replication 2.8.0.0
opensearch-node1 opensearch-geospatial                2.8.0.0
opensearch-node1 opensearch-index-management          2.8.0.0
opensearch-node1 opensearch-job-scheduler             2.8.0.0
opensearch-node1 opensearch-knn                       2.8.0.0
opensearch-node1 opensearch-ml                        2.8.0.0
opensearch-node1 opensearch-neural-search             2.8.0.0
opensearch-node1 opensearch-notifications             2.8.0.0
opensearch-node1 opensearch-notifications-core        2.8.0.0
opensearch-node1 opensearch-observability             2.8.0.0
opensearch-node1 opensearch-performance-analyzer      2.8.0.0
opensearch-node1 opensearch-reports-scheduler         2.8.0.0
opensearch-node1 opensearch-security                  2.8.0.0
opensearch-node1 opensearch-security-analytics        2.8.0.0
opensearch-node1 opensearch-sql                       2.8.0.0

Host/Environment (please complete the following information):

Running Opensearch on Docker environment.

stephen-crawford commented 4 months ago

[Triage] Hi @dbanshee thank you for filing this issue. Someone will take a closer look at your scenario and reach out with any questions.

In the meantime, @dbanshee could you please confirm whether you are still running into trouble with this issue?

dbanshee commented 4 months ago

[Triage] Hi @dbanshee thank you for filing this issue. Someone will take a closer look at your scenario and reach out with any questions.

In the meantime, @dbanshee could you please confirm whether you are still running into trouble with this issue?

I managed to avoid the error by not using a custom field for the roles and using user.roles, modifying my token generation.

stephen-crawford commented 4 months ago

[Triage] Hi @dbanshee, I am happy to hear that you found a workaround for this. To address this we can at least add some documentation about this.

We can also look into further supporting the custom attribute setups similar to yours as a feature enhancement.

spettinichi commented 2 months ago

We have also run into this. I’m happy to see there’s already a ticket! In order to use values from a JWT as an array in the DLS query, you have to have the JWT field be a string of comma separated values with escaped quotes around them.. So instead of having in the JWT “opensearch_roles”: [ “A”, “B” ] it has to be “opensearch_roles”: “\”A\”,\”B\”” and then in DLS query "terms": { "group_permissions.keyword": [ ${attr.jwt.opensearch_roles} ] }

This makes the JWT ugly and much less useful in other contexts. It would definitely be good for this plugin to be able to utilize arrays.

Is there a timeline for this fix at all?