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

Refactor request marking for serverless and operator modes #110370

Merged
merged 34 commits into from
Aug 12, 2024

Conversation

n1v0lg
Copy link
Contributor

@n1v0lg n1v0lg commented Jul 2, 2024

The internal REST parameter path_restricted was introduced to signal to APIs that a request should be subject to partial restrictions in Serverless mode.

The semantics of that parameter have since changed, subtly: in the initial iteration, only requests that corresponded to APIs with partial restrictions were marked. Since then, we have shifted to mark all requests to public APIs by non-operator users, and relying on downstream API handlers to apply partial restrictions (if they had any).

This PR replaces the parameter with two new parameters: serverless_request and operator_request. These parameters are set independently of each other:

  • serverless_request is set for all requests made in serverless mode (regardless of whether the APIs are public or internal)
  • operator_request is set for equests made by operators, both in serverless and in stateful mode

This gives REST handlers and other downstream code more flexibility in toggling behavior and decouples the concept of serverless mode from operator mode, which are technically two orthogonal things.

Relates: ES-8753

@n1v0lg n1v0lg added >refactoring :Security/Security Security issues without another label labels Jul 2, 2024
@n1v0lg n1v0lg self-assigned this Jul 2, 2024
@n1v0lg n1v0lg changed the title Rename path_restricted to restrict_for_serverless Rename path_restricted to use_serverless_partial_api_restrictions Jul 3, 2024
@n1v0lg n1v0lg marked this pull request as ready for review July 9, 2024 13:24
@n1v0lg n1v0lg requested a review from jakelandis July 9, 2024 13:25
@elasticsearchmachine elasticsearchmachine added the Team:Security Meta label for security team label Jul 9, 2024
@elasticsearchmachine
Copy link
Collaborator

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

@n1v0lg n1v0lg marked this pull request as draft July 17, 2024 09:04
@n1v0lg n1v0lg changed the title Rename path_restricted to use_serverless_partial_api_restrictions Refactor requests marking for serverless and operator modes Jul 19, 2024
@n1v0lg n1v0lg changed the title Refactor requests marking for serverless and operator modes Refactor request marking for serverless and operator modes Jul 19, 2024
@n1v0lg n1v0lg marked this pull request as ready for review July 23, 2024 19:56
Copy link
Contributor

@jakelandis jakelandis left a comment

Choose a reason for hiding this comment

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

LGTM - just some nitpicks, doc suggestion, and a non-blocking question.
thanks for this refactor, it reads much nicer.

@@ -85,8 +85,10 @@ private static String decodeQueryStringParam(final String s) {
}

private static void addParam(Map<String, String> params, String name, String value) {
if (PATH_RESTRICTED.equalsIgnoreCase(name)) {
throw new IllegalArgumentException("parameter [" + PATH_RESTRICTED + "] is reserved and may not set");
for (var reservedParameter : INTERNAL_MARKER_REQUEST_PARAMETERS) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: technically, we don't need to use case-insensitive checking (arguably we shouldn't be since http params are case intensive). If we don't case insensitive checking, the request with these paramas (say all uppercase) would still fail due to the consumed params check. I do slightly prefer the case-insenstive check since it prevents someone from accidentally mirroring these names with slightly different case. However, this code is called for every request and could save a couple clock cycles (I think) and a couple allocations (I think) if we ignored case and just did a set.contains. Micro optimization for sure, but would make for a simple micro benchmark. super nitpick, nothing wrong as-is, so feel free to ignore this comment.

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 agree with the potential optimization but would prefer to keep this refactor "focused" -- moving away from equalsIgnoreCase is a functional change so I'd rather follow up with a separate PR

ALWAYS_SUPPORTED,
// these internal parameters cannot be set by end-users, but are used by Elasticsearch internally.
// they must be accepted by all handlers
RestRequest.INTERNAL_MARKER_REQUEST_PARAMETERS,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this necessary because we are marking the request earlier in the process ?

Copy link
Contributor Author

@n1v0lg n1v0lg Jul 26, 2024

Choose a reason for hiding this comment

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

we need this because we now set the parameter for actions for which we did not set it before (we didn't set the parameter for internal actions previously, now we do). A couple of these actions (e.g., RestDeleteSnapshotAction) override allSupportedParameters which in turn means that we run a check against all request parameters and reject "unsupported" ones. The default (for virtually all other actions) is to return null which means no check, so we simply didn't exercise this code path before.

@n1v0lg n1v0lg merged commit b7b1872 into elastic:main Aug 12, 2024
20 checks passed
@n1v0lg n1v0lg deleted the rename-path-restricted branch August 12, 2024 11:27
mark-vieira added a commit to mark-vieira/elasticsearch that referenced this pull request Aug 12, 2024
cbuescher pushed a commit to cbuescher/elasticsearch that referenced this pull request Sep 4, 2024
…10370)

The internal REST parameter `path_restricted` was introduced to signal to APIs that a request should be subject to partial restrictions in Serverless mode. 

The semantics of that parameter have since changed, subtly: in the initial iteration, only requests that corresponded to APIs with partial restrictions were marked. Since then, we have shifted to mark _all_ requests to public APIs by non-operator users, and relying on downstream API handlers to apply partial restrictions (if they had any). 

This PR replaces the parameter with two new parameters: `serverless_request` and `operator_request`. These parameters are set independently of each other: 

*  `serverless_request` is set for all requests made in serverless mode (regardless of whether the APIs are public or internal)
* `operator_request` is set for equests made by operators, both in serverless and in stateful mode

This gives REST handlers and other downstream code more flexibility in toggling behavior and decouples the concept of serverless mode from operator mode, which are technically two orthogonal things. 

Relates: ES-8753
davidkyle pushed a commit to davidkyle/elasticsearch that referenced this pull request Sep 5, 2024
…10370)

The internal REST parameter `path_restricted` was introduced to signal to APIs that a request should be subject to partial restrictions in Serverless mode. 

The semantics of that parameter have since changed, subtly: in the initial iteration, only requests that corresponded to APIs with partial restrictions were marked. Since then, we have shifted to mark _all_ requests to public APIs by non-operator users, and relying on downstream API handlers to apply partial restrictions (if they had any). 

This PR replaces the parameter with two new parameters: `serverless_request` and `operator_request`. These parameters are set independently of each other: 

*  `serverless_request` is set for all requests made in serverless mode (regardless of whether the APIs are public or internal)
* `operator_request` is set for equests made by operators, both in serverless and in stateful mode

This gives REST handlers and other downstream code more flexibility in toggling behavior and decouples the concept of serverless mode from operator mode, which are technically two orthogonal things. 

Relates: ES-8753
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>refactoring :Security/Security Security issues without another label Team:Security Meta label for security team v8.16.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants