File: //usr/share/filebeat/module/salesforce/login-stream/ingest/pipeline.yml
---
description: Pipeline for parsing Salesforce Login (Streaming) logs
processors:
- set:
field: event.ingested
value: '{{_ingest.timestamp}}'
- remove:
field:
- message
ignore_missing: true
- set:
field: salesforce.access_mode
value: stream
ignore_failure: true
- date:
field: json.EventDate
target_field: "@timestamp"
formats:
- ISO8601
ignore_failure: true
- rename:
field: json.schema
target_field: salesforce.login.schema
ignore_missing: true
- rename:
field: json.ApiType
target_field: salesforce.login.api_type
ignore_missing: true
- rename:
field: json.AuthMethodReference
target_field: salesforce.login.auth_method_reference
ignore_missing: true
- rename:
field: json.LoginType
target_field: salesforce.login.login_type
ignore_missing: true
- rename:
field: json.PolicyOutcome
target_field: salesforce.login.policy_outcome
ignore_missing: true
- rename:
field: json.AuthServiceId
target_field: salesforce.login.auth_service_id
ignore_missing: true
- rename:
field: json.EvaluationTime
target_field: salesforce.login.evaluation_time
ignore_missing: true
- rename:
field: json.ClientVersion
target_field: salesforce.login.client_version
ignore_missing: true
- rename:
field: json.LoginGeoId
target_field: salesforce.login.login_geo_id
ignore_missing: true
- rename:
field: json.LoginHistoryId
target_field: salesforce.login.login_history_id
ignore_missing: true
- rename:
field: json.CreatedById
target_field: salesforce.login.created_by_id
ignore_missing: true
- rename:
field: json.ApiVersion
target_field: salesforce.login.api_version
ignore_missing: true
- rename:
field: json.RelatedEventIdentifier
target_field: salesforce.login.related_event_identifier
ignore_missing: true
- rename:
field: json.LoginKey
target_field: salesforce.login.login_key
ignore_missing: true
- rename:
field: json.Application
target_field: salesforce.login.application
ignore_missing: true
- rename:
field: json.PolicyId
target_field: salesforce.login.policy_id
ignore_missing: true
- rename:
field: json.SessionLevel
target_field: salesforce.login.session_level
ignore_missing: true
- rename:
field: json.replayId
target_field: salesforce.login.replay_id
ignore_missing: true
#######################
## ECS Event Mapping ##
#######################
- set:
field: event.outcome
value: success
if: 'ctx?.json?.Status == "Success" && ctx?.json?.Status != null'
ignore_failure: true
- set:
field: event.outcome
value: failure
if: 'ctx?.json?.Status != "Success" && ctx?.json?.Status != null'
ignore_failure: true
- date:
field: json.CreatedDate
target_field: event.created
formats:
- ISO8601
ignore_failure: true
- rename:
field: json.LoginUrl
target_field: event.url
ignore_missing: true
- set:
field: event.type
value: "info"
- set:
field: event.kind
value: "event"
- set:
field: event.action
value: "login-attempt"
- set:
field: event.category
value: "authentication"
- set:
field: event.dataset
value: "salesforce.login"
- set:
field: event.module
value: "salesforce"
######################
## ECS User Mapping ##
######################
# As per the following article, the username must be in the format of an email address.
# Reference: https://help.salesforce.com/s/articleView?language=en_US&type=5&id=sf.basics_intro_usernames_passwords.htm
- rename:
field: json.Username
target_field: user.email
ignore_missing: true
- rename:
field: json.UserId
target_field: user.id
ignore_missing: true
- rename:
field: json.UserType
target_field: user.roles
ignore_missing: true
########################
## ECS Source Mapping ##
########################
- rename:
field: json.SourceIp
target_field: source.ip
ignore_missing: true
############################
## ECS Related.ip Mapping ##
############################
- append:
field: related.ip
value: "{{{source.ip}}}"
if: ctx?.source?.ip != null
allow_duplicates: false
ignore_failure: true
############################
## ECS Source.Geo Mapping ##
############################
- rename:
field: json.LoginLatitude
target_field: source.geo.location.lat
ignore_missing: true
- rename:
field: json.LoginLongitude
target_field: source.geo.location.lon
ignore_missing: true
- rename:
field: json.CountryIso
target_field: source.geo.country_iso_code
ignore_missing: true
- rename:
field: json.PostalCode
target_field: source.geo.postal_code
ignore_missing: true
- rename:
field: json.City
target_field: source.geo.city_name
ignore_missing: true
- rename:
field: json.Subdivision
target_field: source.geo.region_name
ignore_missing: true
- rename:
field: json.Country
target_field: source.geo.country_name
ignore_missing: true
############################
## ECS User Agent Mapping ##
############################
- rename:
field: json.Browser
target_field: user_agent.name
ignore_missing: true
- rename:
field: json.Platform
target_field: user_agent.os.platform
ignore_missing: true
######################
## ECS HTTP Mapping ##
######################
- rename:
field: json.HttpMethod
target_field: http.request.method
ignore_missing: true
- rename:
field: json.AdditionalInfo
target_field: http.request.body.content
ignore_missing: true
#####################
## ECS TLS Mapping ##
#####################
- rename:
field: json.CipherSuite
target_field: tls.cipher
ignore_missing: true
- dissect:
pattern: "%{tls.version_protocol} %{tls.version}"
field: "json.TlsProtocol"
ignore_failure: true
#############
## Cleanup ##
#############
- script:
description: Drops null/empty values recursively
lang: painless
source: |
boolean dropEmptyFields(Object object) {
if (object == null || object == "") {
return true;
} else if (object instanceof Map) {
((Map) object).values().removeIf(value -> dropEmptyFields(value));
return (((Map) object).size() == 0);
} else if (object instanceof List) {
((List) object).removeIf(value -> dropEmptyFields(value));
return (((List) object).length == 0);
}
return false;
}
dropEmptyFields(ctx);
- remove:
field:
- json
ignore_missing: true
on_failure:
- set:
field: error.message
value: '{{_ingest.on_failure_message}}'