-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Add a new API to update RCS specific API keys #96085
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 a new API to update RCS specific API keys #96085
Conversation
public final class TransportUpdateCrossClusterApiKeyAction extends TransportBaseUpdateApiKeyAction< | ||
UpdateCrossClusterApiKeyRequest, | ||
UpdateApiKeyResponse> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is technically possible to have a bulk version of this transport action and use it for the single update REST action as well. But doing so could make auditing message look a bit weird because we differentiate beteween single and bulk update in audit events for REST API keys. So I chose to have a dedicate single update transport action and leave out bulk update transport action since we don't need it for now.
new BaseBulkUpdateApiKeyRequest(List.of(request.getId()), request.getRoleDescriptors(), request.getMetadata()) { | ||
@Override | ||
public ApiKey.Type getType() { | ||
return ApiKey.Type.CROSS_CLUSTER; | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use anonymous class here to have one less class file.
// Cross-cluster API keys can be created by an API key as long as it has manage_security | ||
final boolean createWithUser = randomBoolean(); | ||
if (createWithUser) { | ||
client().execute(CreateCrossClusterApiKeyAction.INSTANCE, request, future); | ||
} else { | ||
final CreateApiKeyResponse createAdminKeyResponse = new CreateApiKeyRequestBuilder(client()).setName("admin-key") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a randomisation here which should have been part of #95714.
Pinging @elastic/es-security (Team:Security) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went through the production code (still need to review tests) and I'm on board with the changes, except one behavior which we have to tweak:
Currently, if an API key creates a cross cluster API key, it becomes impossible to update it. The API key can't update it because we prevent this in the ApiKeyService
. The owner of the original API key can't update it either because the realm doesn't match anymore (it's set to _es_api_key
on the cross cluster key on creation).
I think the simplest way to address this is to simply skip supporting derived cross cluster API keys for now (since there wasn't a strong ask for these in the first place), but wanted to also see your thoughts. Apologies for not catching this in the review of the create API! And apologies if I'm missing something and this isn't actually an issue.
@@ -194,7 +199,8 @@ public class Constants { | |||
"cluster:admin/xpack/security/api_key/update", | |||
"cluster:admin/xpack/security/api_key/bulk_update", | |||
"cluster:admin/xpack/security/cache/clear", | |||
"cluster:admin/xpack/security/cross_cluster/api_key/create", | |||
TcpTransport.isUntrustedRemoteClusterEnabled() ? "cluster:admin/xpack/security/cross_cluster/api_key/create" : null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
...ain/java/org/elasticsearch/xpack/security/action/apikey/TransportBaseUpdateApiKeyAction.java
Show resolved
Hide resolved
...ain/java/org/elasticsearch/xpack/security/action/apikey/TransportBaseUpdateApiKeyAction.java
Show resolved
Hide resolved
} | ||
|
||
@Override | ||
void resolveUserRoleDescriptors(Authentication authentication, ActionListener<Set<RoleDescriptor>> listener) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I think we could collapse the two abstract methods into one, since they are only called together. Something like:
abstract void doExecuteUpdate(
Task task,
Request request,
Authentication authentication,
ActionListener<Response> listener
);
The fact that we are resolving role descriptors is arguably an implementation detail of the regular update actions; for cross cluster, we don't really resolve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah one abstract method looks better. I have updated accordingly e62022c
For the derived key issue, I commented on the PR of create API here #95714 (comment) I personally think it's a separate issue since it's a known bug. Other than not updatable, it otherwise works just fine. My preference would be moving forward as is and fork a separate issue to agree on API key's identity and ownership. But please let me know if you think otherwise. The other issue that I realised today is that we should have license check for both APIs. I'll have it as a separate PR to keep the size in control. |
Ah apologies, I missed this!
Since the API key does end up broken (in a surprising way), I think it would be good to either fix the bug or keep derived API keys out of scope. Totally fair to handle this outside of this PR though, and fork a separate issue 👍
Sounds good! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Sorry for the delay. Just a few smaller things and nits around tests.
final CreateCrossClusterApiKeyRequest request = CreateCrossClusterApiKeyRequest.withNameAndAccess( | ||
randomAlphaOfLengthBetween(3, 8), | ||
""" | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: there is a bunch of extra whitespace here; lets nuke it
...curity-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
Show resolved
Hide resolved
...curity-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
Show resolved
Hide resolved
...nalClusterTest/java/org/elasticsearch/xpack/security/authc/apikey/ApiKeySingleNodeTests.java
Outdated
Show resolved
Hide resolved
...nalClusterTest/java/org/elasticsearch/xpack/security/authc/apikey/ApiKeySingleNodeTests.java
Outdated
Show resolved
Hide resolved
...elasticsearch/xpack/security/action/apikey/TransportUpdateCrossClusterApiKeyActionTests.java
Outdated
Show resolved
Hide resolved
|
||
public void testUpdateHasTypeOfCrossCluster() throws Exception { | ||
final String id = randomAlphaOfLength(10); | ||
final String access = randomFrom(ACCESS_CANDIDATES); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally optional but a randomCrossClusterApiKeyAccessField()
or something like that could be a nice wrapper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add suggested method to CreateCrossClusterApiKeyRequestTests
and replace all occurences like this one with the new method.
...plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
Show resolved
Hide resolved
Co-authored-by: Nikolaj Volgushev <[email protected]>
Thanks a lot for the thorough review and nice catches! |
This PR adds REST spec files and YAML tests for the new create and update cross-cluster API key APIs. Relates: elastic#95714, elastic#96085
This PR adds API doc pages for the new create and update cross-cluster API key APIs. Relates: elastic#95714, elastic#96085
This PR adds API doc pages for the new create and update cross-cluster API key APIs. Relates: #95714, #96085 Co-authored-by: Arianna Laudazzi <[email protected]>
This PR adds a new endpoint to update RCS specific API keys. It works similarly to the existing UpdateApiKey API except:
Relates: #95714