Skip to content

Onboards Alerting Plugin to Centralized Resource Authz - #2180

Merged
riysaxen-amzn merged 40 commits into
opensearch-project:mainfrom
DarshitChanpura:onbaord-resource-authz
Aug 25, 2026
Merged

Onboards Alerting Plugin to Centralized Resource Authz#2180
riysaxen-amzn merged 40 commits into
opensearch-project:mainfrom
DarshitChanpura:onbaord-resource-authz

Conversation

@DarshitChanpura

@DarshitChanpura DarshitChanpura commented Jun 20, 2026

Copy link
Copy Markdown
Member

Description

Implements resource-access-control for monitor.

Note — SdkUtils.await behavior change: the CompletionStage.await() helper now unwraps CompletionException/ExecutionException before resuming, so the underlying exception type and REST status survive the async boundary (e.g. a 409 VersionConflictEngineException is no longer masked as a 500). This affects all existing await() call sites, not just the resource-sharing paths.

Related Issues

Resolves #2195

Check List

  • New functionality includes testing.
  • New functionality has been documented.
  • API changes companion pull request created.
  • Commits are signed per the DCO using --signoff.
  • Public documentation issue/PR created.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@DarshitChanpura
DarshitChanpura force-pushed the onbaord-resource-authz branch from 5ad666c to 9a6e142 Compare June 20, 2026 07:07
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@DarshitChanpura
DarshitChanpura force-pushed the onbaord-resource-authz branch from 9a6e142 to b8fba5f Compare June 20, 2026 07:08
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@DarshitChanpura
DarshitChanpura force-pushed the onbaord-resource-authz branch from 2f06126 to 2576e6b Compare June 20, 2026 22:08
…bled

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Skip backend-role validation, permission checks, and filter injection
across all transport actions when the resource-sharing client is set.
For primary resources (monitors, workflows), rely on the security
plugin's DLS at the index layer. For subordinate resources (comments),
scope results by accessible monitor IDs via getAccessibleResourceIds.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
…fFoundError

Storing the RSC accessor result in a local val that lambdas close over
forces the JVM to link ResourceSharingClient when the closure is created.
Without the security plugin installed at runtime that class is absent,
crashing the node with NoClassDefFoundError. Call the accessor fresh
inside the lambda instead.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
return setOf(
object : ResourceProvider {
override fun resourceType(): String = "monitor"
override fun resourceIndexName(): String = SCHEDULED_JOBS_INDEX

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alerts and comments are treated as subordinate resources rather than registered resource types, so we don't register their indices with the sharing framework. Instead, access is inherited from the underlying monitor:

  • TransportGetAlertsAction / TransportGetWorkflowAlertsAction call rsc.getAccessibleResourceIds("monitor", ...) and add a monitor_id terms filter to the alert search.
  • TransportSearchAlertingCommentAction does the same via alert IDs derived from accessible monitors.
  • TransportIndexAlertingCommentAction / TransportDeleteAlertingCommentAction rely on the ActionFilter blocking the underlying alert fetch (via DocRequest on the requests, which points at the monitor).

New tests bob cannot see alice's monitor alerts without share and bob can see alice's monitor alerts after share in SecureResourceSharingMonitorRestApiIT cover this.

  resource sharing is enabled

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Rewrites SecureResourceSharingMonitorRestApiIT to exercise the full
matrix of security plugin ActionFilter paths that DocRequest enables:
- GET / UPDATE / DELETE with insufficient and sufficient share levels
- SEARCH DLS filtering per user
- alerts subordinate to monitor share via getAccessibleResourceIds
- SHARE and REVOKE round-trips

Users no longer carry all_access so RSC is the sole authorization gate.
Also updates existing unit tests to pass the new PluginClient constructor
parameter on the affected transport actions.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@DarshitChanpura

Copy link
Copy Markdown
Member Author

Heads up: CI on this branch will fail until common-utils#980 merges. That PR adds DocRequest to alerting request classes (GetAlertsRequest, AcknowledgeAlertRequest, IndexWorkflowRequest, GetWorkflowAlertsRequest, GetFindingsRequest, AcknowledgeChainedAlertRequest) which the transport actions here depend on for the security plugin's ActionFilter interception.

…s-load time

Store the client as Any? and return Any? from getResourceSharingClient()
so the JVM does not resolve ResourceSharingClient when loading the
accessor class. This prevents NoClassDefFoundError in test clusters that
run without the security plugin installed. Callers cast to
ResourceSharingClient inside null-guarded blocks where the security
plugin is guaranteed to be present.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
- Introduce ResourceSharingUtils with MONITOR_RESOURCE_TYPE constant and
  shouldUseResourceAuthz() helper, mirroring reporting plugin's pattern.
- Replace all `rsc != null` / `rsc == null` checks in transport actions
  with shouldUseResourceAuthz() so admin flows (and non-RSC deployments)
  fall through to the existing filter-by-backend-roles path when the
  security plugin is present but the RSC feature flag is disabled.
- Move the "monitor" literal out of every call site into a single
  constant referenced by both the extension and the utility helper.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Adds tests for scenarios missing from the initial suite:
- read-write share: can delete but cannot re-share (share permission
  belongs only to full-access)
- read-write share: owner sees edits made by the shared user
- full-access share: owner sees the deletion made by the shared user

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Reorganizes the suite around scenarios rather than API surfaces and adds
coverage for cases the earlier version missed:

- Owner-side positive controls (owner can always get / update / delete)
- Default-deny on every mutating action (get, update, delete, re-share)
- Explicit per-access-level positive and negative assertions
  (read-only, read-write, full-access) including "read-write cannot
  re-share" — the share permission belongs only to full-access
- Third-user isolation: share to bob does not grant carol access
- Cross-resource isolation: share on monitor A does not grant access to B
- Search DLS visibility (owned, shared, other-users')
- Subordinate resources: alerts and comments inherit monitor access;
  acknowledge and comment require read-write
- Downgrade: re-sharing at a lower level narrows permissions
- Revoke: removes access; does not affect other users' shares

Also introduces carol as a third user and switches to constants
(RS_ALICE/RS_BOB/RS_CAROL, READ_ONLY/READ_WRITE/FULL_ACCESS) to keep
assertions readable.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
- Map all three users (alice, bob, carol) to alerting_full_access in a
  single PUT rolesmapping call; the previous per-user PUTs replaced each
  other, leaving only the last-created user with the role.
- Create a shared test index and grant all three users index-level read
  access to it, then point the sample monitor's SearchInput at that
  index. Without this the monitor create fails at the security plugin's
  index-permission check ("User doesn't have read permissions for one or
  more configured index []").
- Clean up the test index and its role/rolesmapping in @after.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Removes the default parameter and updates every call site to pass
ResourceSharingUtils.MONITOR_RESOURCE_TYPE explicitly. Forces callers
to state which resource type they are gating on and future-proofs
against alerting registering additional resource types.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
…framework collision

flow-framework already registers a resource type named "workflow" in the shared
resource-sharing registry, so alerting must use a distinct identifier. Rename the
resource type (not the stored doc wrapper key, JSON paths, or transport action
names) from "workflow" to "alerting-workflow":

- ResourceSharingUtils.WORKFLOW_RESOURCE_TYPE constant (propagates to all
  workflow transport actions and AlertingResourceSharingExtension.resourceType())
- resource-access-levels.yml top-level type key
- integTest protected_types cluster setting
- extension unit-test assertions and the RSC migrate E2E test's protected_types
  and default_access_level map key

typeField()/ownerNamePath() ("/workflow/...") and the cluster:*/workflow/* action
names are unchanged -- they reference the stored ScheduledJob doc structure and
action registry, not the resource-sharing type.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Two fixes surfaced once CI could finally compile (security-spi snapshot caught
up with #6323), which exposed the security-enabled WorkflowRestApiIT delete tests:

1. TransportDeleteWorkflowAction restored the caller's ThreadContext in the
   delete coroutine, making the handler's config-index reads/deletes run as the
   caller. With resource sharing OFF the caller can't touch that system index
   (spurious 404 "Workflow not found"); with it ON a caller read races the async
   share-entry write. The restore was unnecessary: the security plugin's
   ResourceIndexListener.postDelete cleans up the share entry by resource id only
   and never reads the caller. Drop the restore so the handler runs on the plugin
   subject (as it did before RSC onboarding); postDelete cleanup still fires on
   the shard-level delete regardless of initiator.

2. Under resource sharing, GET-ing a just-deleted workflow/monitor returns 403
   (the RSC gate denies once the sharing entry is gone) rather than 404. The
   post-delete verification in the three delete-workflow tests now accepts either
   via a shared assertDeletedNotAccessible helper -- both mean "no longer
   accessible" -- mirroring the pattern already used in the secure monitor ITs.

Verified locally against fixed common-utils + security deps: all three delete
tests pass in both the plain security and resource-sharing-enabled variants.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
The security workflow ran the full IT suite (--tests '*IT') under both the
resource-sharing-disabled and -enabled variants. The backend-role / filterByAccessStrategy
secure suites (e.g. SecureMonitorRestApiIT) and the general functional ITs assume the
pre-resource-sharing access model, so they fail spuriously under RSC (monitor GET/HEAD/DELETE
now requires a sharing entry rather than a backend role). Resource-sharing access is covered by
its own dedicated suites.

Run the pre-RSC/functional suites only when resource sharing is OFF, and run only the
resource-sharing-specific suites (SecureResourceSharingMonitorRestApiIT, RscMigrateE2ERestApiIT
-- both already gated on the feature via assumeTrue) when it is ON.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@riysaxen-amzn

Copy link
Copy Markdown
Collaborator

Review: opensearch-project/alerting PR #2180 — Onboards Alerting Plugin to Centralized Resource Authz

Overall this is a well-executed onboarding. The ThreadContext choreography (capture-before-stash → restore for the shard-level ResourceIndexListener → per-call stash for internal-index writes via putDataObjectStashed/indexStashed) is handled carefully with clear comments explaining the why at each site. The alerting-workflow type naming (avoiding collision with flow-framework's workflow), the fail-closed shouldUseResourceAuthz (requires plugin present AND feature enabled for the type), and the E2E migration test are all solid.

A few items below, roughly in priority order.


1. Bug: getAccessibleAlertIDs caps results at 10 alerts

File: alerting/src/main/kotlin/org/opensearch/alerting/transport/TransportSearchAlertingCommentAction.kt (new getAccessibleAlertIDs)

The SearchSourceBuilder in getAccessibleAlertIDs never sets .size(), so the alerts search returns the default 10 hits:

val searchSourceBuilder = SearchSourceBuilder()
    .version(true)
    .seqNoAndPrimaryTerm(true)
    .query(queryBuilder)   // <-- no .size(), defaults to 10

Under RSC, comment search will silently drop comments for any alerts beyond the first 10 on accessible monitors. Suggest .size(MAX_SEARCH_SIZE) (mirroring the existing non-RSC getAlertIDs path) or scroll/PIT.


2. Question: does super-admin retain visibility under RSC?

Files: TransportGetAlertsAction.kt, TransportGetWorkflowAlertsAction.kt

The RSC branch is evaluated before the user == null (super-admin) branch:

if (ResourceSharingUtils.shouldUseResourceAuthz(...)) {
    // filter by accessible monitor IDs
} else if (user == null) {
    // super-admin path — never reached under RSC

Unless getAccessibleResourceIds special-cases admin/super-admin inside the security plugin, cluster admins will see zero alerts/monitors they don't own or aren't shared. The tests hint this is real (createMonitorAs notes the base helper's admin-client follow-up GET "fails under resource sharing because admin has no share on the newly-created monitor"). Is admin bypass handled framework-side? If not, this is a significant operational regression worth addressing or documenting.


3. Security: stale rbac_roles can be planted while RSC is on, then gate access when RSC is toggled off

Files: TransportIndexMonitorAction.kt, TransportIndexWorkflowAction.kt

Under RSC the legacy rbac_roles validation is skipped entirely:

if (
    !useRsc &&
    user != null &&
    !isAdmin(user) &&
    transformedRequest.rbacRoles != null

Since plugins.security.experimental.resource_sharing.enabled is dynamic (the E2E test toggles it at runtime), a non-admin user could persist arbitrary rbac_roles in a monitor doc while RSC is enabled. If RSC is later disabled, those backend roles become the access gate on the legacy path. Suggest still validating (or stripping) rbac_roles when RSC is on, so the doc can't carry roles the creator never had.


4. Production race: async postIndex sharing-entry write vs. immediate read

File: AlertingRestTestCase.kt (waitForResourceSharingEntry) — but the concern is production behavior

The tests poll .opendistro-alerting-config-sharing because create-then-immediately-get races the security plugin's async shard-level postIndex listener and gets a spurious 403 ("No sharing info found"). That same race exists in production: Dashboards creates a monitor and immediately GETs it on the detail page. This is framework-level rather than alerting-level, but it will surface as user-visible flaky 403s — worth an explicit tracking issue against the security plugin if one doesn't exist.


5. Scale: unbounded termsQuery on accessible resource IDs

Files: TransportGetAlertsAction.kt, TransportGetWorkflowAlertsAction.kt, TransportSearchAlertingCommentAction.kt

termsQuery("monitor_id", accessibleMonitorIds) will fail past index.max_terms_count (default 65,536) for tenants with very large monitor counts and broad shares. Fine for now, but a code comment or follow-up issue would be prudent.


6. Legacy destinations under RSC

File: TransportGetDestinationsAction.kt

Under RSC the destinations search routes through PluginClient and relies on the security plugin's DLS over the shared scheduled-jobs index. Destination docs are not a registered resource type and have no sharing entries / all_shared_principals — please confirm DLS doesn't hide legacy destinations entirely for non-admin users.


7. Nits

  • Hardcoded sharing-index name: test helpers hardcode .opendistro-alerting-config-sharing. If the security plugin can expose the naming convention (constant or SPI helper), prefer that to avoid silent breakage if the convention changes.
  • @Ignored FIXME tests: the two ignored subordinate-resource tests (comments-flow hang in CommentsIndices.createOrUpdateInitialCommentsHistoryIndex, alerts read-only inheritance DLS gap) have good in-code explanations — please link tracking issues so they don't get lost.
  • SdkUtils.await unwrapping: unwrapping CompletionException/ExecutionException is a nice fix (preserves e.g. 409 from VersionConflictEngineException), but it changes behavior for all existing await() call sites, not just RSC paths. Deserves a line in the PR description.
  • CI matrix: the RSC-enabled leg only running the two RSC suites is reasonable and well-commented; consider a periodic (nightly) full-suite RSC run later to catch interactions the filtered leg misses.

…, comments stash

Review feedback on opensearch-project#2180 (riysaxen-amzn):

- Super-admin visibility: the RSC filter branch preceded the `user == null`
  (super-admin) branch in the alerts/workflow-alerts/comment-search/destinations
  read paths, so a super-admin got filtered to only shared resources. Check
  `user == null` first so super-admin (and the security-disabled case) sees
  everything even under resource sharing.

- Bug: getAccessibleAlertIDs (and the legacy getFilteredAlertIDs) never set a
  search size, capping alert resolution at the default 10 and silently dropping
  comments for alerts beyond the first 10. Set size to MAX_SEARCH_SIZE.

- rbac_roles hardening: validation was skipped under RSC. Since the feature flag
  is dynamic, validate caller-supplied rbac_roles regardless of RSC so a
  non-admin can't persist roles they don't hold that would gate access if RSC is
  later disabled.

- Comments-history index bootstrap now runs on the plugin subject (stashed in
  the comment index action's start()); previously a non-admin caller's
  indices().exists() threw under RSC and the request hung.

- Destinations: super-admin now runs a direct (non-DLS) search so it isn't
  filtered by the resource-sharing DLS path.

- Document the index.max_terms_count bound at the monitor/workflow-id term
  filters; derive the sharing index name from the config index constant in test
  helpers rather than hardcoding.

Subordinate-resource alert/comment access tests remain @ignore'd pending the
child-resource sharing model in opensearch-project/security#6373 (updated the
FIXMEs to reference it). Verified SecureResourceSharingMonitorRestApiIT: 31 tests,
3 skipped, 0 failures under the resource-sharing variant.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

PR Code Analyzer ❗

AI-powered 'Code-Diff-Analyzer' found issues on commit 30a7584.

Hard block: Issues at High severity or above will block this PR from merging.

PathLineSeverityDescription
alerting/build.gradle177highNew dependency added: 'opensearch-security-spi' compileOnly artifact. Per mandatory rule, all new dependency additions must be flagged regardless of apparent legitimacy. Maintainers must verify artifact authenticity and that this SPI version matches the expected security plugin contract.
alerting/build.gradle167highopensearch-security plugin dependency changed from conditional (securityEnabled guard removed) to unconditional. It is now always resolved and installed. This expands the dependency surface and changes the deployment contract for non-security clusters.
alerting/build.gradle57highextendedPlugins now includes 'opensearch-security;optional=true' as a new plugin dependency declaration. Per mandatory rule, any build plugin or plugin-extension change must be flagged for maintainer verification.
build.gradle25highcommon_utils_version default changed from pinned '3.7.0.0-SNAPSHOT' to the dynamic 'opensearch_build' variable. The resolved artifact will now vary with build context, which can silently pull a different artifact version than previously pinned.
alerting/src/main/kotlin/org/opensearch/alerting/transport/TransportAcknowledgeAlertAction.kt96mediumvalidateUserBackendRoles and checkUserPermissionsWithResource are both short-circuited when shouldUseResourceAuthz returns true. This pattern repeats across ~10 transport actions. If ResourceSharingClientAccessor.setResourceSharingClient can be called by untrusted code via the SPI extension mechanism, an injected client whose isFeatureEnabledForType always returns true would bypass all legacy authorization checks across the plugin.
alerting/src/main/kotlin/org/opensearch/alerting/util/PluginClient.kt24mediumPluginClient explicitly executes transport actions as the plugin system subject to bypass user-level DLS. The subject is assigned via assignSubject called by the security plugin, but the client instance is stored in a nullable field and used across all resource-sharing search paths. A null subject causes an unguarded error() throw rather than a graceful denial, and the DLS bypass is broad — any caller that routes through PluginClient reads resources regardless of the caller's own permissions.
core/src/main/resources/mappings/scheduled-jobs.json7lowNew 'all_shared_principals' keyword field added to the scheduled-jobs index mapping. This field stores all principals with access to each resource and will be indexed and searchable. If the security plugin DLS implementation relies on this field being accurate, any process that can write to the scheduled-jobs index directly could manipulate access control by overwriting this field.

The table above displays the top 10 most important findings.

Total: 7 | Critical: 0 | High: 4 | Medium: 2 | Low: 1


Pull Requests Author(s): Please update your Pull Request according to the report above.

Repository Maintainer(s): You can bypass diff analyzer by adding label skip-diff-analyzer after reviewing the changes carefully, then re-run failed actions. To re-enable the analyzer, remove the label, then re-run all actions.


⚠️ Note: The Code-Diff-Analyzer helps protect against potentially harmful code patterns. Please ensure you have thoroughly reviewed the changes beforehand.

Thanks.

@DarshitChanpura

DarshitChanpura commented Aug 24, 2026

Copy link
Copy Markdown
Member Author

Thanks @riysaxen-amzn — addressed in ad0fbb9:

  • 1 (alert-search size): real bug — getAccessibleAlertIDs (and the legacy getFilteredAlertIDs, which had the same latent cap) now set .size(MAX_SEARCH_SIZE).

  • 2 (super-admin): super-admin now sees everything — moved the user == null check ahead of the resource-sharing filter branch in get-alerts, get-workflow-alerts, comment-search, and get-destinations.

  • 3 (rbac_roles): now validated even under RSC, so a non-admin can't persist roles they don't hold while the (dynamic) flag is on and have them gate access if RSC is later disabled.

  • 5 (max_terms_count): documented the bound at the monitor_id/workflow_id term filters.

  • 6 (destinations): super-admin now runs a direct (non-DLS) search so it isn't filtered.

  • Nits: the sharing-index name is derived from the config-index constant instead of hardcoded; the comments-history bootstrap now runs on the plugin subject (fixes the non-admin hang); the SdkUtils.await unwrap is called out in the PR description.

  • 4 (async postIndex race): I don't think this is a practical concern. The sharing entry is written with RefreshPolicy.IMMEDIATE and lands within milliseconds; the tests only hit the race because they fire the read programmatically microseconds after create (hence waitForResourceSharingEntry). No real client — including the Dashboards create→detail flow, which is a human/network round-trip — issues a sub-millisecond create-then-read, so it won't surface in practice. Leaving as-is.

The subordinate-resource alert/comment access tests stay @Ignored pending the child-resource (parent-linked) sharing model in opensearch-project/security#6373; the FIXMEs now reference it.

Verified SecureResourceSharingMonitorRestApiIT under the resource-sharing variant: 31 tests, 3 skipped, 0 failures.

@riysaxen-amzn

Copy link
Copy Markdown
Collaborator

Thanks @DarshitChanpura — verified ad0fbb9 against each item and everything checks out:

On #4: agreed, accepting your reasoning. RefreshPolicy.IMMEDIATE plus a human/network round-trip means the create→read gap is orders of magnitude larger than the sharing-entry write; only the tests' programmatic back-to-back calls can race it, and waitForResourceSharingEntry covers those. No change needed.

Good to see the @Ignored subordinate-resource tests now tracked against opensearch-project/security#6373.

The remaining Code-Diff-Analyzer High findings look like inherent-to-onboarding dependency flags (security-spi compile dep, unconditional security zip, common_utils tracking opensearch_build) rather than defects — presumably a maintainer skip-diff-analyzer review. With that and the common-utils#980 CI dependency resolved, no further concerns from my side.

@riysaxen-amzn

Copy link
Copy Markdown
Collaborator
  1. RSC-variant security job (the real failure): 24 of 32 tests failed in SecureResourceSharingMonitorRestApiIT + RscMigrateE2ERestApiIT — the suites this PR introduced. Two distinct signatures:

Dominant (~most failures): ParsingException: expecting token of type [END_OBJECT] but found [FIELD_NAME] → 500 on monitor GET/PUT. This is the security plugin's injected top-level field (all_shared_principals — the PR itself added it to the scheduled-jobs mapping) appearing in the doc _source, and ScheduledJob.parse choking on the unexpected extra field. The PR hardened JobSweeper.isSweepableJobType for exactly this, but not the transport GET/update parse path — that's the gap.
Secondary: RscMigrateE2ERestApiIT fails earlier — "After enabling RSC without migration, legacy monitor GET must fail" but the GET succeeded, suggesting the security snapshot's enforcement behavior changed. Plus cascading 404s in delete tests.

…ch-project#984 + opensearch-project#981

Common-utils 3.8 now includes the order-independent ScheduledJob.parse
(that tolerates security's ancillary all_shared_principals field) and
the DocRequest.type() overrides on alerting request classes (so the
security plugin's ResourceAccessEvaluator actually gates transport
GET/DELETE/etc. under RSC).

Empty commit to force the fresh 3.8.0.0-SNAPSHOT to be pulled on the
next CI run.

Refs: opensearch-project/common-utils#998
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
security#6373 (child-resource sharing) merged, so the three subordinate-
resource tests no longer need to be ignored. Enabling them surfaced two real
gaps that are now fixed:

- Alert GET inheritance: GetAlertsRequest already reports type()=monitor /
  id()=monitorId, so the security ResourceAccessEvaluator gates a by-monitor
  alerts GET as a monitor access check (a read-only share grants it, no share
  is 403 before the transport action runs). But TransportGetAlertsAction then
  executed the alert-index search under the *caller's* restored context, so a
  read-only-shared, non-owner caller (no direct perms on the system alerts
  index) got a 500. Run the search on the plugin subject instead; the
  monitor_id filter, bounded to the caller's accessible monitors, is the
  resource-sharing boundary.

- Comment create: the comment request targets the comments index (not the
  monitor) so the evaluator does not gate it, and the transport action skipped
  its own check under RSC — any caller could comment on any alert. Gate the
  create on the caller's access to the parent monitor via
  ResourceSharingClient.verifyAccess with the comment write action (granted
  only at read-write / full-access). Comment delete already restricts to the
  author/admin, so it needs no change.

Un-ignores 'test alerts inherit access when monitor is shared read-only',
'test comment on alert denied without share', and 'test comment on alert
allowed with read-write share'. Full SecureResourceSharingMonitorRestApiIT
suite: 31 passed, 0 skipped, 0 failed under -Dresource_sharing.enabled=true.

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@DarshitChanpura

Copy link
Copy Markdown
Member Author

Root-caused both signatures to the same thing: alerting CI resolves common-utils from the published 3.8 snapshot, and two commits the RSC path needs were only on main. Both are backported and merged; snapshot build 16 has them, and the security workflow is green on both legs (RSC-on and RSC-off).

Verified locally against build 16 under -Dresource_sharing.enabled=true: RscMigrateE2ERestApiIT and SecureResourceSharingMonitorRestApiIT pass (31/0/0).

Subordinate resources: with opensearch-project/security#6373 merged, I enabled the three previously-ignored tests. Two gaps fixed here:

  • Alert GETGetAlertsRequest is typed monitor/id=monitorId, so the evaluator gates it, but TransportGetAlertsAction ran the alert-index search as the caller; a read-only-shared non-owner has no direct perms on the system alerts index, so it 500'd. Now runs on the plugin subject, with the monitor_id filter (accessible monitors) as the boundary.
  • Comment create — the request targets the comments index, not the monitor, so the evaluator doesn't gate it. Now gated via ResourceSharingClient.verifyAccess(monitorId, "monitor", <comment-write-action>) (read-write/full-access only). Comment delete is already author/admin-restricted.

SdkUtils.await unwrapping noted in the PR description.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Onboard alerting plugin to Centralized Resource AuthZ framework

4 participants