-
Notifications
You must be signed in to change notification settings - Fork 91
OpenSearch Cedarling demo plugin
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.
GET /students/_search
{
"query":{
"match_all":{
}
},
"ext": {
"tbac": {
"tokens": {
"access_token": "...",
"id_token": "...",
"userinfo_token": "..."
},
"context": { ... }
}
}
}
{
...
"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.
- 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
)
- 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
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
}
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.
- OpenSearch version targeted is 3.0.0