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

Support updates of API key attributes [REST and transport layer] #88186

Merged
merged 192 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from 161 commits
Commits
Show all changes
192 commits
Select commit Hold shift + click to select a range
3bba543
Service and request draft
n1v0lg Jun 21, 2022
3a709a9
Update response
n1v0lg Jun 21, 2022
fc53cf3
Get api key docs for name
n1v0lg Jun 21, 2022
74d264c
More
n1v0lg Jun 21, 2022
0bc2ec5
More
n1v0lg Jun 21, 2022
648ae52
Check expiration
n1v0lg Jun 21, 2022
2d43dda
Integ test
n1v0lg Jun 21, 2022
4384e56
More
n1v0lg Jun 21, 2022
3d73b99
Assert role descriptors as expected
n1v0lg Jun 21, 2022
ff54fec
Clean up role descriptor checks
n1v0lg Jun 21, 2022
e484923
Test not found
n1v0lg Jun 21, 2022
a9c8caa
WIP expected metadata
n1v0lg Jun 21, 2022
d638a45
Fix metadata
n1v0lg Jun 21, 2022
0c819e4
Nit
n1v0lg Jun 21, 2022
abe677b
Fix setting metadata
n1v0lg Jun 21, 2022
3c7b2c1
Nit
n1v0lg Jun 21, 2022
29f0320
WIP use old role descriptors
n1v0lg Jun 21, 2022
eef2b38
Clean up
n1v0lg Jun 21, 2022
e5b8650
More todos
n1v0lg Jun 21, 2022
30cfc39
One more
n1v0lg Jun 21, 2022
b14271a
Other users API key not found
n1v0lg Jun 21, 2022
cd5d58f
Nit
n1v0lg Jun 21, 2022
eeca38a
Tweaks
n1v0lg Jun 21, 2022
7c3d3f0
Null bytes
n1v0lg Jun 21, 2022
f6d1783
Other
n1v0lg Jun 21, 2022
0e44586
Not found test clean up
n1v0lg Jun 22, 2022
3c83743
Tweaks
n1v0lg Jun 22, 2022
b88cdc8
Inactive tests
n1v0lg Jun 22, 2022
68eaa91
Expiration test
n1v0lg Jun 22, 2022
36bb431
Friendlier exception message
n1v0lg Jun 22, 2022
c545e20
Translate response
n1v0lg Jun 22, 2022
63c0729
Noop not possible
n1v0lg Jun 22, 2022
7aefeb1
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 22, 2022
89d7229
Much clean up
n1v0lg Jun 22, 2022
003f969
Test validate
n1v0lg Jun 22, 2022
8937d94
Spotless
n1v0lg Jun 22, 2022
bdd4dfb
Also test empty name
n1v0lg Jun 22, 2022
4bd5cad
More clean up
n1v0lg Jun 22, 2022
d88f949
Skip todo
n1v0lg Jun 22, 2022
421e04f
Remove unused
n1v0lg Jun 22, 2022
719e4ba
Update request tests and serialization
n1v0lg Jun 22, 2022
c536534
Lint
n1v0lg Jun 22, 2022
c46ab34
Clean up
n1v0lg Jun 22, 2022
de179dd
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 22, 2022
7931e00
Nits
n1v0lg Jun 22, 2022
3f8b218
Checkstyle
n1v0lg Jun 22, 2022
7166217
Fix
n1v0lg Jun 22, 2022
0f48e8c
Owner realms
n1v0lg Jun 22, 2022
ae573ca
Checkstyle
n1v0lg Jun 22, 2022
629e5a1
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 23, 2022
d29c1e2
Use raw field
n1v0lg Jun 23, 2022
147adb0
Clean up new and merged doc
n1v0lg Jun 23, 2022
8cffe22
With versioning
n1v0lg Jun 23, 2022
0cac5e5
Clean up
n1v0lg Jun 23, 2022
7d9956e
Invalidate doc cache
n1v0lg Jun 23, 2022
f5d089f
More clean up
n1v0lg Jun 23, 2022
0b34c7b
Test cache
n1v0lg Jun 23, 2022
65c8d46
Assert auth cache not cleared
n1v0lg Jun 23, 2022
2e3b623
Null tweaks
n1v0lg Jun 23, 2022
2f91430
Null input stream
n1v0lg Jun 23, 2022
73d3fac
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 24, 2022
ef49292
Updated doc test
n1v0lg Jun 24, 2022
3f099c4
Lint
n1v0lg Jun 24, 2022
9426e56
More lint
n1v0lg Jun 24, 2022
325d4d0
More clean up
n1v0lg Jun 24, 2022
044831f
Put in version stop gap
n1v0lg Jun 24, 2022
1d3d8a2
Combine tests
n1v0lg Jun 24, 2022
e377155
Include domain
n1v0lg Jun 24, 2022
e95fd34
Use param message
n1v0lg Jun 24, 2022
c536811
Bump version
n1v0lg Jun 24, 2022
b7b4c36
Check get api correct metadata
n1v0lg Jun 24, 2022
30b0267
Rename
n1v0lg Jun 24, 2022
17375b3
Still the logging
n1v0lg Jun 24, 2022
0481c01
Imports
n1v0lg Jun 24, 2022
1a29f8b
Test creator
n1v0lg Jun 24, 2022
6d7a341
Add creator assertions
n1v0lg Jun 24, 2022
99d5d06
Randomize expiration
n1v0lg Jun 24, 2022
6d7013c
Fix assertion
n1v0lg Jun 24, 2022
64990b5
WIP tests multiple role descriptors
n1v0lg Jun 24, 2022
bba8f2b
More clean up
n1v0lg Jun 24, 2022
dd69a00
Support multiple roles
n1v0lg Jun 24, 2022
3aefef8
Domain check and test clean up
n1v0lg Jun 24, 2022
49b4dd5
Better names
n1v0lg Jun 26, 2022
4a0b2b2
WIP address feedback
n1v0lg Jun 27, 2022
2bd3ea4
Scroll helper
n1v0lg Jun 27, 2022
0473c5d
Add assertion
n1v0lg Jun 27, 2022
6c33703
api key error message
n1v0lg Jun 27, 2022
d7bd723
More inline
n1v0lg Jun 27, 2022
9418b9b
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 27, 2022
0b2457d
Single and fix test
n1v0lg Jun 27, 2022
3f283d9
Better error message
n1v0lg Jun 27, 2022
0d02eba
Nit
n1v0lg Jun 27, 2022
82fdb6b
Api keys not allowed
n1v0lg Jun 27, 2022
7a371a4
Move assertion up
n1v0lg Jun 27, 2022
4586139
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 27, 2022
910500b
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 27, 2022
a9dd29f
WIP actions
n1v0lg Jun 27, 2022
41d3f03
Manage own api key priv
n1v0lg Jun 27, 2022
d26f459
WIP
n1v0lg Jun 27, 2022
a9d005f
Error message
n1v0lg Jun 27, 2022
49eba62
Nit
n1v0lg Jun 27, 2022
3fdb5ff
Simplify
n1v0lg Jun 27, 2022
df2b6a3
Role descs
n1v0lg Jun 27, 2022
58019b4
More tweaks
n1v0lg Jun 27, 2022
58a7e02
Assert
n1v0lg Jun 27, 2022
3946dc1
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 28, 2022
a896ae0
Address feedback
n1v0lg Jun 28, 2022
542b360
More logs and finals
n1v0lg Jun 28, 2022
7c36b17
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 28, 2022
b9fcad1
More randomization in test
n1v0lg Jun 28, 2022
2b45045
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 28, 2022
87b6fb0
Caps API key
n1v0lg Jun 28, 2022
725248d
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 28, 2022
7481d52
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 28, 2022
160cac3
Merge branch 'update-api-keys-service-level' into update-api-keys-res…
n1v0lg Jun 28, 2022
59b9093
WIP
n1v0lg Jun 28, 2022
ca65709
Address review
n1v0lg Jun 28, 2022
e025390
Merge branch 'master' into update-api-keys-service-level
n1v0lg Jun 28, 2022
8ed5724
Merge branch 'update-api-keys-service-level' into update-api-keys-res…
n1v0lg Jun 28, 2022
8a1a88b
Hard-won rest test
n1v0lg Jun 28, 2022
782f6ec
Nits
n1v0lg Jun 28, 2022
60a0755
Plug in client
n1v0lg Jun 28, 2022
d8fc643
Merge
n1v0lg Jun 29, 2022
7e2e786
WIP
n1v0lg Jun 29, 2022
44f16ab
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jun 29, 2022
4ff33aa
Native realm user
n1v0lg Jun 29, 2022
5489f53
Api key test
n1v0lg Jun 29, 2022
41b573f
REST test
n1v0lg Jun 29, 2022
665c426
Expect metadata rest test
n1v0lg Jun 29, 2022
84b22f6
Nit
n1v0lg Jun 29, 2022
a04792b
Manage own api key test
n1v0lg Jun 29, 2022
7f5240a
Tweak method
n1v0lg Jun 29, 2022
74b9e79
More tweaks
n1v0lg Jun 29, 2022
6a89230
Simplify
n1v0lg Jun 29, 2022
ab9b0d8
Only post
n1v0lg Jun 29, 2022
673de56
Clean up
n1v0lg Jun 29, 2022
9ada903
Use stream utils
n1v0lg Jun 29, 2022
dc1db79
Undo
n1v0lg Jun 29, 2022
e8d7bb8
Undo more
n1v0lg Jun 29, 2022
a354673
Nit
n1v0lg Jun 29, 2022
96e4864
Import
n1v0lg Jun 29, 2022
85ee9de
Add to non-operator constants
n1v0lg Jun 29, 2022
d538118
Clean up
n1v0lg Jun 29, 2022
77021e4
Few more tweaks
n1v0lg Jun 29, 2022
222d475
Nit
n1v0lg Jun 29, 2022
7654f75
Address early feedback
n1v0lg Jun 30, 2022
1ead5ea
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jun 30, 2022
5aab296
Fix tests
n1v0lg Jun 30, 2022
0f17546
Better error message
n1v0lg Jun 30, 2022
b3aaf2e
WIP rest tests
n1v0lg Jun 30, 2022
9e7ce5e
Also test bearer token auth
n1v0lg Jun 30, 2022
085cc4f
Grant target can update api key test
n1v0lg Jun 30, 2022
dde0b72
Refactor
n1v0lg Jun 30, 2022
f90b93e
Randomize auth method
n1v0lg Jun 30, 2022
5e7a5bd
Use header constant
n1v0lg Jun 30, 2022
4be5dee
Randomize cluster privs
n1v0lg Jun 30, 2022
7b137d2
Plug in more client
n1v0lg Jun 30, 2022
5070e48
Import
n1v0lg Jun 30, 2022
bad21a0
Random realm id
n1v0lg Jun 30, 2022
cb67b3e
Get random node
n1v0lg Jun 30, 2022
046a22d
Nit
n1v0lg Jun 30, 2022
a2f5f38
Add back comment
n1v0lg Jun 30, 2022
4f66060
Auto sync user roles test
n1v0lg Jun 30, 2022
46bc5f2
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jul 4, 2022
57938c5
Clean up test
n1v0lg Jul 4, 2022
6a2deb1
Test grantor cannot update
n1v0lg Jul 4, 2022
a838648
Include ID in assertion
n1v0lg Jul 4, 2022
2d6d9d0
Update docs/changelog/88186.yaml
n1v0lg Jul 4, 2022
3e3e5e0
Changelog
n1v0lg Jul 4, 2022
05571e2
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jul 4, 2022
57b7e67
Validator tests
n1v0lg Jul 4, 2022
0fc25b9
Priv test
n1v0lg Jul 4, 2022
75e2e0e
Clean up tests
n1v0lg Jul 4, 2022
ea8d79e
Randomize more but not too much
n1v0lg Jul 4, 2022
bedd5b0
Imports
n1v0lg Jul 4, 2022
96e681a
Randomize cluster privs in auto update test
n1v0lg Jul 4, 2022
8ce5651
Update docs/changelog/88186.yaml
n1v0lg Jul 4, 2022
cfe84c8
Clear cache param
n1v0lg Jul 4, 2022
eb6cdad
Merge branch 'update-api-keys-rest-transport-layers' of github.com:n1…
n1v0lg Jul 4, 2022
17e449f
Changelog
n1v0lg Jul 4, 2022
23f8572
Use ids to avoid cascading failure
n1v0lg Jul 4, 2022
3673f0f
Exclude invalid role descriptors
n1v0lg Jul 4, 2022
e5e16d0
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jul 5, 2022
16a6233
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jul 5, 2022
398a0fa
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jul 6, 2022
66a38d8
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jul 6, 2022
209905c
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jul 6, 2022
37657f5
Merge branch 'master' into update-api-keys-rest-transport-layers
n1v0lg Jul 7, 2022
284f565
Address comments
n1v0lg Jul 7, 2022
5d64607
Allow empty request body
n1v0lg Jul 7, 2022
fa8a055
Ownership comment
n1v0lg Jul 7, 2022
c048e15
Update docs/changelog/88186.yaml
n1v0lg Jul 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.core.security.action.apikey;

import org.elasticsearch.action.ActionType;

public final class UpdateApiKeyAction extends ActionType<UpdateApiKeyResponse> {

public static final String NAME = "cluster:admin/xpack/security/api_key/update";
public static final UpdateApiKeyAction INSTANCE = new UpdateApiKeyAction();

private UpdateApiKeyAction() {
super(NAME, UpdateApiKeyResponse::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public UpdateApiKeyRequest(String id, @Nullable List<RoleDescriptor> roleDescrip
public UpdateApiKeyRequest(StreamInput in) throws IOException {
super(in);
this.id = in.readString();
this.roleDescriptors = readOptionalList(in);
this.roleDescriptors = in.readOptionalList(RoleDescriptor::new);
this.metadata = in.readMap();
}

Expand All @@ -65,21 +65,12 @@ public ActionRequestValidationException validate() {
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeString(id);
writeOptionalList(out);
out.writeOptionalCollection(roleDescriptors);
out.writeGenericMap(metadata);
}

private List<RoleDescriptor> readOptionalList(StreamInput in) throws IOException {
return in.readBoolean() ? in.readList(RoleDescriptor::new) : null;
}

private void writeOptionalList(StreamOutput out) throws IOException {
if (roleDescriptors == null) {
out.writeBoolean(false);
} else {
out.writeBoolean(true);
out.writeList(roleDescriptors);
}
public static UpdateApiKeyRequest usingApiKeyId(String id) {
return new UpdateApiKeyRequest(id, null, null);
}

public String getId() {
Expand All @@ -93,4 +84,17 @@ public Map<String, Object> getMetadata() {
public List<RoleDescriptor> getRoleDescriptors() {
return roleDescriptors;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UpdateApiKeyRequest that = (UpdateApiKeyRequest) o;
return id.equals(that.id) && Objects.equals(metadata, that.metadata) && Objects.equals(roleDescriptors, that.roleDescriptors);
}

@Override
public int hashCode() {
return Objects.hash(id, metadata, roleDescriptors);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.elasticsearch.xpack.core.security.action.apikey.GrantApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.InvalidateApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.UpdateApiKeyRequest;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.RealmDomain;
Expand Down Expand Up @@ -61,6 +62,11 @@ private ManageOwnClusterPermissionCheck() {
protected boolean extendedCheck(String action, TransportRequest request, Authentication authentication) {
if (request instanceof CreateApiKeyRequest) {
return true;
} else if (request instanceof UpdateApiKeyRequest) {
// Note: we return `true` here even if the authenticated entity is an API key. API keys *cannot* update themselves
// however this is a "business-logic" restriction, rather than one related to privileges. We therefore enforce this
// limitation at the transport layer, in `TransportUpdateApiKeyAction`
return true;
} else if (request instanceof final GetApiKeyRequest getApiKeyRequest) {
return checkIfUserIsOwnerOfApiKeys(
authentication,
Expand Down Expand Up @@ -96,7 +102,7 @@ protected boolean extendedCheck(String action, TransportRequest request, Authent
} else if (request instanceof GrantApiKeyRequest) {
return false;
}
String message = "manage own api key privilege only supports API key requests (not " + request.getClass().getName() + ")";
final var message = "manage own api key privilege only supports API key requests (not " + request.getClass().getName() + ")";
assert false : message;
throw new IllegalArgumentException(message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ public static Authentication.RealmRef randomRealmRef(boolean underDomain, boolea
}
}

public static RealmConfig.RealmIdentifier randomRealmIdentifier(boolean includeInternal) {
return new RealmConfig.RealmIdentifier(randomRealmTypeSupplier(includeInternal).get(), ESTestCase.randomAlphaOfLengthBetween(3, 8));
}

private static Supplier<String> randomRealmTypeSupplier(boolean includeInternal) {
final Supplier<String> randomAllRealmTypeSupplier = () -> ESTestCase.randomFrom(
"reserved",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.elasticsearch.xpack.core.security.action.apikey.InvalidateApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyAction;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.UpdateApiKeyRequest;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.AuthenticationTestHelper;
import org.elasticsearch.xpack.core.security.authc.AuthenticationTests;
Expand All @@ -40,9 +41,10 @@ public void testAuthenticationWithApiKeyAllowsAccessToApiKeyActionsWhenItIsOwner
final Authentication authentication = AuthenticationTests.randomApiKeyAuthentication(userJoe, apiKeyId);
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());

final TransportRequest updateApiKeyRequest = UpdateApiKeyRequest.usingApiKeyId(apiKeyId);
assertTrue(clusterPermission.check("cluster:admin/xpack/security/api_key/get", getApiKeyRequest, authentication));
assertTrue(clusterPermission.check("cluster:admin/xpack/security/api_key/invalidate", invalidateApiKeyRequest, authentication));
assertTrue(clusterPermission.check("cluster:admin/xpack/security/api_key/update", updateApiKeyRequest, authentication));
assertFalse(clusterPermission.check("cluster:admin/something", mock(TransportRequest.class), authentication));
}

Expand All @@ -69,8 +71,10 @@ public void testAuthenticationWithUserAllowsAccessToApiKeyActionsWhenItIsOwner()

TransportRequest getApiKeyRequest = GetApiKeyRequest.usingRealmAndUserName(realmRef.getName(), "joe");
TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingRealmAndUserName(realmRef.getName(), "joe");
TransportRequest updateApiKeyRequest = UpdateApiKeyRequest.usingApiKeyId(randomAlphaOfLength(10));
assertTrue(clusterPermission.check("cluster:admin/xpack/security/api_key/get", getApiKeyRequest, authentication));
assertTrue(clusterPermission.check("cluster:admin/xpack/security/api_key/invalidate", invalidateApiKeyRequest, authentication));
assertTrue(clusterPermission.check("cluster:admin/xpack/security/api_key/update", updateApiKeyRequest, authentication));
n1v0lg marked this conversation as resolved.
Show resolved Hide resolved

assertFalse(clusterPermission.check("cluster:admin/something", mock(TransportRequest.class), authentication));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ public class Constants {
"cluster:admin/xpack/security/api_key/grant",
"cluster:admin/xpack/security/api_key/invalidate",
"cluster:admin/xpack/security/api_key/query",
"cluster:admin/xpack/security/api_key/update",
"cluster:admin/xpack/security/cache/clear",
"cluster:admin/xpack/security/delegate_pki",
"cluster:admin/xpack/security/enroll/node",
Expand Down
Loading