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 support for the simple_query_string to the Query API Key API #104132

Conversation

albertzaharovits
Copy link
Contributor

@albertzaharovits albertzaharovits commented Jan 9, 2024

This adds support for the simple_query_string query type to the Query API key Information API.
In addition, this also adds support for querying all the API Key metadata fields simultaneously,
rather than requiring each to be specified, such as metadata.x, metadata.y, etc.

Relates: #101691

@albertzaharovits albertzaharovits force-pushed the query-string-support-for-api-key-querying branch from 347cdd7 to 4c62314 Compare January 10, 2024 11:22
@albertzaharovits albertzaharovits changed the title Simple query string Add support for the simple_query_string to the Query API Key API Jan 12, 2024
@albertzaharovits albertzaharovits added >enhancement :Security/Security Security issues without another label labels Jan 12, 2024
@elasticsearchmachine
Copy link
Collaborator

Hi @albertzaharovits, I've created a changelog YAML for you.

@albertzaharovits albertzaharovits marked this pull request as ready for review January 12, 2024 14:16
@elasticsearchmachine
Copy link
Collaborator

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

@elasticsearchmachine elasticsearchmachine added the Team:Security Meta label for security team label Jan 12, 2024
@n1v0lg n1v0lg requested a review from jfreden January 12, 2024 15:36
Copy link
Contributor

@jfreden jfreden left a comment

Choose a reason for hiding this comment

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

Great job on this! I think it looks great! Just have some minor comments/questions.

At a high level, as someone who has not seen this before, I had a hard time wrapping my head around why we don't allow simple match query on the metadata level. If I use your IT test data as an example, why should this return data:

{"query": {"simple_query_string": {"query": "prod 42 true", "fields": ["meta*"]}}}

but not:

{"query": {"simple_query_string": {"query": "prod 42 true", "fields": ["metadata.val*"]}}}

}
}
if (simpleQueryStringBuilder.fields().isEmpty()) {
simpleQueryStringBuilder.field("match_nothing_place_holder_field_name_wildcard*");
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 for testing purposes only?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it's not for test only.
I forgot to comment in the code...
If we let the SimpleQueryStringBuilder#fields() be empty here, it's eventually going to be interpreted as *

List<String> defaultFields = context.defaultFields();
This means it's going to search on the other fields in the .security index, including the disallowed ones. This conspicuous pattern (a non-pattern should work too for this query type) is put in here in order to avoid this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah yes, because the default is *, that makes sense. Thanks for clarifying!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pushed b73a13d to add a comment explaining it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nifty! I'm wondering if we can be more explicit by returning a MatchNoneQueryBuilder here instead (it also avoids "pointless" match work on a field we know doesn't exist).

(Note: I may be overlooking something here!)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point! I'll try it, I think it should work! Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pushed 0a7b76e , I think it will pass the tests.

}
}
if (indexFieldNames.isEmpty() && Regex.isSimpleMatchPattern(fieldNameOrPattern) == false) {
throw new IllegalArgumentException("Field [" + fieldNameOrPattern + "] is not allowed for API Key query");
Copy link
Contributor

@jfreden jfreden Jan 15, 2024

Choose a reason for hiding this comment

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

Should this result in an error or just be ignored? Based on this it looks like it shouldn't even be checked for correct syntax.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmmm, now that you're mentioning it....
I verified that the simple_query_string for the regular _search endpoints just ignores unrecognized fields (if querying on a unrecognized field, no matches are returned) - and there's no parameter to change this behavior.
So, I believe that you're right that it would probably be more appropriate to also ignore unrecognized fields for simple_query_strings for the /_security/_query/api_key endpoint, even if all the other allowed query types complain about it.
@n1v0lg Do you have preference here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pushed f542fc5 to make the SimpleQueryString preprocessing ignore unknown field names, analogously to the the core's processing of the same query type.
The result of it is that a simple query string issued to the POST /_security/_query/api_key endpoint behaves identical to when issued to the regular _search endpoints (ignores unknown fields).
@n1v0lg If you're leaning towards the less lenient, original implementation, please pitch in, I can easily revert it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for the delay! I'm ++ on the consistent behavior with regular _search. I'll review the rest of the PR shortly.

// moreover, it's not possible to iterate the concrete fields matching the prefix
if (Regex.isSimpleMatchPattern(fieldNamePrefix)) {
// this means `metadata.*` and `metadata.x*` are expanded to the empty list
// rather than be replaced with `metadata_flattened.*` and `metadata_flattened.x*`
Copy link
Contributor

Choose a reason for hiding this comment

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

I found this a little confusing. Sorry if my question doesn't make sense!

So, this means that we don't support wildcards for metadata attribute field selection, right? It has to be the exact name of the attribute to match? So we can't have metadata.something_a and metadata.something_b and select them for search with "fields": ["metadata.something*"]. Is it possible to document that part, so the part where the result of this return false is that we can't match on a simple match pattern when selecting metadata attributes, it's either all attributes or a list of specific attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's indeed confusing. I'll jot something in the docs to explain it.

So, this means that we don't support wildcards for metadata attribute field selection, right?

That's exactly right!

The root limitation actually comes from the way the flattened field type works (the API key metadata_flattened field is mapped as such).
As you say, it's not possible to access a subset of the metadata_flattened.* fields via wildcards. It's either all of them, via metadata_flattened, or specific (non-wildcard) ones in a list.

Because the limitation comes from the Simple Query String processing, we could drop the processing here, i.e. which prohibits the metadata.x* -> metadata_flattened.x* translation, and it would still work identically (because metadata_flattened.x* is going to be implicitly ignored). But I think it's clearer to keep it (and test for it).


Interestingly, if the sub-field is a wildcard, e.g. metadata_flattened.wild* exists as a field, then this field cannot be accessed in the field parameter of the simple_query_string.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pushed 18e9993 to explain the above in the docs proper.

@albertzaharovits albertzaharovits removed the :Security/Security Security issues without another label label Jan 16, 2024
@elasticsearchmachine elasticsearchmachine added needs:triage Requires assignment of a team area label and removed Team:Security Meta label for security team labels Jan 16, 2024
@albertzaharovits albertzaharovits added :Security/Authentication Logging in, Usernames/passwords, Realms (Native/LDAP/AD/SAML/PKI/etc) and removed needs:triage Requires assignment of a team area label labels Jan 16, 2024
@elasticsearchmachine elasticsearchmachine added the Team:Security Meta label for security team label Jan 16, 2024
@albertzaharovits
Copy link
Contributor Author

@elasticsearchmachine run elasticsearch-ci/part-4-fips

@albertzaharovits
Copy link
Contributor Author

@elasticsearchmachine run elasticsearch-ci/part-2-fips

@albertzaharovits
Copy link
Contributor Author

@elasticsearchmachine run elasticsearch-ci/part-2-fips

2 similar comments
@albertzaharovits
Copy link
Contributor Author

@elasticsearchmachine run elasticsearch-ci/part-2-fips

@albertzaharovits
Copy link
Contributor Author

@elasticsearchmachine run elasticsearch-ci/part-2-fips

@albertzaharovits
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/part-2-fips

1 similar comment
@albertzaharovits
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/part-2-fips

@albertzaharovits albertzaharovits merged commit aeb2b77 into elastic:main Jan 19, 2024
19 checks passed
@albertzaharovits albertzaharovits deleted the query-string-support-for-api-key-querying branch January 19, 2024 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>enhancement :Security/Authentication Logging in, Usernames/passwords, Realms (Native/LDAP/AD/SAML/PKI/etc) Team:Security Meta label for security team v8.13.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants