-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Respect runas realm for ApiKey security operations #52178
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
Changes from 4 commits
9712caf
3899fcc
e264109
455a6d6
f966f4d
f3cd6ff
584343a
df9cf5d
b7bdd03
57b5b06
b1bce89
a05fdeb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -104,7 +104,9 @@ public String configRoles() { | |
| "manage_api_key_role:\n" + | ||
| " cluster: [\"manage_api_key\"]\n" + | ||
| "manage_own_api_key_role:\n" + | ||
| " cluster: [\"manage_own_api_key\"]\n"; | ||
| " cluster: [\"manage_own_api_key\"]\n" + | ||
| "run_as_role:\n" + | ||
| " run_as: [\"user_with_manage_own_api_key_role\"]\n"; | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -114,15 +116,17 @@ public String configUsers() { | |
| return super.configUsers() + | ||
| "user_with_no_api_key_role:" + usersPasswdHashed + "\n" + | ||
| "user_with_manage_api_key_role:" + usersPasswdHashed + "\n" + | ||
| "user_with_manage_own_api_key_role:" + usersPasswdHashed + "\n"; | ||
| "user_with_manage_own_api_key_role:" + usersPasswdHashed + "\n" + | ||
| "user_with_run_as_role:" + usersPasswdHashed + "\n"; | ||
| } | ||
|
|
||
| @Override | ||
| public String configUsersRoles() { | ||
| return super.configUsersRoles() + | ||
| "no_api_key_role:user_with_no_api_key_role\n" + | ||
| "manage_api_key_role:user_with_manage_api_key_role\n" + | ||
| "manage_own_api_key_role:user_with_manage_own_api_key_role\n"; | ||
| "manage_own_api_key_role:user_with_manage_own_api_key_role\n" + | ||
| "run_as_role:user_with_run_as_role\n"; | ||
| } | ||
|
|
||
| private void awaitApiKeysRemoverCompletion() throws Exception { | ||
|
|
@@ -540,6 +544,25 @@ public void testGetApiKeysOwnedByCurrentAuthenticatedUser() throws InterruptedEx | |
| response, userWithManageApiKeyRoleApiKeys.stream().map(o -> o.getId()).collect(Collectors.toSet()), null); | ||
| } | ||
|
|
||
| public void testGetApiKeysOwnedByRunAsUser() throws ExecutionException, InterruptedException { | ||
| int noOfSuperuserApiKeys = randomIntBetween(3, 5); | ||
| int noOfApiKeysForUserWithManageApiKeyRole = randomIntBetween(3, 5); | ||
| createApiKeys(noOfSuperuserApiKeys, null); | ||
ywangd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| final String userWithManageOwnApiKeyRole = "user_with_manage_own_api_key_role"; | ||
| final String userWithRunAsRole = "user_with_run_as_role"; | ||
| List<CreateApiKeyResponse> userWithManageOwnApiKeyRoleApiKeys = createApiKeys(userWithManageOwnApiKeyRole, | ||
| userWithRunAsRole, noOfApiKeysForUserWithManageApiKeyRole, null, "monitor"); | ||
| final Client client = client().filterWithHeader(Map.of("Authorization", UsernamePasswordToken | ||
| .basicAuthHeaderValue(userWithRunAsRole, SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING), | ||
| "es-security-runas-user", userWithManageOwnApiKeyRole)); | ||
|
|
||
| PlainActionFuture<GetApiKeyResponse> listener = new PlainActionFuture<>(); | ||
| client.execute(GetApiKeyAction.INSTANCE, GetApiKeyRequest.forOwnedApiKeys(), listener); | ||
|
||
| GetApiKeyResponse response = listener.get(); | ||
| verifyGetResponse(userWithManageOwnApiKeyRole, noOfApiKeysForUserWithManageApiKeyRole, userWithManageOwnApiKeyRoleApiKeys, | ||
| response, userWithManageOwnApiKeyRoleApiKeys.stream().map(o -> o.getId()).collect(Collectors.toSet()), null); | ||
| } | ||
|
|
||
| public void testGetAllApiKeys() throws InterruptedException, ExecutionException { | ||
| int noOfSuperuserApiKeys = randomIntBetween(3, 5); | ||
| int noOfApiKeysForUserWithManageApiKeyRole = randomIntBetween(3, 5); | ||
|
|
@@ -600,6 +623,25 @@ public void testInvalidateApiKeysOwnedByCurrentAuthenticatedUser() throws Interr | |
| verifyInvalidateResponse(noOfApiKeysForUserWithManageApiKeyRole, userWithManageApiKeyRoleApiKeys, invalidateResponse); | ||
| } | ||
|
|
||
| public void testInvalidateApiKeysOwnedByRunAsUser() throws InterruptedException, ExecutionException { | ||
| int noOfSuperuserApiKeys = randomIntBetween(3, 5); | ||
| int noOfApiKeysForUserWithManageApiKeyRole = randomIntBetween(3, 5); | ||
| createApiKeys(noOfSuperuserApiKeys, null); | ||
| final String userWithManageOwnApiKeyRole = "user_with_manage_own_api_key_role"; | ||
| final String userWithRunAsRole = "user_with_run_as_role"; | ||
| List<CreateApiKeyResponse> userWithManageApiKeyRoleApiKeys = createApiKeys(userWithManageOwnApiKeyRole, | ||
| userWithRunAsRole, noOfApiKeysForUserWithManageApiKeyRole, null, "monitor"); | ||
| final Client client = client().filterWithHeader(Map.of("Authorization", UsernamePasswordToken | ||
| .basicAuthHeaderValue(userWithRunAsRole, SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING), | ||
| "es-security-runas-user", userWithManageOwnApiKeyRole)); | ||
|
|
||
| PlainActionFuture<InvalidateApiKeyResponse> listener = new PlainActionFuture<>(); | ||
| client.execute(InvalidateApiKeyAction.INSTANCE, InvalidateApiKeyRequest.forOwnedApiKeys(), listener); | ||
|
||
| InvalidateApiKeyResponse invalidateResponse = listener.get(); | ||
|
|
||
| verifyInvalidateResponse(noOfApiKeysForUserWithManageApiKeyRole, userWithManageApiKeyRoleApiKeys, invalidateResponse); | ||
| } | ||
|
|
||
| public void testApiKeyAuthorizationApiKeyMustBeAbleToRetrieveItsOwnInformationButNotAnyOtherKeysCreatedBySameOwner() | ||
| throws InterruptedException, ExecutionException { | ||
| List<CreateApiKeyResponse> responses = createApiKeys(SecuritySettingsSource.TEST_SUPERUSER,2, null, (String[]) null); | ||
|
|
@@ -699,14 +741,28 @@ private List<CreateApiKeyResponse> createApiKeys(int noOfApiKeys, TimeValue expi | |
| } | ||
|
|
||
| private List<CreateApiKeyResponse> createApiKeys(String user, int noOfApiKeys, TimeValue expiration, String... clusterPrivileges) { | ||
| final Map<String, String> headers = Collections.singletonMap( | ||
| "Authorization", UsernamePasswordToken.basicAuthHeaderValue(user, SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING)); | ||
| return createApiKeys(headers, noOfApiKeys, expiration, clusterPrivileges); | ||
| } | ||
|
|
||
| private List<CreateApiKeyResponse> createApiKeys(String user, String runAsUser, | ||
| int noOfApiKeys, TimeValue expiration, String... clusterPrivileges) { | ||
| final Map<String, String> headers = Map.of("Authorization", | ||
| UsernamePasswordToken.basicAuthHeaderValue(runAsUser, SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING), | ||
| "es-security-runas-user", user); | ||
|
||
| return createApiKeys(headers, noOfApiKeys, expiration, clusterPrivileges); | ||
| } | ||
|
|
||
| private List<CreateApiKeyResponse> createApiKeys(Map<String, String> headers, | ||
| int noOfApiKeys, TimeValue expiration, String... clusterPrivileges) { | ||
| List<CreateApiKeyResponse> responses = new ArrayList<>(); | ||
| for (int i = 0; i < noOfApiKeys; i++) { | ||
| final RoleDescriptor descriptor = new RoleDescriptor("role", clusterPrivileges, null, null); | ||
| Client client = client().filterWithHeader(Collections.singletonMap("Authorization", UsernamePasswordToken | ||
| .basicAuthHeaderValue(user, SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING))); | ||
| Client client = client().filterWithHeader(headers); | ||
| final CreateApiKeyResponse response = new CreateApiKeyRequestBuilder(client) | ||
| .setName("test-key-" + randomAlphaOfLengthBetween(5, 9) + i).setExpiration(expiration) | ||
| .setRoleDescriptors(Collections.singletonList(descriptor)).get(); | ||
| .setName("test-key-" + randomAlphaOfLengthBetween(5, 9) + i).setExpiration(expiration) | ||
| .setRoleDescriptors(Collections.singletonList(descriptor)).get(); | ||
| assertNotNull(response.getId()); | ||
| assertNotNull(response.getKey()); | ||
| responses.add(response); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.