[Entity Store] Implement EUID#250566
Conversation
1d0e717 to
c55e063
Compare
I agree, we don't have a clear guideline yet on establishing additional fields for all the ECS root fields (i.e |
That's is a valid concern, and since we are moving to store a typed entity.id (e.g. I suggest we reserve an This keeps the typed ids for uniqueness, and preserving enough context to re-query source events and debug id generation. The idea of the Let me know what are your thoughts on that, this can be totally addressed in a follow-up ticket as well |
csr
left a comment
There was a problem hiding this comment.
LGTM, thanks for working through our Scout feedback. Nice tests!
@opauloh I think for simplicity of the query having just the |
opauloh
left a comment
There was a problem hiding this comment.
User / Host / Service Ranking implementation LGTM 💯
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]
History
cc @romulets |
Introduces unique id identifier.
### Decisions:
- Not create an abstraction for the evaluation logic yet. Pushing this
as it's for faster development loop
- **Always prefixing the `${type}:` to ids**
- `host.name@host.domain` becomes `host:host.name @ host.domain`
- `user.name` becomes `user:user.name`
- `user.name` becomes `user:user.name`
- `service.name` becomes `service:service.name`
- `user.entity.id` becomes `user:user.entity.id`
- `host.entity.id` becomes `host:host.entity.id`
- `service.entity.id` becomes `service:service.entity.id`
- `entity.id` becomes `generic:entity.id`
### Decisions to be made
- Will generic be only on `entity.id`? I believe so. @opauloh do you
agree?
- With always prepending things, we might temper with valuable data.
Should we have another field to keep ids with the type?
### Tests
1. Enable the v2 feature flag (via `kibana.yaml` or http call)
```
POST kbn:/internal/kibana/settings
{
"changes": {
"securitySolution:entityStoreEnableV2": true
}
}
```
2. Install the entity store v2
```
POST kbn:/internal/security/entity-store/install?apiVersion=2
{}
```
3. Watch it run or force logs extraction via the internal api
```
POST kbn:/internal/security/entity-store/host/force-log-extraction?apiVersion=2
{
"fromDateISO": "2026-01-20T11:00:00Z",
"toDateISO": "2026-01-20T13:00:00Z"
}
```
<details>
<summary> I used this `_bulk` operation as testing data </summary>
```
POST /_bulk
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:00Z", "user": {"name": "john.doe"},
"host": {"entity": {"id": "host-123"}}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:01Z", "user": {"name": "jane.smith"},
"host": {"id": "host-456"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:02Z", "user": {"name": "bob.jones"},
"host": {"name": "server-01"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:03Z", "user": {"name": "alice.brown",
"id": "user-789"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:04Z", "user": {"id": "user-101"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:04Z", "user": {"entity": {"id":
"non-generated-user"}}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:05Z", "user": {"email":
"test@example.com"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:06Z", "user": {"name":
"charlie.wilson", "domain": "corp"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:07Z", "user": {"name": "david.lee"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:08Z", "user": {"name": "", "id":
"user-202"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:09Z", "user": {"name": null, "id":
"user-303"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:10Z", "user": {"name": "eve.martin"},
"host": {"entity": {"id": ""}, "id": "host-404"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:11Z", "user": {"name": "frank.taylor"},
"host": {"entity": {"id": null}, "id": "", "name": "workstation-05"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:12Z", "user": {"name":
"grace.anderson", "email": "grace@example.com"}, "host": {"entity":
{"id": null}, "id": null, "name": null}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:13Z", "user": {"name": "henry.clark"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:14Z", "user": {"name": "iris.davis",
"domain": ""}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:15Z", "user": {"name": "jack.white",
"domain": null}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:16Z", "user": {"name": "karen.green",
"id": "user-505"}, "host": {"entity": {"id": "host-505"}}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:17Z", "user": {"name": "larry.black",
"email": "larry@example.com"}, "host": {"id": "host-606"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:18Z", "user": {"name": "mary.blue",
"domain": "corp"}, "host": {"name": "server-07"}}
{"create": {"_index": ".entities.v2.updates.security_user_default"}}
{"@timestamp": "2026-01-20T12:05:19Z"}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:00Z", "host": {"id": "host-123"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:01Z", "host": {"name": "server-01",
"domain": "example.com"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:02Z", "host": {"hostname":
"workstation-05", "domain": "corp.local"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:03Z", "host": {"domain": "test.org"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:04Z", "host": {"hostname":
"laptop-01"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:05Z", "host": {"name": "desktop-02"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:06Z", "host": {"id": "host-456",
"name": "server-02", "domain": "example.com"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:07Z", "host": {"id": "host-789",
"hostname": "workstation-10", "domain": "corp.local"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:08Z", "host": {"name": "server-03",
"hostname": "backup-server", "domain": "test.com"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:09Z", "host": {"id": "", "name":
"server-04", "domain": "example.org"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:10Z", "host": {"id": null, "name":
"server-05", "domain": "test.net"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:11Z", "host": {"name": "", "domain":
"example.com"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:12Z", "host": {"name": null,
"hostname": "workstation-20", "domain": "corp.local"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:13Z", "host": {"name": "server-06",
"domain": ""}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:14Z", "host": {"name": "server-07",
"domain": null}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:15Z", "host": {"hostname": "",
"domain": "test.org"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:16Z", "host": {"hostname": null,
"domain": "example.com"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:17Z", "host": {"hostname": "laptop-02",
"name": "server-08", "domain": "corp.local"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:18Z", "host": {"hostname":
"workstation-30"}}
{"create": {"_index": ".entities.v2.updates.security_host_default"}}
{"@timestamp": "2026-01-20T12:05:04Z", "host": {"entity": {"id":
"non-generated-host"}}}
```
</details>
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary A combination of elastic#250566 + elastic#250772 caused a lint issue, then an import issue on main.
Introduces unique id identifier.
Decisions:
${type}:to idshost.name@host.domainbecomeshost:host.name @ host.domainuser.namebecomesuser:user.nameuser.namebecomesuser:user.nameservice.namebecomesservice:service.nameuser.entity.idbecomesuser:user.entity.idhost.entity.idbecomeshost:host.entity.idservice.entity.idbecomesservice:service.entity.identity.idbecomesgeneric:entity.idDecisions to be made
entity.id? I believe so. @opauloh do you agree?Tests
kibana.yamlor http call)I used this `_bulk` operation as testing data