Skip to main content

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 nameelastic_agent
CreatesEndpoints
Runs onA sensor with network reach to Kibana
Presence flagelastic_exits
Field prefixelastic_

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.

Policy revision index tells you about drift

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

FromToProtocolPort
The sensor running the integrationKibana, at the URL configured on the instanceHTTPS over TCPWhatever 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

NeedWhy
An account that can create Kibana users or rolesThe credential is a Kibana username and password — see Creating the Kibana user
That user able to read FleetThe run lists enrolled agents and reads nothing else
Fleet in use in the stackA 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

NeedWhy
A registered, healthy sensor with reach to KibanaThe 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

FieldRequiredNotes
NameYesLabel for this instance
URLYesKibana base URL — the Fleet API lives in Kibana, not Elasticsearch
UsernameYesKibana user
PasswordYesPassword for that user
CookiesNoExtra cookies added to requests
SensorYesSensor that will run the integration
Ignore SSLNoPresent on the form, but not consulted — see the warning below
Point this at Kibana, not Elasticsearch

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.

Unenrolled agents disappear rather than age

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 hasEnter it asExample
The Kibana base URLURLhttps://kibana.example.com:5601
The Kibana userUsernamelumenedge-fleet-read
That user's passwordPassword
TODO

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

FieldTypeHolds
elastic_exitsBooleanAlways true — the presence flag marking this asset as Elastic-covered
elastic_agent_idTextFleet agent ID. The primary key used to match the host on later runs
elastic_agent_hostnameTextHostname the agent reports, from the agent's local metadata
elastic_agent_nameTextHost 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_idTextHost ID from the agent's local metadata — the machine identity, distinct from the Fleet agent ID

Network

FieldTypeHolds
elastic_agent_source_ipIPThe host's private IPv4 addresses. Derived, not copied — see the note below
elastic_agent_macTextMAC addresses the agent reports — an array in the source record

Platform

FieldTypeHolds
elastic_agent_os_nameTextOS name as the agent reports it
elastic_agent_os_fullTextFull OS string. This is the input to the normalised os, and through it to type
elastic_agent_os_familyTextOS family. The input to the normalised os_vendor
elastic_agent_architectureTextHost architecture

Agent state

FieldTypeHolds
elastic_agent_agent_versionTextElastic Agent version
elastic_agent_enrolled_atDate/timeWhen the agent enrolled into Fleet. Also the sort key of the collection query
elastic_agent_last_checkinDate/timeWhen the agent last checked in. Drives both the offline drop rule above and the shared first_seen and last_seen
elastic_agent_updated_atDate/timeLast change to the Fleet agent record

Policy

FieldTypeHolds
elastic_agent_policyTextThe agent policy ID, not its name — resolve it in Fleet if you need the label
elastic_agent_policy_revision_idxTextRevision of that policy the agent is running
elastic_agent_source_ip is filtered, not copied

The 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 fieldDerived from
nameselastic_agent_name
private_ipelastic_agent_source_ip — the same private-IPv4-only list
oselastic_agent_os_full, normalised to a canonical name such as Windows 11 or Ubuntu 20.04
os_vendorelastic_agent_os_family, normalised to Windows, Linux, MacOS, OpenBSD or VMware
typeInferred from the normalised osEndpoint, Server, Hypervisor and similar
first_seenelastic_agent_last_checkin, on the run that creates the asset
last_seenelastic_agent_last_checkin
updated_atTime of the run that produced the record
Elastic overwrites shared fields it does not own

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 narrow

The 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.

Timestamps have to match one of two formats

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