Skip to content

Commit 6520fa2

Browse files
authored
Add cloud API keys to auth info report (#130041)
* add change and test * improve test
1 parent 1e6473a commit 6520fa2

File tree

3 files changed

+51
-19
lines changed

3 files changed

+51
-19
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/xcontent/XContentUtils.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,7 @@ public static void addAuthorizationInfo(final XContentBuilder builder, final Map
112112
private static void addSubjectInfo(XContentBuilder builder, Subject subject) throws IOException {
113113
switch (subject.getType()) {
114114
case USER -> builder.array(User.Fields.ROLES.getPreferredName(), subject.getUser().roles());
115-
case API_KEY -> {
116-
addApiKeyInfo(builder, subject);
117-
}
115+
case API_KEY -> addApiKeyInfo(builder, subject);
118116
case SERVICE_ACCOUNT -> builder.field("service_account", subject.getUser().principal());
119117
case CROSS_CLUSTER_ACCESS -> {
120118
builder.startObject("cross_cluster_access");
@@ -129,7 +127,16 @@ private static void addSubjectInfo(XContentBuilder builder, Subject subject) thr
129127
builder.endObject();
130128
}
131129
case CLOUD_API_KEY -> {
132-
// TODO Add cloud API key information here
130+
builder.startObject("cloud_api_key");
131+
Map<String, Object> metadata = subject.getUser().metadata();
132+
builder.field("id", subject.getUser().principal());
133+
Object name = metadata.get(AuthenticationField.API_KEY_NAME_KEY);
134+
if (name instanceof String) {
135+
builder.field("name", name);
136+
}
137+
builder.field("internal", metadata.get(AuthenticationField.API_KEY_INTERNAL_KEY));
138+
builder.array(User.Fields.ROLES.getPreferredName(), subject.getUser().roles());
139+
builder.endObject();
133140
}
134141
}
135142
}

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTestHelper.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,27 @@ public static User randomUser() {
9292
);
9393
}
9494

95+
public static User randomCloudApiKeyUser() {
96+
return randomCloudApiKeyUser(null);
97+
}
98+
99+
public static User randomCloudApiKeyUser(String principal) {
100+
final Map<String, Object> metadata = ESTestCase.randomBoolean()
101+
? null
102+
: Map.ofEntries(
103+
Map.entry(AuthenticationField.API_KEY_NAME_KEY, ESTestCase.randomAlphanumericOfLength(64)),
104+
Map.entry(AuthenticationField.API_KEY_INTERNAL_KEY, ESTestCase.randomBoolean())
105+
);
106+
return new User(
107+
principal == null ? ESTestCase.randomAlphanumericOfLength(64) : principal,
108+
ESTestCase.randomArray(1, 3, String[]::new, () -> "role_" + ESTestCase.randomAlphaOfLengthBetween(3, 8)),
109+
null,
110+
null,
111+
metadata,
112+
true
113+
);
114+
}
115+
95116
public static InternalUser randomInternalUser() {
96117
return ESTestCase.randomFrom(InternalUsers.get());
97118
}
@@ -260,27 +281,14 @@ public static Authentication randomCloudApiKeyAuthentication(User user, String a
260281
if (apiKeyId == null) {
261282
apiKeyId = user != null ? user.principal() : ESTestCase.randomAlphanumericOfLength(64);
262283
}
263-
final Map<String, Object> metadata = ESTestCase.randomBoolean()
264-
? null
265-
: Map.ofEntries(
266-
Map.entry(AuthenticationField.API_KEY_NAME_KEY, ESTestCase.randomAlphanumericOfLength(64)),
267-
Map.entry(AuthenticationField.API_KEY_INTERNAL_KEY, ESTestCase.randomBoolean())
268-
);
269284
if (user == null) {
270-
user = new User(
271-
apiKeyId,
272-
ESTestCase.randomArray(1, 3, String[]::new, () -> "role_" + ESTestCase.randomAlphaOfLengthBetween(3, 8)),
273-
null,
274-
null,
275-
metadata,
276-
true
277-
);
285+
user = randomCloudApiKeyUser(apiKeyId);
278286
}
279287

280288
assert user.principal().equals(apiKeyId) : "user principal must match cloud API key ID";
281289

282290
return Authentication.newCloudApiKeyAuthentication(
283-
AuthenticationResult.success(user, metadata),
291+
AuthenticationResult.success(user, user.metadata()),
284292
"node_" + ESTestCase.randomAlphaOfLengthBetween(3, 8)
285293
);
286294

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/xcontent/XContentUtilsTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import java.util.stream.Collectors;
2525

2626
import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_ID_KEY;
27+
import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_INTERNAL_KEY;
2728
import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_NAME_KEY;
2829
import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.CROSS_CLUSTER_ACCESS_AUTHENTICATION_KEY;
30+
import static org.hamcrest.Matchers.containsString;
2931
import static org.hamcrest.Matchers.equalTo;
3032

3133
public class XContentUtilsTests extends ESTestCase {
@@ -62,6 +64,21 @@ public void testAddAuthorizationInfoWithApiKey() throws IOException {
6264
assertThat(json, equalTo("{\"authorization\":{\"api_key\":{\"id\":\"" + apiKeyId + "\",\"name\":\"" + apiKeyName + "\"}}}"));
6365
}
6466

67+
public void testAddAuthorizationInfoWithCloudApiKey() throws IOException {
68+
User user = AuthenticationTestHelper.randomCloudApiKeyUser();
69+
Authentication authentication = AuthenticationTestHelper.randomCloudApiKeyAuthentication(user);
70+
String json = generateJson(Map.of(AuthenticationField.AUTHENTICATION_KEY, authentication.encode()));
71+
assertThat(json, containsString("{\"authorization\":{\"cloud_api_key\":{\"id\":\"" + user.principal()));
72+
assertThat(json, containsString("\"internal\":" + user.metadata().getOrDefault(API_KEY_INTERNAL_KEY, null)));
73+
if (user.metadata().containsKey(API_KEY_NAME_KEY)) {
74+
assertThat(json, containsString("\"name\":\"" + user.metadata().getOrDefault(API_KEY_NAME_KEY, null) + "\""));
75+
}
76+
for (String role : user.roles()) {
77+
assertThat(json, containsString(role));
78+
}
79+
80+
}
81+
6582
public void testAddAuthorizationInfoWithServiceAccount() throws IOException {
6683
String account = "elastic/" + randomFrom("kibana", "fleet-server");
6784
User user = new User(account);

0 commit comments

Comments
 (0)