Skip to content

Conversation

@afharo
Copy link
Member

@afharo afharo commented Dec 2, 2025

Summary

We identified some scenarios where clients authorized to a partial list of SO types would circumvent the Saved Objects Repository's allowed types (it could list "hidden" SO types).

This PR addresses this issue by unifying the flow for partially and fully authorized clients, and applying the intersection of the allowed and authorized lists.

Checklist

  • Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support
  • Documentation was added for features that require explanation or tutorials
  • Unit or functional tests were updated or added to match the most common scenarios
  • If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the docker list
  • This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The release_note:breaking label should be applied in these situations.
  • Flaky Test Runner was used on any tests changed
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines
  • Review the backport guidelines and apply applicable backport:* labels.

Identify risks

  • Some APIs might have been abusing this bug. We need to validate through CI that they work as intended, and send an internal note to all Kibana contributors to raise awareness of potential failures.

@afharo afharo self-assigned this Dec 2, 2025
@afharo afharo added bug Fixes for quality problems that affect the customer experience Team:Core Platform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t// release_note:fix Team:Security Platform Security: Auth, Users, Roles, Spaces, Audit Logging, etc t// backport:all-open Backport to all branches that could still receive a release labels Dec 2, 2025
@afharo afharo force-pushed the saved-objects-repository/intersect-allowed-and-authorized-types branch from 60c94ce to 3a28421 Compare December 3, 2025 14:17
@elasticmachine
Copy link
Contributor

⏳ Build in-progress, with failures

Failed CI Steps

Test Failures

  • [job] [logs] Jest Tests #14 / #deleteByNamespace performDeleteByNamespace search dsl constructs a query using all multi-namespace types, and another using all single-namespace types
  • [job] [logs] Jest Tests #14 / #deleteByNamespace performDeleteByNamespace search dsl constructs a query using all multi-namespace types, and another using all single-namespace types

History

cc @afharo

}
if (authorizationResult?.status === 'partially_authorized') {
if (
authorizationResult?.status === 'fully_authorized' ||
Copy link
Member Author

@afharo afharo Dec 3, 2025

Choose a reason for hiding this comment

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

This only ensures the same path is followed for both authorization levels, although, functionally, it achieves the same result if we don't add this clause in the if.

Happy to remove this line if we think that performance might be a problem.

I'd appreciate @azasypkin's thoughts on this.

Comment on lines +180 to +181
// Discard the types that the SO repository doesn't know about (typically hidden objects).
if (!allowedTypes.includes(objType)) continue;
Copy link
Member Author

Choose a reason for hiding this comment

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

Mixing the user's authorization and the client's scope here (which can be odd).

However, typeToNamespacesMap doesn't really imply that it's bound to only one.

{
type: [
type,
'foo',
Copy link
Member Author

Choose a reason for hiding this comment

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

I had to add foo to the requested type so that it is kept in the auth map.

expect(arrayMapsAreEqual(actualMap, expectedMap)).toBeTruthy();
});

test(`uses the authorization map when fully authorized`, async () => {
Copy link
Member Author

Choose a reason for hiding this comment

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

just repeating the test above, but for fully authorized.

Comment on lines +119 to +120
// Make sure to search through all the hidden types as well.
includedHiddenTypes: types.filter((t) => t.hidden).map((t) => t.name),
Copy link
Member Author

Choose a reason for hiding this comment

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

I assume that we want to search references to the Data View across all types. Is my assumption correct?

@afharo afharo marked this pull request as ready for review December 4, 2025 00:08
@afharo afharo requested review from a team as code owners December 4, 2025 00:08
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-security (Team:Security)

@afharo afharo requested a review from a team December 4, 2025 00:09
@afharo afharo added the Team:DataDiscovery Discover, search (data plugin and KQL), data views, saved searches. For ES|QL, use Team:ES|QL. t// label Dec 4, 2025
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-data-discovery (Team:DataDiscovery)

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

Labels

backport:all-open Backport to all branches that could still receive a release bug Fixes for quality problems that affect the customer experience release_note:fix Team:Core Platform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t// Team:DataDiscovery Discover, search (data plugin and KQL), data views, saved searches. For ES|QL, use Team:ES|QL. t// Team:Security Platform Security: Auth, Users, Roles, Spaces, Audit Logging, etc t//

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants