-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Updatable API keys - logging audit trail event #88276
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 195 commits
3bba543
3a709a9
fc53cf3
74d264c
0bc2ec5
648ae52
2d43dda
4384e56
3d73b99
ff54fec
e484923
a9c8caa
d638a45
0c819e4
abe677b
3c7b2c1
29f0320
eef2b38
e5b8650
30cfc39
b14271a
cd5d58f
eeca38a
7c3d3f0
f6d1783
0e44586
3c83743
b88cdc8
68eaa91
36bb431
c545e20
63c0729
7aefeb1
89d7229
003f969
8937d94
bdd4dfb
4bd5cad
d88f949
421e04f
719e4ba
c536534
c46ab34
de179dd
7931e00
3f8b218
7166217
0f48e8c
ae573ca
629e5a1
d29c1e2
147adb0
8cffe22
0cac5e5
7d9956e
f5d089f
0b34c7b
65c8d46
2e3b623
2f91430
73d3fac
ef49292
3f099c4
9426e56
325d4d0
044831f
1d3d8a2
e377155
e95fd34
c536811
b7b4c36
30b0267
17375b3
0481c01
1a29f8b
6d7a341
99d5d06
6d7013c
64990b5
bba8f2b
dd69a00
3aefef8
49b4dd5
4a0b2b2
2bd3ea4
0473c5d
6c33703
d7bd723
9418b9b
0b2457d
3f283d9
0d02eba
82fdb6b
7a371a4
4586139
910500b
a9dd29f
41d3f03
d26f459
a9d005f
49eba62
3fdb5ff
df2b6a3
58019b4
58a7e02
3946dc1
a896ae0
542b360
7c36b17
b9fcad1
2b45045
87b6fb0
725248d
7481d52
160cac3
59b9093
ca65709
e025390
8ed5724
8a1a88b
782f6ec
60a0755
d8fc643
7e2e786
44f16ab
4ff33aa
5489f53
41b573f
665c426
84b22f6
a04792b
7f5240a
74b9e79
6a89230
ab9b0d8
673de56
9ada903
dc1db79
e8d7bb8
a354673
96e4864
85ee9de
d538118
77021e4
222d475
7654f75
1ead5ea
5aab296
0f17546
b3aaf2e
9e7ce5e
085cc4f
dde0b72
f90b93e
5e7a5bd
4be5dee
7b137d2
5070e48
bad21a0
cb67b3e
046a22d
a2f5f38
4f66060
46bc5f2
57938c5
6a2deb1
a838648
2d6d9d0
3e3e5e0
05571e2
57b7e67
0fc25b9
75e2e0e
ea8d79e
bedd5b0
96e681a
8ce5651
cfe84c8
eb6cdad
17e449f
23f8572
3673f0f
e5e16d0
16a6233
8f500b4
ba17743
6f2cdb7
e90a9c4
1596bdd
e694d90
7f646da
b3eeaa1
9d3f737
416d219
b06a593
55ea3f9
1f47fc6
ec73e1a
d9797df
aeb2558
3520028
da5e7d7
6db216b
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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 88276 | ||
summary: Updatable API keys - logging audit trail event | ||
area: Audit | ||
type: enhancement | ||
issues: [] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,6 +231,29 @@ event action. | |
["index-b*"],"privileges":["all"]}],"applications":[],"run_as":[]}]}}} | ||
==== | ||
|
||
[[event-update-apikey]] | ||
`update_apikey`:: | ||
Logged when the <<security-api-update-api-key,update API key>> API is | ||
n1v0lg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
invoked to update the attributes of an existing API key. | ||
+ | ||
You must include the `security_config_change` event type to audit the related | ||
event action. | ||
+ | ||
.Example | ||
[%collapsible%open] | ||
==== | ||
[source,js] | ||
{"type":"audit", "timestamp":"2020-12-31T00:33:52,521+0200", "node.id": | ||
"9clhpgjJRR-iKzOw20xBNQ", "event.type":"security_config_change", "event.action": | ||
"update_apikey", "request.id":"9FteCmovTzWHVI-9Gpa_vQ", "change":{"apikey_update": | ||
{"id":"zcwN3YEBBmnjw-K-hW5_","role_descriptors":[{"cluster": | ||
["monitor","manage_ilm"],"indices":[{"names":["index-a*"],"privileges": | ||
["read","maintenance"]},{"names":["in*","alias*"],"privileges":["read"], | ||
"field_security":{"grant":["field1*","@timestamp"],"except":["field11"]}}], | ||
"applications":[],"run_as":[]},{"cluster":["all"],"indices":[{"names": | ||
["index-b*"],"privileges":["all"]}],"applications":[],"run_as":[]}]}}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: no metadata here - will need to add it when we add metadata to the actual event. |
||
==== | ||
|
||
[[event-delete-privileges]] | ||
`delete_privileges`:: | ||
Logged when the | ||
|
@@ -535,8 +558,8 @@ In addition, if `event.type` equals <<security-config-change,`security_config_ch | |
the `event.action` attribute takes one of the following values: | ||
`put_user`, `change_password`, `put_role`, `put_role_mapping`, | ||
`change_enable_user`, `change_disable_user`, `put_privileges`, `create_apikey`, | ||
`delete_user`, `delete_role`, `delete_role_mapping`, `invalidate_apikeys` or | ||
`delete_privileges`. | ||
`delete_user`, `delete_role`, `delete_role_mapping`, `invalidate_apikeys`, | ||
`delete_privileges`, or `update_apikey`. | ||
|
||
`request.id` :: A synthetic identifier that can be used to correlate the events | ||
associated with a particular REST request. | ||
|
@@ -626,7 +649,7 @@ ones): | |
The events with the `event.type` attribute equal to `security_config_change` have one of the following | ||
`event.action` attribute values: `put_user`, `change_password`, `put_role`, `put_role_mapping`, | ||
`change_enable_user`, `change_disable_user`, `put_privileges`, `create_apikey`, `delete_user`, | ||
`delete_role`, `delete_role_mapping`, `invalidate_apikeys`, or `delete_privileges`. | ||
`delete_role`, `delete_role_mapping`, `invalidate_apikeys`, `delete_privileges`, or `update_apikey`. | ||
|
||
These events also have *one* of the following extra attributes (in addition to the common | ||
ones), which is specific to the `event.type` attribute. The attribute's value is a nested JSON object: | ||
|
@@ -640,7 +663,8 @@ ones), which is specific to the `event.type` attribute. The attribute's value is | |
`role_mapping` or for application `privileges`. | ||
`change` :: The object representation of the security config that | ||
is being changed. It can be the `password`, `enable` or `disable`, | ||
config object for native or built-in users. | ||
config object for native or built-in users, or `apikey_update` if | ||
an API key is updated. | ||
`create` :: The object representation of the new security config that is being | ||
created. This is currently only used for API keys auditing. | ||
If the API key is created using the | ||
|
@@ -758,6 +782,14 @@ object that is part of the above `role` config object. | |
---- | ||
// NOTCONSOLE | ||
|
||
`apikey_update` :: An object like: | ||
+ | ||
[source,js] | ||
---- | ||
`{"id": <string>, "role_descriptors" [<object>]}` | ||
---- | ||
// NOTCONSOLE | ||
|
||
`service_token` :: An object like: | ||
+ | ||
[source,js] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,8 @@ | |
import org.elasticsearch.xpack.core.security.action.apikey.GrantApiKeyRequest; | ||
import org.elasticsearch.xpack.core.security.action.apikey.InvalidateApiKeyAction; | ||
import org.elasticsearch.xpack.core.security.action.apikey.InvalidateApiKeyRequest; | ||
import org.elasticsearch.xpack.core.security.action.apikey.UpdateApiKeyAction; | ||
import org.elasticsearch.xpack.core.security.action.apikey.UpdateApiKeyRequest; | ||
import org.elasticsearch.xpack.core.security.action.privilege.DeletePrivilegesAction; | ||
import org.elasticsearch.xpack.core.security.action.privilege.DeletePrivilegesRequest; | ||
import org.elasticsearch.xpack.core.security.action.privilege.PutPrivilegesAction; | ||
|
@@ -287,7 +289,8 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener { | |
DeleteServiceAccountTokenAction.NAME, | ||
ActivateProfileAction.NAME, | ||
UpdateProfileDataAction.NAME, | ||
SetProfileEnabledAction.NAME | ||
SetProfileEnabledAction.NAME, | ||
UpdateApiKeyAction.NAME | ||
); | ||
private static final String FILTER_POLICY_PREFIX = setting("audit.logfile.events.ignore_filters."); | ||
// because of the default wildcard value (*) for the field filter, a policy with | ||
|
@@ -747,6 +750,9 @@ public void accessGranted( | |
} else if (msg instanceof final SetProfileEnabledRequest setProfileEnabledRequest) { | ||
assert SetProfileEnabledAction.NAME.equals(action); | ||
securityChangeLogEntryBuilder(requestId).withRequestBody(setProfileEnabledRequest).build(); | ||
} else if (msg instanceof final UpdateApiKeyRequest updateApiKeyRequest) { | ||
assert UpdateApiKeyAction.NAME.equals(action); | ||
securityChangeLogEntryBuilder(requestId).withRequestBody(updateApiKeyRequest).build(); | ||
} else { | ||
throw new IllegalStateException( | ||
"Unknown message class type [" | ||
|
@@ -1215,6 +1221,16 @@ LogEntryBuilder withRequestBody(GrantApiKeyRequest grantApiKeyRequest) throws IO | |
return this; | ||
} | ||
|
||
LogEntryBuilder withRequestBody(final UpdateApiKeyRequest updateApiKeyRequest) throws IOException { | ||
logEntry.with(EVENT_ACTION_FIELD_NAME, "update_apikey"); | ||
XContentBuilder builder = JsonXContent.contentBuilder().humanReadable(true); | ||
builder.startObject(); | ||
withRequestBody(builder, updateApiKeyRequest); | ||
builder.endObject(); | ||
logEntry.with(CHANGE_CONFIG_FIELD_NAME, Strings.toString(builder)); | ||
return this; | ||
} | ||
|
||
private void withRequestBody(XContentBuilder builder, CreateApiKeyRequest createApiKeyRequest) throws IOException { | ||
TimeValue expiration = createApiKeyRequest.getExpiration(); | ||
builder.startObject("apikey") | ||
|
@@ -1228,6 +1244,18 @@ private void withRequestBody(XContentBuilder builder, CreateApiKeyRequest create | |
.endObject(); // apikey | ||
} | ||
|
||
private void withRequestBody(final XContentBuilder builder, final UpdateApiKeyRequest updateApiKeyRequest) throws IOException { | ||
builder.startObject("apikey_update").field("id", updateApiKeyRequest.getId()); | ||
if (updateApiKeyRequest.getRoleDescriptors() != null) { | ||
builder.startArray("role_descriptors"); | ||
for (RoleDescriptor roleDescriptor : updateApiKeyRequest.getRoleDescriptors()) { | ||
withRoleDescriptor(builder, roleDescriptor); | ||
} | ||
builder.endArray(); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not including metadata here since it doesn't seem relevant to the security change event itself. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's an oversight that That said, I am happy for it to be a separate PR. In fact, I can take this one so that you can focus on the main tasks. |
||
builder.endObject(); | ||
} | ||
|
||
private void withRoleDescriptor(XContentBuilder builder, RoleDescriptor roleDescriptor) throws IOException { | ||
builder.startObject().array(RoleDescriptor.Fields.CLUSTER.getPreferredName(), roleDescriptor.getClusterPrivileges()); | ||
if (roleDescriptor.getConditionalClusterPrivileges() != null && roleDescriptor.getConditionalClusterPrivileges().length > 0) { | ||
|
Uh oh!
There was an error while loading. Please reload this page.