Elastic agent
Pulls the agents enrolled in Elastic Fleet — the hosts shipping data into your Elastic deployment — with their platform detail and policy assignment.
| Type name | elastic_agent |
| Creates | Endpoints |
| Runs on | A sensor with network reach to Kibana |
| Presence flag | elastic_exits |
| Field prefix | elastic_ |
What it contributes
- Identity — agent ID, hostname, agent name, host ID
- Network — source IP, MAC
- Platform — OS name, OS full, OS family, architecture
- Agent state — agent version, enrolled at, last check-in, updated at
- Policy — policy, policy revision index
Alongside its own elastic_* fields it writes the shared fields names, os,
os_vendor, type and private_ip, so its hosts correlate against every other
source. None of them is protected from overwrite — see
Exported fields for the complete list and what that implies.
Agents sitting on an old elastic_agent_policy_revision_idx have not picked up
the current policy. Grouping by it turns the inventory into a Fleet rollout
report.
Requirements
The integration is outbound-only: it reads the Fleet API on a schedule, so nothing is installed in the Elastic stack, nothing changes on the enrolled hosts, and nothing has to reach into the deployment.
Network access
| From | To | Protocol | Port |
|---|---|---|---|
| The sensor running the integration | Kibana, at the URL configured on the instance | HTTPS over TCP | Whatever the URL names — 5601 on a default self-managed install, 443 on Elastic Cloud |
One host, and it is Kibana rather than Elasticsearch: the Fleet API is served by
Kibana, so an egress rule to 9200 will not do — see the warning under
Configuration. This is usually an internal destination rather
than an internet one, so the rule belongs in the internal firewall.
Access in Elastic
| Need | Why |
|---|---|
| An account that can create Kibana users or roles | The credential is a Kibana username and password — see Creating the Kibana user |
| That user able to read Fleet | The run lists enrolled agents and reads nothing else |
| Fleet in use in the stack | A stack with no Fleet-enrolled hosts authenticates fine and returns nothing |
The username and password are sent on every request, as HTTP basic auth.
In this deployment
| Need | Why |
|---|---|
| A registered, healthy sensor with reach to Kibana | The integration runs on a sensor, on the platform's schedule — see Sensors |
Because the destination is typically internal, the sensor's placement matters more here than for the SaaS integrations: it has to sit somewhere that can route to Kibana.
Configuration
| Field | Required | Notes |
|---|---|---|
| Name | Yes | Label for this instance |
| URL | Yes | Kibana base URL — the Fleet API lives in Kibana, not Elasticsearch |
| Username | Yes | Kibana user |
| Password | Yes | Password for that user |
| Cookies | No | Extra cookies added to requests |
| Sensor | Yes | Sensor that will run the integration |
| Ignore SSL | No | Present on the form, but not consulted — see the warning below |
The run calls /api/fleet/agents on the configured host. That endpoint is served
by Kibana (port 5601 by default), not by Elasticsearch (9200). Pointing it at
Elasticsearch produces a 404 that reads like a version problem.
The query asks for active agents only, so an unenrolled host stops being returned
entirely rather than ageing out. With Asset missing set to Delete asset,
unenrolling an agent removes the asset — which is rarely what you want if Elastic
is one source among several.
Creating the Kibana user
Create a Kibana user, or a role that user holds, with read access to Fleet. The
built-in fleet-admin-style privileges are more than needed; Fleet read on the
Kibana side is enough to list agents.
There is no generated key to copy — the three values you enter are the ones you already have:
| Elastic has | Enter it as | Example |
|---|---|---|
| The Kibana base URL | URL | https://kibana.example.com:5601 |
| The Kibana user | Username | lumenedge-fleet-read |
| That user's password | Password | — |
Pin down the exact minimum Kibana privilege set for GET /api/fleet/agents on
current stack versions, and document whether an API key can be used in place of
username and password.
The integration then authenticates with HTTP basic auth and pages
/api/fleet/agents, 100 agents at a time, sorted by enrolment date descending,
with inactive and upgradeable-only agents excluded by the query itself.
Exported fields
Each agent returned by /api/fleet/agents becomes one asset record. The
integration copies the Fleet agent attributes into fields prefixed elastic_,
keeping the Elastic name so a value in the platform can always be traced back to
the agent record it came from, and additionally writes the shared fields that make
the host correlate with other sources.
Records are dropped at two points. The collection query excludes inactive and
upgradeable-only agents, so they never arrive at all. Of what does arrive, an agent
whose elastic_agent_last_checkin is older than the Ignore if host is offline
window configured in the instance's advanced settings is dropped before anything is
written.
Identity
| Field | Type | Holds |
|---|---|---|
elastic_exits | Boolean | Always true — the presence flag marking this asset as Elastic-covered |
elastic_agent_id | Text | Fleet agent ID. The primary key used to match the host on later runs |
elastic_agent_hostname | Text | Hostname the agent reports, from the agent's local metadata |
elastic_agent_name | Text | Host name from the same metadata. This is what becomes the shared names, and what the run falls back to when the agent ID does not match |
elastic_agent_host_id | Text | Host ID from the agent's local metadata — the machine identity, distinct from the Fleet agent ID |
Network
| Field | Type | Holds |
|---|---|---|
elastic_agent_source_ip | IP | The host's private IPv4 addresses. Derived, not copied — see the note below |
elastic_agent_mac | Text | MAC addresses the agent reports — an array in the source record |
Platform
| Field | Type | Holds |
|---|---|---|
elastic_agent_os_name | Text | OS name as the agent reports it |
elastic_agent_os_full | Text | Full OS string. This is the input to the normalised os, and through it to type |
elastic_agent_os_family | Text | OS family. The input to the normalised os_vendor |
elastic_agent_architecture | Text | Host architecture |
Agent state
| Field | Type | Holds |
|---|---|---|
elastic_agent_agent_version | Text | Elastic Agent version |
elastic_agent_enrolled_at | Date/time | When the agent enrolled into Fleet. Also the sort key of the collection query |
elastic_agent_last_checkin | Date/time | When the agent last checked in. Drives both the offline drop rule above and the shared first_seen and last_seen |
elastic_agent_updated_at | Date/time | Last change to the Fleet agent record |
Policy
| Field | Type | Holds |
|---|---|---|
elastic_agent_policy | Text | The agent policy ID, not its name — resolve it in Fleet if you need the label |
elastic_agent_policy_revision_idx | Text | Revision of that policy the agent is running |
elastic_agent_source_ip is filtered, not copiedThe agent reports its addresses as a list, often with a prefix length attached. The
run strips the prefix, then keeps only private IPv4 — RFC 1918 space. Public
addresses, IPv6 and link-local addresses are discarded rather than stored
elsewhere, so a cloud host with only a public address gets an empty
elastic_agent_source_ip and an empty shared private_ip. The full unfiltered
list is not retained in any field.
Shared fields it writes
These are the normalised, source-independent fields. They are what other integrations correlate against, so their values are cleaned up rather than copied verbatim:
| Shared field | Derived from |
|---|---|
names | elastic_agent_name |
private_ip | elastic_agent_source_ip — the same private-IPv4-only list |
os | elastic_agent_os_full, normalised to a canonical name such as Windows 11 or Ubuntu 20.04 |
os_vendor | elastic_agent_os_family, normalised to Windows, Linux, MacOS, OpenBSD or VMware |
type | Inferred from the normalised os — Endpoint, Server, Hypervisor and similar |
first_seen | elastic_agent_last_checkin, on the run that creates the asset |
last_seen | elastic_agent_last_checkin |
updated_at | Time of the run that produced the record |
CrowdStrike and Nessus write os, type and mac in do-not-override mode, so a
weaker source cannot clobber what a stronger one asserted. This integration writes
none of its shared fields that way: every run overwrites names, os, os_vendor,
type and private_ip with whatever Fleet reported, even where an EDR had already
supplied a better value. Where a host's os disagrees with its cs_os_version,
check whether an Elastic run is the last writer.
os_vendor comes from the family string, and the normaliser is narrowThe normaliser recognises values containing windows/microsoft, linux,
ubuntu, debian, mac, openbsd or vmware, and passes anything else through
unchanged. Because it is fed os.family rather than the full OS string, a family
value that does not contain one of those substrings lands in os_vendor verbatim.
Compare os_vendor against elastic_agent_os_family before treating it as
normalised.
enrolled_at, updated_at and last_checkin are parsed as
yyyy-MM-dd'T'HH:mm:ss'Z' or yyyy-MM-dd'T'HH:mm:ss.SSS'Z'. A value in any other
shape parses to zero rather than raising — which reads as the epoch in the field,
and, if Ignore if host is offline is set, drops the agent as impossibly stale.
An estate that vanishes the moment you configure that window is the symptom.
See also
- Elastic aggregation query — for data in your own indices rather than Fleet's
- Elastic asset owner — resolving owners from Elastic logs
- Integrations overview — the shared configuration model
- Assets — inspecting which source asserted an attribute