Skip to content

OpenSearch Cedarling demo plugin

Michael Schwartz edited this page Jul 4, 2025 · 3 revisions

Summary

This plugin allows the interception of requests to the single index query endpoints:

GET /<index>/_search
POST /<index>/_search

(ref here) and filters the response - search hits - based on the cedarling configuration provided.

Sample request

GET /students/_search

{
    "query":{
        "match_all":{
        }
    },
    "ext": {
        "tbac": {
            "tokens": {
                "access_token": "...",
                "id_token": "...",
                "userinfo_token": "..."
            },
            "context": { ... }
        }
    }
}

Sample response

{
  ...
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "hits" : [
      {
        "_index" : "student",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "John Doe",
          "grad_year" : 2022
        }
      },
      {
        "_index" : "student",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "Gong Doe",
          "grad_year" : 2023
        }
      }
    ]
  },
  "ext" : {
    "cedarling" : {
      "average_decision_time" : 0.1,
      "authorized_hits_count" : 2
    }
  }
}

In this example, from the total of three hits found by OpenSearch, only two were authorized and returned in the result set.

Cedarling policy store

  • A store is created pointing to a trusted issuer (Jans server). Example policy store here
  • In the schema, an entity is created per every OpenSearch index (ie. database table) to support (eg. students)

Plugin installation

  • The generated plugin file (zip format) is transferred to some node in the cluster
  • CLI commands are issued to add the plugin. It is uncertain if/how the plugin is replicated throughout all nodes

Plugin configuration

Settings

OpenSearch provides endpoints for handling configuration settings. The way settings are declared and supplied in OpenSearch is not practical and support for JSON is clumsy. For this purpose, a special endpoint was created to GET and PUT plugin configurations. This allows to pass complex JSON objects without hassle. Under the hood everything is converted into a big string and stored as a single setting in Opensearch.

Example:

curl -u admin:password -H 'Content-Type: application/json' -d @payload.txt -X PUT https://localhost:9200/_plugins/cedarling/settings

where the payload looks like:

{
    "bootstrapProperties": {
        "CEDARLING_APPLICATION_NAME": "Cedarling OpenSearch demo",
        "CEDARLING_USER_AUTHZ": "enabled",
        "CEDARLING_JWT_SIG_VALIDATION": "enabled",
        "CEDARLING_JWT_STATUS_VALIDATION": "enabled",
        "CEDARLING_JWT_SIGNATURE_ALGORITHMS_SUPPORTED": [
            "HS256",
            "RS256"
        ],
        "CEDARLING_ID_TOKEN_TRUST_MODE": "none",
        "CEDARLING_MAPPING_USER": "Jans::User",
        "CEDARLING_POLICY_STORE_LOCAL": {
            "cedar_version": "4.4.0",
            "policy_stores": {
                "449805c83e13f332b1b35eac6ffa93187fbd1c648085": {
                    "name": "Cedarling OpenSearch demo",
                    "policies": {
                          "76acfe86fb09731682f92c4fbf7d2e066813ce639404": { ... }
                     }
                    "trusted_issuers": { ... },
                    "schema": { ... }
                },
                ...
            }
        }
    },
    "searchActionName": "Jans::Action::\"Search\"",
    "enabled": true
}

Pipeline configuration

For search requests to be effectively intercepted, a search pipeline must be created. There is an OpenSearch endpoint for this. Example:

PUT /_search/pipeline/cedarling_search

and the payload looks like:

{
  "response_processors": [
    {
      "cedarling" : {
        "tag" : "cedarling_response_1",
        "description" : "My dummy processor",
        "ignore_failure": false
      }
    }
  ]
}

Here cedarling is the name of the search response processor implemented by this plugin.

Additional notes

  • OpenSearch version targeted is 3.0.0
Clone this wiki locally