Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add include_data_streams flag for authorization #58154

Merged

Conversation

danhermann
Copy link
Contributor

@danhermann danhermann commented Jun 16, 2020

Most of the work around the addition of an includeDataStreams flag was done in #58381. The remainder of this PR adds the flag to the appropriate request classes, updates IndexNameExpressionResolver to rely on the flag rather than a separate boolean flag, and updates tests.

This PR adds an includeDataStreams flag to the IndicesRequest interface so that it is available when AuthorizationEngine::loadAuthorizedIndices is called. This is necessary to avoid different behaviors when security is enabled and disabled.

The disparate behavior is described in the referenced issue. When a GET */_alias request (or any other request that does not operate on data streams) is sent without security enabled, any data streams present are ignored by the IndexNameExpressionResolver class and the correct HTTP 200 response is returned.

When security is enabled, the star in GET */_alias is first resolved to all authorized indices, aliases, and data streams. Because the _alias endpoint does not understand data streams, the first data stream it encounters among the list of authorized indices is treated as an alias and an incorrect 404 for "unknown alias" is returned.

This PR changes AuthorizationService to selectively exclude (in the case of most requests) or include (and the case of ResolveIndexAction.Request and other requests that opt in) data streams during the authorized index resolution phase.

Especially interested in feedback from @elastic/es-security.

Fixes #57712

Relates to #53100

@danhermann danhermann added >non-issue :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC v8.0.0 :Data Management/Data streams Data streams and their lifecycles v7.9.0 labels Jun 16, 2020
@elasticmachine elasticmachine added the Team:Security Meta label for security team label Jun 16, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-features (:Core/Features/Data streams)

@elasticmachine elasticmachine added the Team:Data Management Meta label for data/management team label Jun 16, 2020
@danhermann
Copy link
Contributor Author

I'll resolve the test failures. I'm still interested in feedback on the general approach.

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

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

The general approach looks good to me. A number of other requests classes
would need to implement this method as well.

I think we should also make sure that the includeDataStreams() method is used in
IndexNameExpressionResolver#concreteIndexNames(...) and IndexNameExpressionResolver#concreteIndices(...) then the overloaded method that
also accepts includeDataStreams boolean parameter can be removed.

/**
* Determines whether the action should be applied to data streams
*/
default boolean includeDataStreams() {
Copy link
Member

@martijnvg martijnvg Jun 16, 2020

Choose a reason for hiding this comment

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

I think we can move this method to IndicesRequest?

@danhermann
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/bwc

@danhermann
Copy link
Contributor Author

@elasticmachine update branch

@danhermann
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/default-distro

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

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

I left some comments.

* Determines whether the action should be applied to data streams
*/
default boolean includeDataStreams() {
return false;
Copy link
Member

Choose a reason for hiding this comment

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

I think we should change the default here, because most indices based action will be supporting data streams.

Copy link
Member

Choose a reason for hiding this comment

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

Let's keep the default to false. After all apis that need to support data stream resolution have been changed to do that, we can revisit what the default should be.

@@ -65,11 +65,6 @@
indices.create:
index: logs-foobarbaz

- do:
Copy link
Member

Choose a reason for hiding this comment

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

why is this removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll mute that portion of the test for now since that one call has different behavior when security is enabled or not. Once this PR and #57900 land, its behavior will be the same.

@@ -457,8 +457,8 @@ private void executeLocalSearch(Task task, SearchTimeProvider timeProvider, Sear
if (localIndices == null) {
return Index.EMPTY_ARRAY; //don't search on any local index (happens when only remote indices were specified)
}
return indexNameExpressionResolver.concreteIndices(clusterState, indicesOptions, true,
timeProvider.getAbsoluteStartMillis(), localIndices.indices());
return indexNameExpressionResolver.concreteIndices(clusterState, indicesOptions, localIndices,
Copy link
Member

Choose a reason for hiding this comment

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

I think we should change this resolveLocalIndices() method here. I think we should change the indicesOptions parameter to request (and pass down the request from where it is being invoked).

Then change the concreteIndices() method this method invokes. Remove the options and indexExpressions parameters and add request parameter (of type IndicesRequest). Then
in the body of this method derive the indicesOptions and indices from the request parameter.

@tvernum tvernum requested a review from albertzaharovits June 18, 2020 08:01
indicesAndAliases.add(aliasOrIndex);
if (entry.getValue().getType() != IndexAbstraction.Type.DATA_STREAM || includeDataStreams) {
indicesAndAliases.add(aliasOrIndex);
}
}
Copy link
Contributor

@albertzaharovits albertzaharovits Jun 18, 2020

Choose a reason for hiding this comment

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

I gave it more thought than it probably warrants.

Overall I am OK with the change, but I would suggest we move this whole logic( if (entry.getValue().getType() != IndexAbstraction.Type.DATA_STREAM || includeDataStreams) {) to

final ResolvedIndices.Builder resolvedIndicesBuilder = new ResolvedIndices.Builder();

This is the place where we deal with the entities (open/close indices and aliases) behind the "authorised" names, and I believe it would help us to keep complexity under control in an already messy spaghetti.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would moving the logic to IndicesAndAliasesResolver still achieve the desired result? The problem is that all requests that implement IndicesRequest.Replaceable have their requested indices replaced with the result of the loadAuthorizedIndices call and this causes problems for the requests such as GET /_alias that do not (and should not) operate on data streams.

Copy link
Contributor

Choose a reason for hiding this comment

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

What I mean is to move the whole processing on loadAuthorizedIndices, as you've proposed, over to the method in IndicesAndAliasesResolver. I think the outcome is the same, but it feels to me like a better place for these kind of processing on index names based on requests. Makes sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, thanks for the clarification. I will make that change.

Copy link
Contributor

@albertzaharovits albertzaharovits left a comment

Choose a reason for hiding this comment

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

I have left a style suggestion that I feel kinda strongly about.
If you agree to follow it, I don't believe another review round is necessary.

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

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

LGTM

@danhermann
Copy link
Contributor Author

This is likely to be included in #58381 since the two concerns are tightly related.

@danhermann danhermann force-pushed the include_ds_flag_for_authorization branch from d11c6c9 to 279f4f4 Compare July 2, 2020 18:29
@danhermann danhermann force-pushed the include_ds_flag_for_authorization branch from 9950d0a to 9125043 Compare July 3, 2020 03:00
@danhermann danhermann merged commit e592a9a into elastic:master Jul 3, 2020
danhermann added a commit to danhermann/elasticsearch that referenced this pull request Jul 3, 2020
@danhermann danhermann deleted the include_ds_flag_for_authorization branch July 3, 2020 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Data Management/Data streams Data streams and their lifecycles >non-issue :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC Team:Data Management Meta label for data/management team Team:Security Meta label for security team v7.9.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Conflicting behavior of data streams and querying for _aliases
5 participants