
Ecs Field Mappings
- 212 installs
- 15 repo stars
- Updated August 5, 2026
- elastic/integration-skills
Elastic skill for ECS field mappings, ecs.yml, categorization, and custom field types.
About
Elastic integration ECS field mapping skill. Guides populating ecs.yml with ECS field references, selecting ECS categorization values for event.kind, category, type, and outcome, choosing custom field types when ECS fields are insufficient, and troubleshooting mapping conflicts. Used when defining field mappings for new or existing data streams in integration packages. Ensures documents align with Elastic Common Schema for cross-integration correlation and Kibana field compatibility.
- ecs.yml population with ECS field references
- ECS categorization value selection for events
- Custom field type choices when ECS insufficient
- Mapping conflict troubleshooting guidance
- Data stream field definition for integration packages
Ecs Field Mappings by the numbers
- 212 all-time installs (skills.sh)
- Ranked #639 of 2,064 Data Science & ML skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
ecs-field-mappings capabilities & compatibility
- Capabilities
- populate ecs yml · select categorization · define custom fields · troubleshoot mappings
- Works with
- elasticsearch
- Use cases
- data analysis · api development
npx skills add https://github.com/elastic/integration-skills --skill ecs-field-mappingsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 212 |
|---|---|
| repo stars | ★ 15 |
| Last updated | August 5, 2026 |
| Repository | elastic/integration-skills ↗ |
How do I map vendor fields to ECS in this integration data stream?
Define ECS field mappings for Elastic integration data streams including ecs.yml population, categorization values, and custom field types.
Who is it for?
Elastic integration developers defining or fixing field mappings.
Skip if: Kibana dashboard layout or ingest processor syntax alone.
When should I use this skill?
User defines field mappings, populates ecs.yml, or troubleshoots ECS mapping issues.
What you get
ecs.yml populated with correct ECS references, categorization, and custom fields.
Files
ecs-field-mappings
When to use
Use this skill when tasks include:
- adding or modifying files under
data_stream/<stream>/fields/ - populating
ecs.ymlwith ECS field references - selecting
event.kind,event.category,event.type, andevent.outcomevalues - choosing field
typeand mapping properties (metric_type,dimension,multi_fields, and related options) - checking whether a field already exists in ECS before adding custom fields
- troubleshooting mapping validation/build failures from
elastic-package check,elastic-package lint, or pipeline test schema checks
ECS dependency configuration
Every package needs _dev/build/build.yml at the package root. This file pins the ECS schema version used for field resolution.
dependencies:
ecs:
reference: "git@v9.3.0"This file is required whenever the package has any field file. The scaffold does not generate it — create it manually. If it is missing or uses an outdated version, tests report ECS fields as undefined (e.g., field "destination.ip" is undefined).
Field files and roles
A data stream's fields/ directory contains a small set of YAML files with distinct responsibilities:
base-fields.yml
Fixed routing constants and @timestamp. All six fields are ECS fields, so each entry uses external: ecs. Override type and value where the data stream needs a constant_keyword with a fixed value — the description is inherited from ECS automatically.
- name: data_stream.type
external: ecs
- name: data_stream.dataset
external: ecs
- name: data_stream.namespace
external: ecs
- name: event.module
external: ecs
type: constant_keyword
value: <package_name>
- name: event.dataset
external: ecs
type: constant_keyword
value: <package_name>.<stream_name>
- name: '@timestamp'
external: ecsDo not add other fields here. Only these routing constants and @timestamp belong in base-fields.yml.
constant_keyword candidates
Fields that hold a single value for every document in a data stream should use constant_keyword. Beyond the routing constants in base-fields.yml, evaluate these:
| Field | Why constant_keyword |
|---|---|
event.dataset | One value per data stream by definition |
event.module | One value per package |
data_stream.type | Fixed per stream (logs/metrics) |
data_stream.dataset | Fixed per stream |
data_stream.namespace | Set at deployment, constant within index |
observer.vendor | Package represents one vendor |
observer.product | Package represents one product |
When a constant_keyword field is also an ECS field (e.g., observer.vendor), use external: ecs with the type override. This inherits the description from ECS and avoids manual duplication. Place the definition in the appropriate field file (ecs.yml for most ECS fields, base-fields.yml for routing constants):
- name: observer.vendor
external: ecs
type: constant_keyword
value: Acme Corp`remove_from_source` option: Because constant_keyword stores the value once in index metadata, it does not need to appear in every document's _source. Elasticsearch handles this automatically — no explicit _source.excludes configuration is needed. This saves storage when the value is always the same.
ecs.yml
Populate this file with every ECS field the pipeline sets. Use only name and external: ecs for each entry — no type, no description. The type is resolved from the ECS schema via _dev/build/build.yml.
external: ecs must be used whenever a field name exists in ECS (wiki reference). This applies across field files — ecs.yml, base-fields.yml, and any file that defines an ECS field. You may override properties (e.g., type: constant_keyword, value:) while still using external: ecs — the description is inherited from ECS. Do not use external: ecs in fields.yml, agent.yml, or beats.yml — those files define non-ECS fields.
- name: event.kind
external: ecs
- name: event.category
external: ecs
- name: event.type
external: ecs
- name: event.outcome
external: ecs
- name: event.action
external: ecs
- name: source.ip
external: ecs
- name: source.port
external: ecs
- name: destination.ip
external: ecs
- name: user.name
external: ecs
- name: related.ip
external: ecs
- name: related.user
external: ecsWhen attaching extra metadata to an ECS field (for example making a field a TSDB dimension or a constant_keyword with a fixed value), combine external: ecs with that metadata. The description is inherited from ECS. Place the definition in ecs.yml (or base-fields.yml for routing constants):
- name: observer.vendor
external: ecs
type: constant_keyword
value: Acme Corpfields.yml
Integration-specific custom (non-ECS) fields only. Use a nested group hierarchy for the vendor namespace:
- name: acme.firewall
type: group
fields:
- name: rule_id
type: keyword
- name: policy_name
type: keyword
- name: bytes_in
type: long
unit: byte
metric_type: gaugeGroups do not need to be declared as type: object — defining a group with nested fields is sufficient. The object structure is implicit.
labels.* exception
labels is a core ECS object (type: object, object_type: keyword) designed for ad-hoc key-value metadata. Subkeys under labels.* do not require vendor namespacing — this is the one exception to the vendor-prefix rule.
Use labels.* for simple keyword flags or integration-internal markers (e.g., labels.is_ioc_transform_source). Use the vendor namespace for structured or nested data from an upstream source.
Flags vs structured data
Boolean flags and simple tags can live flat under the vendor group:
- name: acme.firewall
type: group
fields:
- name: is_encrypted
type: boolean
- name: policy_name
type: keywordStructured data from the source should use sub-groups for logical hierarchy:
- name: acme.firewall
type: group
fields:
- name: rule
type: group
fields:
- name: id
type: keyword
- name: name
type: keyword
- name: action
type: keywordagent.yml
Non-ECS fields populated by the Elastic Agent or Beats framework but not covered by ECS. Include only when the input type emits these fields. Typical fields: cloud.image.id, cloud.instance.id, host.containerized, host.os.build, host.os.codename, input.type, log.offset.
See references/root-and-core-fields.md for full YAML samples.
beats.yml
Filebeat/Beats-specific fields not covered by ECS. Minimal form contains input.type and log.offset. Some inputs also emit log.flags or log.file.* sub-fields.
See references/root-and-core-fields.md for full YAML samples.
ECS field selection
Prefer ECS fields whenever semantics match. If no ECS field exists for the data, add it under the package namespace in fields.yml.
Categorization quick reference
| Field | Type | Notes |
|---|---|---|
event.kind | keyword | Highest-level classification. |
event.category | keyword[] | Broad domain buckets — always an array. |
event.type | keyword[] | Sub-buckets within category — always an array. |
event.outcome | keyword | success, failure, unknown; only set when meaningful. |
event.kind:alert,asset,enrichment,event,metric,pipeline_error,signal,stateevent.category:api,authentication,configuration,database,driver,email,file,host,iam,intrusion_detection,library,malware,network,package,process,registry,session,threat,vulnerability,webevent.type:access,admin,allowed,change,connection,creation,deletion,denied,device,end,error,group,indicator,info,installation,protocol,start,user
Decision workflow: 1. event.kind: event for normal logs, metric for measurements, state for snapshots, pipeline_error in on_failure 2. event.category: one or more values (array) for the broad domain 3. event.type: one or more values (array) for operation style 4. event.outcome: only when a clear success/failure/unknown applies; omit for informational/metric events 5. If no allowed value fits, leave the field empty — do not invent values
Use event.action for source-specific verbs (blocked, dropped, authenticated).
See references/categorization-cheatsheet.md for full worked examples.
Timestamp fields
ECS defines several timestamp fields with distinct semantics. Use them correctly:
| Field | When to use | Set by |
|---|---|---|
@timestamp | The primary event timestamp. Parse from the source event data. Required. | Integration pipeline |
event.created | When the event was first created or recorded by the source system, if different from @timestamp. | Integration pipeline |
event.start | When an activity or period began (e.g., session start, connection start). | Integration pipeline |
event.end | When an activity or period ended (e.g., session end, connection close). | Integration pipeline |
event.ingested | When the event was ingested into Elasticsearch. | Elasticsearch (outside the integration) |
`event.ingested` must NEVER be set by an integration pipeline. It is managed automatically by Elasticsearch's final pipeline. Do not add a set processor for event.ingested.
When the source data contains multiple timestamps: 1. Map the primary event timestamp to @timestamp. 2. If another timestamp represents when the event was first recorded/created, map it to event.created. 3. If timestamps represent the start or end of an activity, map them to event.start and event.end. 4. If a timestamp does not match the semantics of any of the above, map it to a custom field under the vendor namespace with type: date in fields.yml.
Reusable fieldset nesting rules
Some ECS field sets must be nested under a parent entity — they are not valid at document root.
`geo` — must be nested under: client.geo, destination.geo, host.geo, observer.geo, server.geo, source.geo, threat.indicator.geo
Root-level geo.* fields are not recognized and will appear unmapped. Always set target_field on the geoip processor:
- geoip:
field: source.ip
target_field: source.geo
ignore_missing: true`as` (Autonomous System) — nested under: client.as, destination.as, server.as, source.as
When using geoip for geolocation, always also perform an ASN lookup using GeoLite2-ASN.mmdb and rename the raw output fields to ECS names. The geoip ASN processor outputs asn and organization_name, which must be renamed to as.number and as.organization.name:
- geoip:
database_file: GeoLite2-ASN.mmdb
field: source.ip
target_field: source.as
properties:
- asn
- organization_name
ignore_missing: true
- rename:
field: source.as.asn
target_field: source.as.number
ignore_missing: true
- rename:
field: source.as.organization_name
target_field: source.as.organization.name
ignore_missing: trueSee the ingest-pipelines skill → references/processor-cookbook.md for the full geo+ASN pattern with both source and destination.
`os` — nested under: host.os, observer.os, user_agent.os
Nested (array-of-objects) ECS fields
Some ECS fields use type: nested, meaning they hold an array of objects where each object groups related sub-fields together. The pipeline must produce this structure — do not flatten these into parallel scalar arrays.
ECS fields that use `nested` type:
| Field | Contains |
|---|---|
email.attachments | file.name, file.size, file.extension, file.mime_type, file.hash.* |
threat.enrichments | indicator.*, matched.* |
threat.indicator.file.elf.sections | name, physical_size, virtual_size, etc. |
threat.indicator.file.pe.sections | name, physical_size, virtual_size, etc. |
process.elf.sections | name, physical_size, virtual_size, etc. |
process.pe.sections | name, physical_size, virtual_size, etc. |
Anti-pattern — parallel arrays (WRONG):
{
"email": {
"attachments": {
"file": {
"name": ["a.pdf", "b.pdf"],
"size": [1024, 2048]
}
}
}
}This loses the association between each attachment's name and size. Queries cannot isolate individual objects.
Correct — array of objects:
{
"email": {
"attachments": [
{ "file": { "name": "a.pdf", "size": 1024 } },
{ "file": { "name": "b.pdf", "size": 2048 } }
]
}
}`ecs.yml` declaration: declare only the parent nested field with external: ecs. Child fields (email.attachments.file.name, etc.) inherit their types from the ECS schema — do not redeclare them individually.
- name: email.attachments
external: ecsPipeline construction: when source data delivers attachment metadata as separate parallel arrays (e.g., a comma-separated list of filenames and a separate list of sizes), use a script processor to zip them into an array of objects. See ingest-pipelines → references/painless-patterns.md for array construction patterns and references/processor-cookbook.md → Foreach semantics for iterating over array elements.
- script:
tag: build_email_attachments
description: Build email.attachments as array of nested objects from parallel source arrays.
lang: painless
if: ctx.json?.file_names instanceof List && ctx.json?.file_sizes instanceof List
source: |-
def names = ctx.json.file_names;
def sizes = ctx.json.file_sizes;
int len = Math.min(names.size(), sizes.size());
def attachments = new ArrayList(len);
for (int i = 0; i < len; i++) {
def attachment = new HashMap();
def file = new HashMap();
file.put('name', names.get(i));
file.put('size', sizes.get(i));
attachment.put('file', file);
attachments.add(attachment);
}
ctx.email = ctx.email ?: [:];
ctx.email.attachments = attachments;When source data already delivers each attachment as a separate object (e.g., a JSON array of attachment objects), no zipping is needed — use rename or set with copy_from to place the array at email.attachments directly.
Custom field types
For non-ECS fields in fields.yml:
keywordfor identifiers and exact-match stringsconstant_keywordfor fixed values (dataset/module constants)long,double,scaled_floatfor metrics and numeric valuesdate/date_nanosfor timestamps (date_nanosonly when sub-millisecond precision is truly needed)ipfor IP addressesbooleanfor true/false (avoid string booleans in pipelines)geo_pointfor lat/lon coordinatesgroupwith nestedfieldsfor logical structure — no need to separately declare intermediateobjectnodesflattenedfor arbitrary key/value blobs with unknown keysnestedfor arrays of objects requiring per-object query isolation (heavier than group)text/match_only_textfor full-text content; add akeywordsub-field viamulti_fieldswhen aggregation is also needed
Useful properties on numeric fields: metric_type (gauge or counter), unit (e.g., byte, percent, ms), dimension for low-cardinality TSDB fields.
See references/mapping-type-matrix.md for the full type reference.
Field naming conventions
| Rule | DO | DON'T |
|---|---|---|
| Use snake_case | user_name, request_count | userName, RequestCount |
| Use lowercase | source_ip | Source_IP |
| No asterisks in names | network.bytes | network.* (literal asterisk) |
| Use groups for hierarchy | vendor.module.field as nested group | vendor.module.field as flat dotted name |
Field names must never contain literal * characters. An asterisk in a field name is almost always a copy-paste error from documentation or wildcard patterns. Use a group with known subfields or flattened for dynamic keys instead.
Dotted field names vs nested groups
Both styles are valid in field files:
# Dotted (flat) — common for ECS fields in ecs.yml
- name: source.ip
external: ecs
# Nested group — common for custom fields
- name: acme.firewall
type: group
fields:
- name: rule_id
type: keywordPipeline expected output (*-expected.json) always uses nested object form regardless of how the source data represented the field. A source "host.name": "myhost" produces {"host": {"name": "myhost"}} in the output.
When source data contains literal dotted keys that Elasticsearch would otherwise expand, use dot_expander:
- dot_expander:
field: "*"
override: truegeo_point field handling
In pipeline test expected outputs, geo_point fields appear as objects with lat and lon keys:
"source": {
"geo": {
"location": { "lat": 51.5142, "lon": -0.0931 },
"city_name": "London",
"country_iso_code": "GB"
}
}These sub-fields do not need entries in fields.yml — they are part of the geo_point type mapping. Only the *.geo.location field (type geo_point) needs to be in ecs.yml for non-standard parent prefixes where ecs@mappings does not apply.
Common pipeline categorization patterns
Web access
- set:
field: event.kind
value: event
- append:
field: event.category
value: web
- append:
field: event.type
value: accessOutcome from HTTP status
- set:
field: event.outcome
value: success
if: "ctx?.http?.response?.status_code != null && ctx.http.response.status_code < 400"
- set:
field: event.outcome
value: failure
if: "ctx?.http?.response?.status_code != null && ctx.http.response.status_code >= 400"Pipeline error fallback
on_failure:
- set:
field: event.kind
value: pipeline_errorTroubleshooting: "field X is undefined" for ECS fields
When tests report field "destination.ip" is undefined for standard ECS fields:
1. Check _dev/build/build.yml exists at the package root 2. Check dependencies.ecs.reference is set (use git@v9.3.0) 3. Check the field is listed in ecs.yml with external: ecs
Fix the root cause. Do not work around it by:
- Adding ECS fields with full type definitions to
fields.ymlwithoutexternal: ecs - Skipping
external: ecsand defining ECS field types/descriptions manually
Exception: Custom (non-ECS) fields reported as undefined must be defined in fields.yml.
Common failure patterns
- missing `_dev/build/build.yml` — all ECS fields reported undefined; create with
dependencies.ecs.reference - outdated ECS version in `build.yml` — fields from newer ECS versions undefined; update reference to
git@v9.3.0 - ECS field set in pipeline but missing from `ecs.yml` — field is undefined in test schema validation; add it to
ecs.yml - ECS field defined without `external: ecs` — descriptions and types diverge from ECS; always use
external: ecsfor ECS fields, with overrides as needed - `metric_type` on non-numeric field — lint error
- *`geo.` at document root** — unmapped; always nest under a parent entity
- `event.category` or `event.type` set as scalar — must use
appendprocessor, notset - `nested` ECS field mapped as parallel arrays —
email.attachments,threat.enrichments, and similarnestedfields must be arrays of objects, not objects with parallel scalar arrays; see the Nested (array-of-objects) ECS fields section above
Validation loop
elastic-package lint
elastic-package check
elastic-package test pipeline --data-streams <stream>References
references/mapping-type-matrix.mdreferences/categorization-cheatsheet.mdreferences/root-and-core-fields.mdreferences/fieldset-links.md- ECS field reference
ECS categorization cheatsheet
Use this guide when selecting event.kind, event.category, event.type, and event.outcome.
Core rules
- Use only ECS allowed values.
event.categoryandevent.typeare arrays.- If no allowed value fits, leave the field empty.
- Use
event.actionfor source-specific verbs (for exampleblocked,dropped,authenticated). - Set
event.outcomeonly when success/failure applies.
event.kind allowed values
| Value | Use when | Notes |
|---|---|---|
alert | External detection/alert event | Used for alerts from external security systems. |
asset | Inventory/entity snapshot records | Asset and identity inventory style records. |
enrichment | Enrichment/context feeds | IOC/context datasets that enrich other events. |
event | General event/log | Most common value for integration logs. |
metric | Numeric measurements | Time series metrics such as cpu/memory/rate. |
pipeline_error | Ingest/parsing failure | Use in ingest on_failure paths. |
signal | Reserved for Kibana alerting framework | Do not set this in data ingestion pipelines. |
state | Non-numeric state snapshots | For periodic categorical state measurements. |
event.category allowed values and typical event.type pairings
| Category | Typical event.type values |
|---|---|
api | access, admin, allowed, change, creation, deletion, denied, end, info, start, user |
authentication | start, end, info |
configuration | access, change, creation, deletion, info |
database | access, change, info, error |
driver | change, end, info, start |
email | info |
file | access, change, creation, deletion, info |
host | access, change, end, info, start |
iam | admin, change, creation, deletion, group, info, user |
intrusion_detection | allowed, denied, info |
library | start |
malware | info |
network | access, allowed, connection, denied, end, info, protocol, start |
package | access, change, deletion, info, installation, start |
process | access, change, end, info, start |
registry | access, change, creation, deletion |
session | start, end, info |
threat | indicator |
vulnerability | info |
web | access, error, info |
event.type allowed values
| Value | Meaning |
|---|---|
access | Something was accessed. |
admin | Administrative object activity. |
allowed | Something was allowed. |
change | Something changed. |
connection | Connection/flow event, usually network. |
creation | Something was created. |
deletion | Something was deleted. |
denied | Something was denied. |
device | Device object related activity. |
end | Something ended. |
error | Error event type (not pipeline parse failures). |
group | Group object related activity. |
indicator | IOC indicator event. |
info | Informational event. |
installation | Installation event. |
protocol | Protocol detail/analysis event. |
start | Something started. |
user | User object related activity. |
event.outcome allowed values
| Value | Meaning | Common usage |
|---|---|---|
success | Successful result | Successful auth, successful HTTP response, successful policy action. |
failure | Failed result | Failed auth, blocked/failed operation from producer perspective. |
unknown | Attempt observed, result unknown | Request-only view where response/outcome is not known. |
Do not set event.outcome for purely informational or metric/state events where outcome does not apply.
Worked examples
Firewall blocked connection (block succeeded)
event.kind:eventevent.category:["network"]event.type:["connection", "denied"]event.outcome:successevent.action:dropped
Failed user creation attempt
event.kind:eventevent.category:["iam"]event.type:["user", "creation"]event.outcome:failure
Web access log
event.kind:eventevent.category:["web"]event.type:["access"]event.outcome:successorfailure(often derived from HTTP status)
File inventory listing (no action outcome)
event.kind:eventevent.category:["file"]event.type:["info"]event.outcome: not set
CDR field requirements
Cloud Detection & Response (CDR) fields apply only to cloud security integrations -- those covering CSPM, CWPP, or vulnerability management use cases (e.g., aws_security_hub, google_scc, prisma_cloud, wiz). Do NOT flag missing CDR fields on non-cloud-security integrations such as general logging, metrics, APM, or non-security cloud integrations.
Aligned with: Elastic CDR 3P Developer Guide v1.0
Finding types and event categorization
| Type | event.kind | event.category | event.type | Key fields |
|---|---|---|---|---|
| Misconfiguration | state | configuration | info | result.evaluation, resource.*, rule.* |
| Vulnerability | state | vulnerability | info | vulnerability.*, package.*, resource.* |
| Runtime detection | alert | varies | varies | rule.*, threat.* |
Misconfiguration finding fields
Fields are listed by importance tier. Must Have fields cause critical UI breakage if missing.
Must Have
| Field | Type | ECS | Purpose |
|---|---|---|---|
@timestamp | date | yes | Base field |
event.ingested | date | yes | Set by Elasticsearch final pipeline -- do NOT set in integration pipeline. Required for transform sync |
event.id | keyword | yes | Unique identifier for grouping by multi-value fields |
data_stream.namespace | keyword | yes | Required for transform uniqueness and Kibana Space support. Must be `keyword` (not `constant_keyword`) in the latest index |
resource.id | keyword | no | Cloud resource ID (e.g., ARN). Transform uniqueness relies on it |
resource.name | keyword | no | Human-readable resource name. Default data grid column |
result.evaluation | keyword | no | passed, failed, or unknown. Used for score calculation |
rule.name | keyword | yes | Pretty name of the evaluation rule. Default column, flyout title |
rule.uuid | keyword | yes | Unique rule identifier. Used for transform uniqueness |
observer.vendor | constant_keyword | yes | Vendor name (e.g., Wiz, Amazon). Use `constant_keyword` for performance |
user.name | keyword | yes | For user-related findings, enables entity correlation |
host.name | keyword | yes | For host-related findings, enables entity correlation |
Should Have
| Field | Type | ECS | Purpose |
|---|---|---|---|
cloud.account.id | keyword | yes | Grouping on Findings page |
cloud.provider | keyword | yes | Must be lowercase: aws, gcp, azure |
event.category | keyword | yes | Must be `configuration` |
event.kind | keyword | yes | Must be `state` |
event.type | keyword | yes | Must be `info` |
event.outcome | keyword | yes | failure, success, or unknown (mirrors result.evaluation) |
event.created | date | yes | When the finding was created |
resource.type | keyword | no | Resource type identifier (e.g., identity-management) |
resource.sub_type | keyword | no | Resource sub-type (e.g., aws-nacl). Default column, billing |
rule.description | keyword | yes | Rule description, shown in flyout |
rule.version | keyword | yes | Rule version, used in telemetry |
rule.tags | keyword | no | Tags for rules (e.g., [gcp, CIS 3.8]) |
rule.impact | keyword | no | Impact of misconfiguration, shown in flyout |
rule.rationale | keyword | no | Rationale for the rule |
rule.reference | keyword | yes | Links to documentation |
rule.remediation | keyword | no | Remediation steps |
result.evidence | object | no | Arbitrary evidence object, shown as JSON in flyout |
orchestrator.cluster.id | keyword | yes | K8s cluster ID for grouping |
orchestrator.cluster.name | keyword | yes | K8s cluster name for grouping |
Benchmark fields (Should Have)
Only when mapping a finding to a benchmark makes sense (1:1 or clear primary).
| Field | Type | ECS | Purpose |
|---|---|---|---|
rule.benchmark.name | keyword | no | Benchmark name (e.g., CIS Google Cloud Platform Foundation) |
rule.benchmark.version | keyword | no | Benchmark version (e.g., 1.9.0) |
rule.benchmark.rule_number | keyword | no | Rule number in benchmark. Provide same value in rule.id |
rule.id | keyword | yes | Rule number in benchmark |
rule.section | keyword | no | Benchmark section the rule belongs to |
Vulnerability finding fields
Must Have
| Field | Type | ECS | Purpose |
|---|---|---|---|
@timestamp | date | yes | Base field |
event.ingested | date | yes | Set by Elasticsearch final pipeline -- do NOT set in integration pipeline. Required for transform sync |
event.id | keyword | yes | Unique identifier for grouping |
event.category | keyword | yes | Must be `vulnerability` |
data_stream.namespace | keyword | yes | Must be `keyword` (not `constant_keyword`) in the latest index |
resource.id | keyword | no | Vulnerable resource ID |
resource.name | keyword | no | Vulnerable resource name (e.g., FQDN) |
observer.vendor | constant_keyword | yes | Vendor name. Use `constant_keyword` for performance |
host.name | keyword | yes | Host name for entity correlation |
package.name | keyword | yes | Affected package name |
vulnerability.id | keyword | yes | CVE ID. Can be multiple values or empty |
vulnerability.severity | keyword | yes | Must be: Low, Medium, High, Critical, or None |
vulnerability.score.base | float | yes | CVSS base score |
vulnerability.title | keyword | no | Human-readable vulnerability title |
Should Have
| Field | Type | ECS | Purpose |
|---|---|---|---|
cloud.account.id | keyword | yes | Grouping on Findings page |
cloud.provider | keyword | yes | Must be lowercase: aws, gcp, azure |
event.kind | keyword | yes | Must be `state` |
event.type | keyword | yes | Must be `info` |
package.version | keyword | yes | Current package version |
package.fixed_version | keyword | no | Version where vulnerability was fixed |
vulnerability.description | keyword | yes | Vulnerability description |
vulnerability.reference | keyword | yes | Link to vulnerability details |
vulnerability.published_date | date | no | Needs explicit `date` type mapping (not covered by ecs@mappings) |
vulnerability.score.version | keyword | yes | CVSS version (e.g., 3.1) |
vulnerability.scanner.vendor | constant_keyword | yes | Use `constant_keyword` for performance |
Correlation fields
CDR integrations MUST populate related.* fields for threat hunting:
related.ip-- resource IPs, actor IPsrelated.user-- IAM users, service accountsrelated.hash-- artifact hashes (for CWPP findings)
These are set by the pipeline via append processors and auto-mapped from ECS -- they typically do NOT need fields.yml entries.
Field definition examples (fields.yml)
Most CDR fields are set by the pipeline and auto-mapped via ECS. Only define fields in fields.yml when they need explicit declaration:
# ecs.yml -- ECS fields via external reference
- name: cloud.provider
external: ecs
- name: cloud.account.id
external: ecs
- name: rule.name
external: ecs
- name: rule.uuid
external: ecs
- name: vulnerability.id
external: ecs
- name: vulnerability.severity
external: ecs
- name: observer.vendor
external: ecs
type: constant_keyword
- name: vulnerability.scanner.vendor
external: ecs
type: constant_keyword
# fields.yml -- non-ECS fields only (no external: ecs here)
- name: vulnerability
type: group
fields:
- name: published_date
type: date
description: When the vulnerability was published.
- name: resource
type: group
fields:
- name: id
type: keyword
description: Cloud resource ID (e.g., ARN).
- name: name
type: keyword
description: Human-readable resource name.
- name: type
type: keyword
description: Resource type identifier.
- name: sub_type
type: keyword
description: Resource sub-type.
- name: result
type: group
fields:
- name: evaluation
type: keyword
description: Evaluation result (passed, failed, unknown).
- name: evidence
type: flattened
description: Arbitrary evidence object for the finding.
- name: rule
type: group
fields:
- name: benchmark
type: group
fields:
- name: name
type: keyword
description: Benchmark name (e.g., CIS Google Cloud Platform Foundation).
- name: version
type: keyword
description: Benchmark version.
- name: rule_number
type: keyword
description: Rule number within the benchmark.
- name: section
type: keyword
description: Benchmark section the rule belongs to.
- name: impact
type: keyword
description: Impact of the misconfigured rule.
- name: rationale
type: keyword
description: Rationale for the rule.
- name: remediation
type: keyword
description: Remediation steps for the finding.
- name: package
type: group
fields:
- name: fixed_version
type: keyword
description: Package version where the vulnerability was fixed.CDR field review checklist
Misconfiguration findings
- [ ] Must Have fields present:
resource.id,resource.name,result.evaluation,rule.name,rule.uuid,event.id,observer.vendor-- HIGH if missing - [ ]
event.categoryset toconfiguration,event.kindtostate,event.typetoinfo-- HIGH if wrong - [ ]
data_stream.namespacemapped askeyword(notconstant_keyword) in latest index -- HIGH if wrong type - [ ]
observer.vendorusesconstant_keywordtype -- MEDIUM - [ ] Benchmark fields present if applicable (
rule.benchmark.name/version/rule_number) -- MEDIUM - [ ]
related.*fields populated by pipeline -- MEDIUM
Vulnerability findings
- [ ] Must Have fields present:
vulnerability.id,vulnerability.severity,vulnerability.score.base,vulnerability.title,resource.id,resource.name,package.name,observer.vendor,event.id-- HIGH if missing - [ ]
event.categoryset tovulnerability,event.kindtostate,event.typetoinfo-- HIGH if wrong - [ ]
vulnerability.published_datemapped asdatetype (not covered byecs@mappings) -- MEDIUM - [ ]
vulnerability.scanner.vendorusesconstant_keywordtype -- MEDIUM - [ ]
package.fixed_versiondefined if available from vendor -- LOW - [ ]
data_stream.namespacemapped askeywordin latest index -- HIGH if wrong type
When CDR fields are NOT required
Do NOT flag CDR field issues for:
- General logging or metrics integrations
- APM integrations
- Non-security cloud integrations (e.g., billing, resource inventory without security posture)
- Integrations that do not produce security findings (misconfiguration, vulnerability, or runtime detection)
ECS fieldset links
Use this index to jump directly to ECS field set documentation.
Primary ECS references
- ECS field reference: <https://www.elastic.co/docs/reference/ecs/ecs-field-reference>
- ECS getting started: <https://www.elastic.co/docs/reference/ecs/ecs-getting-started>
- ECS categorization overview: <https://www.elastic.co/docs/reference/ecs/ecs-category-field-values-reference>
- ECS fields CSV (generated): <https://github.com/elastic/ecs/blob/main/generated/csv/fields.csv>
Field set index
| Field set | Description | URL |
|---|---|---|
| Base | Root-level common event fields. | <https://www.elastic.co/docs/reference/ecs/ecs-base> |
| Agent | Monitoring agent metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-agent> |
| Autonomous System | ASN and routing prefix details. | <https://www.elastic.co/docs/reference/ecs/ecs-as> |
| Client | Client side of network connection. | <https://www.elastic.co/docs/reference/ecs/ecs-client> |
| Cloud | Cloud provider and resource metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-cloud> |
| Code Signature | Binary code-signing details. | <https://www.elastic.co/docs/reference/ecs/ecs-code_signature> |
| Container | Container runtime and image details. | <https://www.elastic.co/docs/reference/ecs/ecs-container> |
| Data Stream | Data stream naming dimensions. | <https://www.elastic.co/docs/reference/ecs/ecs-data_stream> |
| Destination | Destination side of network connection. | <https://www.elastic.co/docs/reference/ecs/ecs-destination> |
| Device | Device-level activity and attributes. | <https://www.elastic.co/docs/reference/ecs/ecs-device> |
| DLL | Dynamic library metadata for processes. | <https://www.elastic.co/docs/reference/ecs/ecs-dll> |
| DNS | DNS query and answer fields. | <https://www.elastic.co/docs/reference/ecs/ecs-dns> |
| ECS | ECS schema metadata fields. | <https://www.elastic.co/docs/reference/ecs/ecs-ecs> |
| ELF Header | Linux ELF executable metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-elf> |
| Email message and transaction fields. | <https://www.elastic.co/docs/reference/ecs/ecs-email> | |
| Entity | Generic entity descriptors. | <https://www.elastic.co/docs/reference/ecs/ecs-entity> |
| Error | Error reporting fields. | <https://www.elastic.co/docs/reference/ecs/ecs-error> |
| Event | Event context and categorization fields. | <https://www.elastic.co/docs/reference/ecs/ecs-event> |
| FaaS | Function-as-a-service execution fields. | <https://www.elastic.co/docs/reference/ecs/ecs-faas> |
| File | File and filesystem metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-file> |
| Gen AI | Generative AI request/response fields. | <https://www.elastic.co/docs/reference/ecs/ecs-gen_ai> |
| Geo | Geographic location fields. | <https://www.elastic.co/docs/reference/ecs/ecs-geo> |
| Group | User group information. | <https://www.elastic.co/docs/reference/ecs/ecs-group> |
| Hash | Hash values, often file hashes. | <https://www.elastic.co/docs/reference/ecs/ecs-hash> |
| Host | Host machine metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-host> |
| HTTP | HTTP request/response details. | <https://www.elastic.co/docs/reference/ecs/ecs-http> |
| Interface | Observer interface details. | <https://www.elastic.co/docs/reference/ecs/ecs-interface> |
| Log | Logging framework/source context. | <https://www.elastic.co/docs/reference/ecs/ecs-log> |
| Mach-O Header | macOS Mach-O executable metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-macho> |
| Network | Network flow and protocol context. | <https://www.elastic.co/docs/reference/ecs/ecs-network> |
| Observer | External observer/sensor metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-observer> |
| Orchestrator | Container orchestrator context. | <https://www.elastic.co/docs/reference/ecs/ecs-orchestrator> |
| Organization | Company/organization context fields. | <https://www.elastic.co/docs/reference/ecs/ecs-organization> |
| Operating System | OS identity and version fields. | <https://www.elastic.co/docs/reference/ecs/ecs-os> |
| Package | Installed software package metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-package> |
| PE Header | Windows PE executable metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-pe> |
| Process | Process lifecycle and identity fields. | <https://www.elastic.co/docs/reference/ecs/ecs-process> |
| Registry | Windows registry activity fields. | <https://www.elastic.co/docs/reference/ecs/ecs-registry> |
| Related | Pivot fields for correlation. | <https://www.elastic.co/docs/reference/ecs/ecs-related> |
| Risk information | Risk score and risk level fields. | <https://www.elastic.co/docs/reference/ecs/ecs-risk> |
| Rule | Detection/rule metadata fields. | <https://www.elastic.co/docs/reference/ecs/ecs-rule> |
| Server | Server side of network connection. | <https://www.elastic.co/docs/reference/ecs/ecs-server> |
| Service | Service identity and version fields. | <https://www.elastic.co/docs/reference/ecs/ecs-service> |
| Source | Source side of network connection. | <https://www.elastic.co/docs/reference/ecs/ecs-source> |
| Threat | Threat classification fields. | <https://www.elastic.co/docs/reference/ecs/ecs-threat> |
| TLS | TLS handshake/session fields. | <https://www.elastic.co/docs/reference/ecs/ecs-tls> |
| Tracing | Distributed tracing fields. | <https://www.elastic.co/docs/reference/ecs/ecs-tracing> |
| URL | URL parsing and representation fields. | <https://www.elastic.co/docs/reference/ecs/ecs-url> |
| User | User identity fields. | <https://www.elastic.co/docs/reference/ecs/ecs-user> |
| User agent | Browser/client user-agent details. | <https://www.elastic.co/docs/reference/ecs/ecs-user_agent> |
| VLAN | VLAN observation fields. | <https://www.elastic.co/docs/reference/ecs/ecs-vlan> |
| Volume | Storage volume metadata fields. | <https://www.elastic.co/docs/reference/ecs/ecs-volume> |
| Vulnerability | Vulnerability and CVE context fields. | <https://www.elastic.co/docs/reference/ecs/ecs-vulnerability> |
| x509 Certificate | X.509 certificate metadata. | <https://www.elastic.co/docs/reference/ecs/ecs-x509> |
Mapping type matrix
Use this matrix when selecting field mappings in integration field files.
Common field types
| Type | Typical use | Notes |
|---|---|---|
constant_keyword | fixed values (data_stream.*, module/dataset constants) | can use value to enforce a constant |
keyword | IDs, codes, exact-match strings | supports ignore_above, normalizer, multi_fields |
wildcard | high-variance strings searched with wildcards | supports ignore_above; more costly than keyword |
text / match_only_text | full-text content | use multi_fields for keyword subfield when aggregation is needed |
long / integer / short / byte | integral numeric values | metric_type allowed for numeric metric fields |
double / float / half_float / scaled_float | fractional numeric values | use scaled_float when controlled precision/storage tradeoff is useful |
unsigned_long | non-negative large integers | useful for very large counters/IDs |
boolean | true/false values | avoid string booleans in pipelines |
date / date_nanos | timestamps | use date_nanos only when sub-millisecond precision is required |
ip | IP addresses | can be a TSDB dimension |
geo_point | latitude/longitude | for geospatial queries/maps |
group | logical field grouping in package definitions | requires nested fields definitions; intermediate object nodes are implicit |
flattened | arbitrary key/value blobs with unknown keys | simpler than nested object trees for unbounded keys |
nested | arrays of objects requiring per-object query isolation | more complex and heavier than group; source data arriving as parallel scalar arrays must be restructured into an array of objects before indexing — see SKILL.md → Nested (array-of-objects) ECS fields |
histogram / aggregate_metric_double | pre-aggregated metric payloads | special-purpose metric storage |
alias | mapped field alias path | requires path to target field |
version | semantic version strings | purpose-built version mapping behaviour |
Property compatibility highlights
| Property | Use with | Notes |
|---|---|---|
metric_type | numeric metric fields, histogram, aggregate_metric_double | allowed values: gauge, counter |
unit | numeric fields | examples: byte, percent, ms, micros |
dimension | selected low-cardinality fields (TSDB) | pick carefully; affects series cardinality and performance |
multi_fields | keyword, text, wildcard | index same source field in multiple ways |
ignore_above | keyword, wildcard | default is 1024 in spec |
scaling_factor | scaled_float | controls precision/storage tradeoff |
external | ECS references | only use in ecs.yml — external: ecs |
runtime | selected scalar types | schema-restricted; use only when query-time fields are intended |
High-signal patterns
Base stream constants
- name: data_stream.type
external: ecs
- name: data_stream.dataset
external: ecs
- name: data_stream.namespace
external: ecsCustom integration group
- name: vendor.product
type: group
fields:
- name: id
type: keyword
- name: latency
type: long
unit: ms
metric_type: gaugeECS reference in ecs.yml
- name: source.ip
external: ecs
- name: observer.vendor
external: ecs
type: constant_keyword
value: Acme Corpmulti_fields patterns
# Keyword primary with text sub-field for full-text search
- name: vendor.message
type: keyword
description: Raw message from the vendor API.
multi_fields:
- name: text
type: match_only_text# Keyword primary with wildcard sub-field for glob-pattern matching
- name: file.path
type: keyword
multi_fields:
- name: text
type: wildcard# Keyword primary with text sub-field for full-text search on long values
- name: request_parameters
type: keyword
ignore_above: 8191
multi_fields:
- name: text
type: text
default_field: falseWhen to use:
- keyword + text/match_only_text: when the field needs both exact matching AND full-text search (long error messages, request parameters, descriptive strings)
- keyword + wildcard: when glob-pattern queries are needed (file paths, URLs)
- keyword + long: when a string field may also need numeric range queries
Properties:
| Property | When to set | Purpose |
|---|---|---|
ignore_above: 1024 | keyword primary when values can be long | prevents indexing of excessively long values |
default_field: false | on sub-fields | excludes from default query expansion |
When NOT to use:
- Don't add text sub-fields to short identifiers (IDs, codes, status values) — exact matching is sufficient
- Don't add multi_fields to ECS fields declared with
external: ecs— they inherit their own multi_fields configuration - Don't add multi_fields when the primary type already satisfies all query needs
Selection rules of thumb
- choose the narrowest type that matches real source data
- avoid relying on implicit coercion in ingest for mapping correctness
- use
keywordby default for string identifiers; only usetextwhen full-text search matters - define timestamps as
date - use
groupfor explicit structure and docs; useflattenedfor flexible unknown keys - add
metric_typeandunitfor metrics intended for TSDB and visualization quality
Validation loop
After mapping edits:
elastic-package lint
elastic-package check
elastic-package test pipeline --data-streams <stream>ECS root and core fields
Use this page as a quick lookup for ECS fields that appear most often in integrations.
Base (root) fields
These are top-level fields in ECS and commonly expected in events.
| Field | Type | Why it matters |
|---|---|---|
@timestamp | date | Required event time used by queries, timelines, and dashboards. |
message | match_only_text | Human-readable log message for quick triage. |
tags | keyword[] | Lightweight event annotations (environment, source, flags). |
Core ECS field sets used frequently in integrations
Event and ECS metadata
| Field set | Typical fields | Typical use |
|---|---|---|
event | event.kind, event.category, event.type, event.outcome, event.action, event.original, event.dataset, event.module | Classify and describe what happened. |
ecs | ecs.version | Declares ECS version the pipeline targets. |
data_stream | data_stream.type, data_stream.dataset, data_stream.namespace | Data stream routing and naming dimensions. |
log | log.level, log.logger, log.file.path, log.offset | Source logging context. |
error | error.message, error.type, error.stack_trace | Mainly used for integration error reporting. |
Network and transport
| Field set | Typical fields | Typical use |
|---|---|---|
source | source.ip, source.port, source.address, source.bytes | Origin side of connection/event. |
destination | destination.ip, destination.port, destination.address, destination.bytes | Target side of connection/event. |
network | network.transport, network.protocol, network.type, network.direction | Shared network context and protocol shape. |
url | url.original, url.path, url.domain, url.query | Parsed URI details for HTTP and proxy logs. |
http | http.request.method, http.response.status_code, http.version | HTTP semantics and response details. |
dns | dns.question.name, dns.question.type, dns.answers | DNS query/answer activity. |
geo | source.geo.*, destination.geo.*, client.geo.*, host.geo.*, observer.geo.*, server.geo.* | Geo enrichment from GeoIP; always nested under an entity prefix — never at document root. |
Identity, host, and runtime context
| Field set | Typical fields | Typical use |
|---|---|---|
host | host.name, host.hostname, host.ip, host.os.name, host.architecture | Host identity and platform details. |
user | user.name, user.id, user.email, user.roles | Primary actor information. |
service | service.name, service.type, service.version, service.address | Service endpoint and runtime metadata. |
observer | observer.type, observer.name, observer.vendor, observer.product | Device/system that observed the event. |
container | container.id, container.name, container.runtime, container.image.name | Containerized runtime details. |
cloud | cloud.provider, cloud.account.id, cloud.region, cloud.instance.id | Cloud resource and tenancy context. |
process | process.name, process.pid, process.executable, process.args | Process lifecycle and command context. |
file | file.path, file.name, file.extension, file.size | File and filesystem activity. |
related | related.ip, related.hosts, related.user, related.hash | Pivot fields for cross-event correlation. |
user_agent | user_agent.original, user_agent.name, user_agent.version | Browser/client fingerprint extraction. |
Field file samples: agent.yml and beats.yml
agent.yml
Non-ECS fields populated by Elastic Agent or Beats but not covered by ECS. Include only when the input type emits these fields.
- name: cloud
title: Cloud
group: 2
type: group
fields:
- name: image.id
type: keyword
description: Image ID for the cloud instance.
- name: instance.id
type: keyword
description: Instance ID of the host machine.
- name: host
title: Host
group: 2
type: group
fields:
- name: containerized
type: boolean
description: If the host is a container.
- name: os.build
type: keyword
description: OS build information.
- name: os.codename
type: keyword
description: OS codename, if any.
- name: input.type
type: keyword
description: Input type.
- name: log.offset
type: long
description: Log offset.beats.yml
Filebeat/Beats-specific fields not covered by ECS. Minimal form:
- name: input.type
type: keyword
description: Type of Filebeat input.
- name: log.offset
type: long
description: Log offset.Some inputs also emit log.flags or log.file.* sub-fields — add them here when present in source data.
Notes for implementation authors
- Prefer ECS fields whenever semantics match to keep cross-integration queries simple.
- If no ECS field exists for your data, add namespaced custom fields under your package namespace in
fields.yml. - Keep categorization fields (
event.*) within allowed ECS values. - List every ECS field the pipeline sets in
ecs.ymlwithname+external: ecs. - Ensure
_dev/build/build.ymlexists withdependencies.ecs.reference: "git@v9.3.0".
Related skills
FAQ
What file holds ECS mappings?
ecs.yml in the integration package data stream directory.
When do I use custom fields?
When ECS fields are insufficient for vendor-specific attributes after checking ECS coverage.
What categorization values matter?
event.kind, event.category, event.type, and event.outcome per ECS categorization guidance.