Repository navigation
Reach the report indices through the plugin subject - #1232
DarshitChanpura wants to merge 2 commits into
Conversation
doExecute had no catch, so an exception raised while switching to the plugin subject left doExecute as a throw and the listener was never completed. A caller that only waits on the listener then waits forever. Complete it with listener.onFailure instead. Also lowers the line that names the subject's principal from info to debug, so an identity is not written on every transport action at a level that is on by default, and marks the subject volatile because assignSubject writes it from a different thread than the transport actions that read it. Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Both index classes wrapped the node client in SecureIndexClient, which stashed the thread context in every override, and the index creation path stashed again around admin().indices().create(). Point them at PluginClient instead, so every read and write to .opendistro-reports-definitions and .opendistro-reports-instances runs as the subject assigned through IdentityAwarePlugin, and delete SecureIndexClient. With the plugin client in place at initialize time, the per-request client choice in getAllReportDefinitions and getAllReportInstances resolves to the same client on both sides of the resource-sharing branch, so the parameter threaded in from the two list actions goes away. Which access list the search carries is still decided by the resource-sharing check. The index creation path reaches admin().indices(), which FilterClient routes back through doExecute, so it now runs as the plugin subject where previously SecureIndexClient delegated admin() to the raw client and the call site stashed by hand. The stash in PluginBaseAction is left in place. It is not system index access: it moves the caller's context onto the coroutine's pooled thread for the length of the request and leaves that thread as it was found. A comment now says so. Adds plugin-additional-permissions.yml with an empty cluster_permissions list. Index actions on a registered system index need no entry and this plugin issues only create, get, index, update, delete and search, none of which security classifies as a cluster permission. The key is present rather than the file omitted because security appends bulk to the parsed list. Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit 019a6cd. ⛔ Hard block: Issues at High severity or above will block this PR from merging.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1232 +/- ##
============================================
+ Coverage 73.12% 74.65% +1.53%
+ Complexity 406 403 -3
============================================
Files 68 67 -1
Lines 2221 2166 -55
Branches 236 233 -3
============================================
- Hits 1624 1617 -7
+ Misses 463 418 -45
+ Partials 134 131 -3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Description
Replaces
ThreadContext.stashContextwith the plugin subject assigned throughIdentityAwarePlugin, so reporting reaches its own system indices as its plugin subject rather than from an unrestricted stashed context.IdentityAwarePluginandutil.PluginClientare already onmain; this finishes the job by moving the remaining call sites onto them.30 of the 32 stash calls being removed were inside
SecureIndexClient, aClient-by-delegation wrapper that stashed in every override, wired at one site each inReportDefinitionsIndexandReportInstancesIndex. That class is deleted and both index classes now hold thePluginClient. The other two were the explicit stash around index creation in each of those classes.Both index classes touch exactly one index each,
.opendistro-reports-definitionsand.opendistro-reports-instances, and both are already registered throughgetSystemIndexDescriptors.Because the plugin client is now the client the index classes hold, the per-request client choice in
getAllReportDefinitionsandgetAllReportInstancesresolves to the same client on both sides of the resource-sharing branch, so the parameter threaded in from the two list actions is gone. Which access list the search carries is still decided by the resource-sharing check, unchanged.Two behaviour changes worth review:
SecureIndexClientdelegatedadmin()to the raw client, soadmin().indices().create()ran as the caller inside a hand written stash.PluginClientextendsFilterClient, whoseadmin()routes back throughdoExecute, so index creation now runs as the plugin subject as well.PluginClient.doExecutehad nocatch, so a failure raised while switching to the subject leftdoExecuteas a throw and the listener was never completed, leaving a listener only caller waiting. It is now reported throughlistener.onFailure. The same commit lowers the line naming the subject's principal from info to debug, so an identity is not written on every transport action at a level that is on by default, and marks the subject field volatile.The stash in
PluginBaseActionis deliberately kept. It is not system index access: the action captures the caller's context on the transport thread, then on the coroutine's pooled thread it stashes whatever the previous task left there, restores the caller's context for the length of the request, and lets the stash put the pooled thread back as it was found. Removing it would both run the request with a stale context and leak the caller's context to the next task on that thread. A comment now records why it is there.Also adds
plugin-additional-permissions.ymlwith an emptycluster_permissionslist. For index actions a plugin subject is already granted everything on its own registered system indices, and the migrated call sites issue onlyindices:admin/create, get, index, update, delete and search. None of the operations that security classifies as cluster permissions despite acting on indices (mget, msearch, scroll, multi term vectors, reindex, template admin) are used anywhere in the plugin, so there is nothing to grant. The key is present rather than the file omitted because security appends bulk to the list it parses.Testing
compileKotlin,compileTestKotlin,test,ktlintanddetektpass on JDK 21. 109 unit tests, no skips and no failures, against a baseline of 105 onmain; the four added tests are the whole delta.Both of the added tests that guard a behaviour were confirmed to fail without it: the synchronous failure test fails against the current
doExecutewith the exception escaping, and the context restore test fails if theActionListener.runBeforewiring is dropped. The fake subject in those tests stashes and restores around its body, the way both the security plugin's subject and core's noop subject do, so the tests do not pass for the wrong reason.Not verified by execution: the permissions file and the behaviour of the migrated call sites against a cluster with security installed. Unit tests do not go through the security plugin, so the reasoning about which actions need granting comes from reading security's privileges evaluator, not from a run. This repository does have a with security workflow, including a resource sharing enabled matrix leg, so CI will exercise it here; it was not run locally.
Related
Tracking issue: opensearch-project/opensearch-plugins#238
RFC: opensearch-project/security#4439
Check List
--signoff.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.