diff --git a/packages/salesforce/_dev/build/docs/README.md b/packages/salesforce/_dev/build/docs/README.md index f011cc19697..61a2f327236 100644 --- a/packages/salesforce/_dev/build/docs/README.md +++ b/packages/salesforce/_dev/build/docs/README.md @@ -13,13 +13,13 @@ As an example, users can use the data from this integration to understand the ac ## Data streams -The Salesforce integration collects log events using the REST API of Salesforce. +The Salesforce integration collects log events using the REST API and Streaming API of Salesforce. **Logs** help users to keep a record of events happening in Salesforce. -Log data streams collected by the Salesforce integration include [Login](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_login.htm), [Logout](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_logout.htm), [Apex](https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_objects_apexclass.htm) and [SetupAuditTrail](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_setupaudittrail.htm). +Log data streams collected by the Salesforce integration include [Login REST](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_login.htm), [Login Stream](https://developer.salesforce.com/docs/atlas.en-us.236.0.platform_events.meta/platform_events/sforce_api_objects_logineventstream.htm), [Logout REST](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_logout.htm), [Apex](https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_objects_apexclass.htm) and [SetupAuditTrail](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_setupaudittrail.htm). Data streams: -- `login_rest`: Tracks login activity of users who log in to Salesforce. +- `login_rest` and `login_stream`: Tracks login activity of users who log in to Salesforce. - `logout_rest`: Tracks logout activity of users who logout from Salesforce. - `apex`: Represents information about various Apex events like Callout, Execution, REST API, SOAP API, Trigger, etc. - `setupaudittrail`: Represents changes users made in the user's organization's Setup area for at least the last 180 days. @@ -69,7 +69,20 @@ In the user's Salesforce instance, ensure that `API Enabled permission` is selec 2. Click on the profile link associated with the `User Account` used for data collection. 3. Search for `API Enabled` permission on the same page. In case it’s not present, search it under `System Permissions` and check if `API Enabled` privilege is selected. If not, enable it for data collection. -## Set Up +For collecting data using `Streaming API`: + +In the user's Salesforce instance, ensure that `View Real-Time Event Monitoring Data` is selected for the user profile. Follow the below steps to enable the same: + +1. Go to `Setup` > `Quick Find` > `Users`, and Click on `Users`. +2. Click on the profile link associated with the `User Account` used for data collection. +3. Search for `View Real-Time Event Monitoring Data` permission on the same page. In case it’s not present, search it under `System Permissions` and check if `View Real-Time Event Monitoring Data` privilege is selected. If not, enable it for data collection. + +Also ensure that `Event Streaming` is enabled for `Login Event` and `Logout Event`. Follow the below steps to enable the same: + +1. Go to `Setup` > `Quick Find` > `Event Manager`, and Click on `Event Manager`. +2. For `Login Event` and `Logout Event` click on the down arrow button on the left corner and select `Enable Streaming`. + +## Setup For step-by-step instructions on how to set up an integration, see the [Getting started](https://www.elastic.co/guide/en/welcome-to-elastic/current/getting-started-observability.html) guide. @@ -179,6 +192,14 @@ This is the `login_rest` data stream. It represents events containing details ab {{fields "login_rest"}} +### Login Stream + +This is the `login_stream` data stream. It represents events containing details about the user's organization's login history. + +{{event "login_stream"}} + +{{fields "login_stream"}} + ### Logout Rest This is the `logout_rest` data stream. It represents events containing details about the user's organization's logout history. diff --git a/packages/salesforce/_dev/deploy/docker/files/config.yml b/packages/salesforce/_dev/deploy/docker/files/config.yml index 461757fd10a..8dac57f0893 100644 --- a/packages/salesforce/_dev/deploy/docker/files/config.yml +++ b/packages/salesforce/_dev/deploy/docker/files/config.yml @@ -5,7 +5,7 @@ rules: - status_code: 200 headers: content-type: ['application/json'] - body: '{"access_token":"access_token","instance_url":"https://temporary-intance-url","id":"https://login.salesforce.com/id/temp_id/temp_token","token_type":"Bearer","issued_at":"1633689089545","signature":"signature"}' + body: '{"access_token":"access_token","instance_url":"http://{{ hostname }}:{{ env "PORT" }}","id":"https://login.salesforce.com/id/temp_id/temp_token","token_type":"Bearer","issued_at":"1633689089545","signature":"signature"}' - path: /services/data/v54.0/query methods: ["GET"] query_params: @@ -69,3 +69,43 @@ rules: body: |- "EVENT_TYPE","TIMESTAMP","REQUEST_ID","ORGANIZATION_ID","USER_ID","RUN_TIME","CPU_TIME","URI","SESSION_KEY","LOGIN_KEY","TYPE","METHOD","SUCCESS","TIME","REQUEST_SIZE","RESPONSE_SIZE","URL","TIMESTAMP_DERIVED","USER_ID_DERIVED","CLIENT_IP","URI_ID_DERIVED" "ApexCallout","20221122044615.591","4exLFFQZ1234xFl1cJNwOV","00D5j000000001V","0055j0000000001","1305","10","CALLOUT-LOG","WvtsJ1235oW24EbH","Obv9123BzbaxqCo1","OData","GET","1","1293","10","256","https://temp.sh/odata/Accounts","2022-11-22T04:46:15.591Z","0055j012345utlPAAQ","81.2.69.142","0055j000000utlPAQZB" + - path: /cometd/38.0 + methods: ["POST"] + request_body: '{"channel": "/meta/handshake", "supportedConnectionTypes": ["long-polling"], "version": "1.0"}' + responses: + - status_code: 200 + body: | + [{"ext":{"replay":true,"payload.format":true},"minimumVersion":"1.0","clientId":"temp_client_id","supportedConnectionTypes":["long-polling"],"channel":"/meta/handshake","version":"1.0","successful":true}] + - path: /cometd/38.0 + methods: ["POST"] + request_body: '{"channel": "/meta/connect", "connectionType": "long-polling", "clientId": "temp_client_id"} ' + responses: + - status_code: 200 + body: | + [{"data": {"payload": { "EventDate": "2022-12-28T11:47:22Z", "AuthServiceId": "06af6d92deqFAwqDaS", "CountryIso": "IN", "Platform": "Unknown", "EvaluationTime": 0.0, "CipherSuite": "ECDHE-RSA-AES256-GCM-SHA384", "PostalCode": "395007", "ClientVersion": "N/A", "LoginGeoId": "04F5j00000FadrI", "LoginUrl": "login.salesforce.com", "LoginHistoryId": "0Ya5j00000GLxCdCAL", "CreatedById": "0055j000000q9s7AAA", "SessionKey": "vMASKIU6AxEr+Op5", "ApiType": "N/A", "AuthMethodReference": "RFC 8176", "LoginType": "Remote Access 2.0", "PolicyOutcome": "Notified", "Status": "Success", "AdditionalInfo": "{}", "ApiVersion": "N/A", "EventIdentifier": "06af6d92-1167-467d-a826-ee8583f7134d", "RelatedEventIdentifier": "bd76f3e7-9ee5-4400-9e7f-54de57ecd79c", "LoginLatitude": 21.1888, "City": "Surat", "Subdivision": "Gujarat", "SourceIp": "81.2.69.142", "Username": "user@elastic.co", "UserId": "0055j000000utlPAAQ", "CreatedDate": "2022-12-28T11:47:30Z", "Country": "India", "LoginLongitude": 72.8293, "TlsProtocol": "TLS 1.2", "LoginKey": "o3vhFaSRBb0OzpCl", "Application": "elastic integration", "UserType": "Standard", "PolicyId": "0NIB000000000KOOAY", "HttpMethod": "POST", "SessionLevel": "STANDARD", "Browser": "Unknown" }, "event": {"replayId":1234}}, "channel": "/event/LoginEventStream"}] + - path: /cometd/38.0 + methods: ["POST"] + responses: + - status_code: 200 + body: | + [{"clientId": "temp_client_id", "channel": "/meta/subscribe", "subscription": "/event/LoginEventStream", "successful":true}] + - path: /cometd/38.0 + methods: ["POST"] + request_body: '{"channel": "/meta/handshake", "supportedConnectionTypes": ["long-polling"], "version": "1.0"}' + responses: + - status_code: 200 + body: | + [{"ext":{"replay":true,"payload.format":true},"minimumVersion":"1.0","clientId":"temp_client_id_1","supportedConnectionTypes":["long-polling"],"channel":"/meta/handshake","version":"1.0","successful":true}] + - path: /cometd/38.0 + methods: ["POST"] + responses: + - status_code: 200 + body: | + [{"clientId": "temp_client_id_1", "channel": "/meta/subscribe", "subscription": "/event/LogoutEventStream", "successful":true}] + - path: /cometd/38.0 + methods: ["POST"] + request_body: '{"channel": "/meta/connect", "connectionType": "long-polling", "clientId": "temp_client_id_1"} ' + responses: + - status_code: 200 + body: | + [{ "data": { "schema": "KvR3_Gn5cwCA8TYgASeP_A", "payload": { "EventDate": "2022-12-29T11:38:54Z", "EventIdentifier": "06ce4a9d-8d6b-4a71-aad8-04d28c9a43df", "SourceIp": "81.2.69.142", "CreatedById": "0055j000000q9s7AAA", "Username": "user@elastic.co", "UserId": "0055j000000utlPAAQ", "RelatedEventIdentifier": null, "SessionKey": "6/HAElgoPCwskqBU", "CreatedDate": "2022-12-29T11:38:54Z", "LoginKey": "CuRVtbMjat6xxbTH", "SessionLevel": "STANDARD" }, "event": { "replayId": 14168970 } }, "channel": "/event/LogoutEventStream" }] diff --git a/packages/salesforce/changelog.yml b/packages/salesforce/changelog.yml index 256fbd9d4ef..ea941edd931 100644 --- a/packages/salesforce/changelog.yml +++ b/packages/salesforce/changelog.yml @@ -1,4 +1,9 @@ # newer versions go on top +- version: 0.6.0 + changes: + - description: Salesforce integration package with "login_stream" data stream. + link: https://github.com/elastic/integrations/pull/4941 + type: enhancement - version: 0.5.0 changes: - description: Migrate visualizations to lens. diff --git a/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-common-config.yml b/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-common-config.yml new file mode 100644 index 00000000000..5622947e4b8 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-common-config.yml @@ -0,0 +1,5 @@ +dynamic_fields: + event.ingested: ".*" +fields: + tags: + - preserve_original_event diff --git a/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-login-stream.log b/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-login-stream.log new file mode 100644 index 00000000000..9ffcb429691 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-login-stream.log @@ -0,0 +1 @@ +{ "EventDate": "2022-12-28T11:47:22Z", "AuthServiceId": "06af6d92deqFAwqDaS", "CountryIso": "IN", "Platform": "Unknown", "EvaluationTime": 0.0, "CipherSuite": "ECDHE-RSA-AES256-GCM-SHA384", "PostalCode": "395007", "ClientVersion": "N/A", "LoginGeoId": "04F5j00000FadrI", "LoginUrl": "login.salesforce.com", "LoginHistoryId": "0Ya5j00000GLxCdCAL", "CreatedById": "0055j000000q9s7AAA", "SessionKey": "vMASKIU6AxEr+Op5", "ApiType": "N/A", "AuthMethodReference": "RFC 8176", "LoginType": "Remote Access 2.0", "PolicyOutcome": "Notified", "Status": "Success", "AdditionalInfo": "{}", "ApiVersion": "N/A", "EventIdentifier": "06af6d92-1167-467d-a826-ee8583f7134d", "RelatedEventIdentifier": "bd76f3e7-9ee5-4400-9e7f-54de57ecd79c", "LoginLatitude": 21.1888, "City": "Surat", "Subdivision": "Gujarat", "SourceIp": "81.2.69.142", "Username": "user@elastic.co", "UserId": "0055j000000utlPAAQ", "CreatedDate": "2022-12-28T11:47:30Z", "Country": "India", "LoginLongitude": 72.8293, "TlsProtocol": "TLS 1.2", "LoginKey": "o3vhFaSRBb0OzpCl", "Application": "elastic integration", "UserType": "Standard", "PolicyId": "0NIB000000000KOOAY", "HttpMethod": "POST", "SessionLevel": "STANDARD", "Browser": "Unknown" } \ No newline at end of file diff --git a/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-login-stream.log-expected.json b/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-login-stream.log-expected.json new file mode 100644 index 00000000000..bb9f9199042 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/_dev/test/pipeline/test-login-stream.log-expected.json @@ -0,0 +1,100 @@ +{ + "expected": [ + { + "@timestamp": "2022-12-28T11:47:22.000Z", + "ecs": { + "version": "8.5.0" + }, + "event": { + "action": "login-attempt", + "category": [ + "authentication" + ], + "created": "2022-12-28T11:47:30.000Z", + "dataset": "salesforce.login_stream", + "id": "06af6d92-1167-467d-a826-ee8583f7134d", + "kind": "event", + "module": "salesforce", + "original": "{ \"EventDate\": \"2022-12-28T11:47:22Z\", \"AuthServiceId\": \"06af6d92deqFAwqDaS\", \"CountryIso\": \"IN\", \"Platform\": \"Unknown\", \"EvaluationTime\": 0.0, \"CipherSuite\": \"ECDHE-RSA-AES256-GCM-SHA384\", \"PostalCode\": \"395007\", \"ClientVersion\": \"N/A\", \"LoginGeoId\": \"04F5j00000FadrI\", \"LoginUrl\": \"login.salesforce.com\", \"LoginHistoryId\": \"0Ya5j00000GLxCdCAL\", \"CreatedById\": \"0055j000000q9s7AAA\", \"SessionKey\": \"vMASKIU6AxEr+Op5\", \"ApiType\": \"N/A\", \"AuthMethodReference\": \"RFC 8176\", \"LoginType\": \"Remote Access 2.0\", \"PolicyOutcome\": \"Notified\", \"Status\": \"Success\", \"AdditionalInfo\": \"{}\", \"ApiVersion\": \"N/A\", \"EventIdentifier\": \"06af6d92-1167-467d-a826-ee8583f7134d\", \"RelatedEventIdentifier\": \"bd76f3e7-9ee5-4400-9e7f-54de57ecd79c\", \"LoginLatitude\": 21.1888, \"City\": \"Surat\", \"Subdivision\": \"Gujarat\", \"SourceIp\": \"81.2.69.142\", \"Username\": \"user@elastic.co\", \"UserId\": \"0055j000000utlPAAQ\", \"CreatedDate\": \"2022-12-28T11:47:30Z\", \"Country\": \"India\", \"LoginLongitude\": 72.8293, \"TlsProtocol\": \"TLS 1.2\", \"LoginKey\": \"o3vhFaSRBb0OzpCl\", \"Application\": \"elastic integration\", \"UserType\": \"Standard\", \"PolicyId\": \"0NIB000000000KOOAY\", \"HttpMethod\": \"POST\", \"SessionLevel\": \"STANDARD\", \"Browser\": \"Unknown\" }", + "outcome": "success", + "type": [ + "info" + ], + "url": "login.salesforce.com" + }, + "http": { + "request": { + "body": { + "content": "{}" + }, + "method": "POST" + } + }, + "related": { + "ip": [ + "81.2.69.142" + ] + }, + "salesforce": { + "login": { + "access_mode": "Stream", + "api": { + "type": "N/A", + "version": "N/A" + }, + "application": "elastic integration", + "auth": { + "method_reference": "RFC 8176", + "service_id": "06af6d92deqFAwqDaS" + }, + "client_version": "N/A", + "evaluation_time": 0.0, + "geo_id": "04F5j00000FadrI", + "history_id": "0Ya5j00000GLxCdCAL", + "key": "o3vhFaSRBb0OzpCl", + "policy_id": "0NIB000000000KOOAY", + "policy_outcome": "Notified", + "related_event_identifier": "bd76f3e7-9ee5-4400-9e7f-54de57ecd79c", + "session": { + "key": "vMASKIU6AxEr+Op5", + "level": "STANDARD" + }, + "type": "Remote Access 2.0" + } + }, + "source": { + "geo": { + "city_name": "Surat", + "country_iso_code": "IN", + "country_name": "India", + "location": { + "lat": 21.1888, + "lon": 72.8293 + }, + "postal_code": "395007", + "region_name": "Gujarat" + }, + "ip": "81.2.69.142" + }, + "tags": [ + "preserve_original_event" + ], + "tls": { + "cipher": "ECDHE-RSA-AES256-GCM-SHA384", + "version": "1.2", + "version_protocol": "TLS" + }, + "user": { + "email": "user@elastic.co", + "id": "0055j000000utlPAAQ", + "roles": "Standard" + }, + "user_agent": { + "name": "Unknown", + "os": { + "platform": "Unknown" + } + } + } + ] +} \ No newline at end of file diff --git a/packages/salesforce/data_stream/login_stream/_dev/test/system/test-default-config.yml b/packages/salesforce/data_stream/login_stream/_dev/test/system/test-default-config.yml new file mode 100644 index 00000000000..79ac54ebd62 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/_dev/test/system/test-default-config.yml @@ -0,0 +1,11 @@ +service: salesforce +vars: + client_id: temp_client_id + client_secret: forty_characters_long_secret_key + username: temp_user + password: temp_password + token_url: http://{{Hostname}}:{{Port}}/services/oauth2/token +input: cometd +data_stream: + vars: + preserve_original_event: true diff --git a/packages/salesforce/data_stream/login_stream/agent/stream/cometd.yml.hbs b/packages/salesforce/data_stream/login_stream/agent/stream/cometd.yml.hbs new file mode 100644 index 00000000000..bcc96c92f5c --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/agent/stream/cometd.yml.hbs @@ -0,0 +1,27 @@ +type: cometd +channel_name: /event/LoginEventStream +auth.oauth2: + enabled: true + client.id: {{client_id}} + client.secret: {{client_secret}} + token_url: {{token_url}} + user: {{username}} + password: {{password}} +tags: +{{#if preserve_original_event}} + - preserve_original_event +{{/if}} +{{#each tags as |tag|}} + - {{tag}} +{{/each}} +{{#contains "forwarded" tags}} +publisher_pipeline.disable_host: true +{{/contains}} +processors: +- add_fields: + target: salesforce + fields: + instance_url: {{instance_url}} +{{#if processors}} +{{processors}} +{{/if}} diff --git a/packages/salesforce/data_stream/login_stream/elasticsearch/ingest_pipeline/default.yml b/packages/salesforce/data_stream/login_stream/elasticsearch/ingest_pipeline/default.yml new file mode 100644 index 00000000000..fb0c75f8956 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/elasticsearch/ingest_pipeline/default.yml @@ -0,0 +1,305 @@ +--- +description: Pipeline for parsing Salesforce Login (Streaming) logs. +processors: +- json: + field: message + target_field: json + ignore_failure: true +- set: + field: event.original + value: '{{{message}}}' + ignore_failure: true + ignore_empty_value: true +- set: + field: salesforce.login.access_mode + value: Stream + ignore_failure: true + ignore_empty_value: true +- set: + field: ecs.version + value: 8.5.0 + ignore_failure: true + ignore_empty_value: true +- date: + field: json.EventDate + target_field: "@timestamp" + formats: + - ISO8601 + ignore_failure: true +- rename: + field: json.AuthServiceId + target_field: salesforce.login.auth.service_id + ignore_failure: true + ignore_missing: true +- convert: + field: json.EvaluationTime + type: float + target_field: salesforce.login.evaluation_time + ignore_failure: true + ignore_missing: true +- rename: + field: json.ClientVersion + target_field: salesforce.login.client_version + ignore_failure: true + ignore_missing: true +- rename: + field: cometd.channel_name + target_field: salesforce.login.channel_name + ignore_failure: true + ignore_missing: true +- rename: + field: json.LoginGeoId + target_field: salesforce.login.geo_id + ignore_failure: true + ignore_missing: true +- rename: + field: json.LoginHistoryId + target_field: salesforce.login.history_id + ignore_failure: true + ignore_missing: true +- rename: + field: json.ApiType + target_field: salesforce.login.api.type + ignore_failure: true + ignore_missing: true +- rename: + field: json.AuthMethodReference + target_field: salesforce.login.auth.method_reference + ignore_failure: true + ignore_missing: true +- rename: + field: json.LoginType + target_field: salesforce.login.type + ignore_failure: true + ignore_missing: true +- rename: + field: json.PolicyOutcome + target_field: salesforce.login.policy_outcome + ignore_failure: true + ignore_missing: true +- rename: + field: json.ApiVersion + target_field: salesforce.login.api.version + ignore_failure: true + ignore_missing: true +- rename: + field: json.EventIdentifier + target_field: event.id + ignore_failure: true + ignore_missing: true +- rename: + field: json.RelatedEventIdentifier + target_field: salesforce.login.related_event_identifier + ignore_failure: true + ignore_missing: true +- rename: + field: json.LoginKey + target_field: salesforce.login.key + ignore_failure: true + ignore_missing: true +- rename: + field: json.Application + target_field: salesforce.login.application + ignore_failure: true + ignore_missing: true +- rename: + field: json.PolicyId + target_field: salesforce.login.policy_id + ignore_failure: true + ignore_missing: true +- rename: + field: json.SessionLevel + target_field: salesforce.login.session.level + ignore_failure: true + ignore_missing: true +- rename: + field: json.SessionKey + target_field: salesforce.login.session.key + ignore_failure: true + ignore_missing: true +- set: + field: event.outcome + value: success + if: 'ctx?.json?.Status == "Success" && ctx?.json?.Status != null' + ignore_failure: true + ignore_empty_value: true +- set: + field: event.outcome + value: failure + if: 'ctx?.json?.Status != "Success" && ctx?.json?.Status != null' + ignore_failure: true + ignore_empty_value: true +- date: + field: json.CreatedDate + target_field: event.created + formats: + - ISO8601 + ignore_failure: true +- rename: + field: json.LoginUrl + target_field: event.url + ignore_failure: true + ignore_missing: true +- set: + field: event.type + value: [info] + ignore_failure: true + ignore_empty_value: true +- set: + field: event.kind + value: event + ignore_failure: true + ignore_empty_value: true +- set: + field: event.action + value: login-attempt + ignore_failure: true + ignore_empty_value: true +- set: + field: event.category + value: [authentication] + ignore_failure: true + ignore_empty_value: true +- set: + field: event.dataset + value: salesforce.login_stream + ignore_failure: true + ignore_empty_value: true +- set: + field: event.module + value: salesforce + ignore_failure: true + ignore_empty_value: true +- rename: + field: json.Username + target_field: user.email + ignore_failure: true + ignore_missing: true +- rename: + field: json.UserId + target_field: user.id + ignore_failure: true + ignore_missing: true +- rename: + field: json.UserType + target_field: user.roles + ignore_failure: true + ignore_missing: true +- convert: + field: json.SourceIp + type: ip + target_field: source.ip + ignore_missing: true + ignore_failure: true +- append: + field: related.ip + value: '{{{source.ip}}}' + if: ctx?.source?.ip != null + allow_duplicates: false + ignore_failure: true +- rename: + field: json.LoginLatitude + target_field: source.geo.location.lat + ignore_failure: true + ignore_missing: true +- rename: + field: json.LoginLongitude + target_field: source.geo.location.lon + ignore_failure: true + ignore_missing: true +- geoip: + field: source.ip + target_field: source.geo + ignore_missing: true + if: '!ctx.source?.geo?.location?.containsKey("lat") && !ctx.source?.geo?.location?.containsKey("lon")' +- rename: + field: json.CountryIso + target_field: source.geo.country_iso_code + ignore_failure: true + ignore_missing: true +- rename: + field: json.PostalCode + target_field: source.geo.postal_code + ignore_failure: true + ignore_missing: true +- rename: + field: json.City + target_field: source.geo.city_name + ignore_failure: true + ignore_missing: true +- rename: + field: json.Subdivision + target_field: source.geo.region_name + ignore_failure: true + ignore_missing: true +- rename: + field: json.Country + target_field: source.geo.country_name + ignore_failure: true + ignore_missing: true +- rename: + field: json.Browser + target_field: user_agent.name + ignore_failure: true + ignore_missing: true +- rename: + field: json.Platform + target_field: user_agent.os.platform + ignore_failure: true + ignore_missing: true +- rename: + field: json.HttpMethod + target_field: http.request.method + ignore_failure: true + ignore_missing: true +- rename: + field: json.AdditionalInfo + target_field: http.request.body.content + ignore_failure: true + ignore_missing: true +- rename: + field: json.CipherSuite + target_field: tls.cipher + ignore_failure: true + ignore_missing: true +- dissect: + pattern: "%{tls.version_protocol} %{tls.version}" + field: json.TlsProtocol + ignore_failure: true + ignore_missing: true +- remove: + field: event.original + if: "ctx.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true +- 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 + - message + ignore_failure: true + ignore_missing: true +on_failure: +- set: + field: error.message + value: '{{_ingest.on_failure_message}}' +- append: + field: event.kind + value: pipeline_error + allow_duplicates: false diff --git a/packages/salesforce/data_stream/login_stream/fields/base-fields.yml b/packages/salesforce/data_stream/login_stream/fields/base-fields.yml new file mode 100644 index 00000000000..3500f7ce8c2 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/fields/base-fields.yml @@ -0,0 +1,15 @@ +- name: data_stream.type + type: constant_keyword + description: Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: Data stream namespace. +- name: input.type + type: keyword + description: Input type. +- name: '@timestamp' + type: date + description: Event timestamp. diff --git a/packages/salesforce/data_stream/login_stream/fields/ecs.yml b/packages/salesforce/data_stream/login_stream/fields/ecs.yml new file mode 100644 index 00000000000..4dbe7e043f0 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/fields/ecs.yml @@ -0,0 +1,68 @@ +- external: ecs + name: ecs.version +- external: ecs + name: event.action +- external: ecs + name: event.agent_id_status +- external: ecs + name: event.category +- external: ecs + name: event.created +- external: ecs + name: event.dataset +- external: ecs + name: event.ingested +- external: ecs + name: event.kind +- external: ecs + name: event.module +- external: ecs + name: event.original +- external: ecs + name: event.outcome +- external: ecs + name: event.type +- external: ecs + name: event.url +- external: ecs + name: http.request.body.content +- external: ecs + name: http.request.method +- external: ecs + name: related.ip +- external: ecs + name: source.geo.city_name +- external: ecs + name: source.geo.continent_name +- external: ecs + name: source.geo.country_iso_code +- external: ecs + name: source.geo.country_name +- external: ecs + name: source.geo.location +- external: ecs + name: source.geo.postal_code +- external: ecs + name: source.geo.region_iso_code +- external: ecs + name: source.geo.region_name +- external: ecs + name: source.ip +- external: ecs + name: tags +- external: ecs + name: tls.cipher +- external: ecs + name: tls.version +- external: ecs + name: tls.version_protocol +- external: ecs + name: user.email +- external: ecs + name: user.id +- external: ecs + name: user.roles +- external: ecs + name: user_agent.name +- external: ecs + name: user_agent.os.platform diff --git a/packages/salesforce/data_stream/login_stream/fields/fields.yml b/packages/salesforce/data_stream/login_stream/fields/fields.yml new file mode 100644 index 00000000000..9a797f50254 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/fields/fields.yml @@ -0,0 +1,74 @@ +- name: salesforce + type: group + fields: + - name: instance_url + type: keyword + description: The Instance URL of the Salesforce instance. + - name: login + type: group + fields: + - name: access_mode + type: keyword + description: The mode of collecting logs from Salesforce - "REST" or "Stream". + - name: api + type: group + fields: + - name: type + type: keyword + description: The type of API that's used to login. + - name: version + type: keyword + description: The version number of the API. If no version number is available, "Unknown" is returned. + - name: application + type: keyword + description: The application used to access the organization. + - name: auth + type: group + fields: + - name: method_reference + type: keyword + description: The authentication method used by a third-party identification provider for an OpenID Connect single sign-on protocol. + - name: service_id + type: keyword + description: The 18-character ID for an authentication service for a login event. + - name: channel_name + type: keyword + description: The Salesforce generic subscription Push Topic name. + - name: client_version + type: keyword + description: The version number of the login client. If no version number is available, "Unknown" is returned. + - name: evaluation_time + type: float + description: The amount of time it took to evaluate the transaction security policy, in milliseconds. + metric_type: gauge + unit: ms + - name: geo_id + type: keyword + description: The Salesforce ID of the geolocation information associated with the login user's IP address. + - name: history_id + type: keyword + description: Tracks a user session so you can correlate user activity with a particular login instance. + - name: key + type: keyword + description: The string that ties together all events in a given user's login session. The session starts with a login event and ends with either a logout event or the user session expiring. + - name: policy_id + type: keyword + description: The ID of the transaction security policy associated with this event. + - name: policy_outcome + type: keyword + description: The result of the transaction policy. + - name: related_event_identifier + type: keyword + description: Represents the EventIdentifier of the related event. + - name: session + type: group + fields: + - name: key + type: keyword + description: The user's unique session ID. Use this value to identify all user events within a session. When a user logs out and logs in again, a new session is started. + - name: level + type: keyword + description: Session-level security controls user access to features that support it, such as connected apps and reporting. + - name: type + type: keyword + description: The type of login used to access the session. diff --git a/packages/salesforce/data_stream/login_stream/manifest.yml b/packages/salesforce/data_stream/login_stream/manifest.yml new file mode 100644 index 00000000000..38526532070 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/manifest.yml @@ -0,0 +1,32 @@ +type: logs +title: Salesforce login logs +streams: + - input: cometd + vars: + - name: tags + type: text + title: Tags + multi: true + required: true + show_user: false + default: + - salesforce-login_stream + - forwarded + - name: preserve_original_event + required: true + show_user: true + title: Preserve original event + description: Preserves a raw copy of the original event, added to the field `event.original`. + type: bool + multi: false + default: false + - name: processors + type: yaml + title: Processors + multi: false + required: false + show_user: false + description: Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details. + template_path: cometd.yml.hbs + title: Salesforce Login logs + description: Collect Salesforce Login logs. diff --git a/packages/salesforce/data_stream/login_stream/sample_event.json b/packages/salesforce/data_stream/login_stream/sample_event.json new file mode 100644 index 00000000000..0f5e47c7ba1 --- /dev/null +++ b/packages/salesforce/data_stream/login_stream/sample_event.json @@ -0,0 +1,122 @@ +{ + "@timestamp": "2022-12-28T11:47:22.000Z", + "agent": { + "ephemeral_id": "ec47b43f-2817-4784-8632-afcaef0577c0", + "id": "19ec90b1-6453-4383-97de-c2add7c43ab2", + "name": "docker-fleet-agent", + "type": "filebeat", + "version": "8.7.0" + }, + "data_stream": { + "dataset": "salesforce.login_stream", + "namespace": "ep", + "type": "logs" + }, + "ecs": { + "version": "8.5.0" + }, + "elastic_agent": { + "id": "19ec90b1-6453-4383-97de-c2add7c43ab2", + "snapshot": false, + "version": "8.7.0" + }, + "event": { + "action": "login-attempt", + "agent_id_status": "verified", + "category": [ + "authentication" + ], + "created": "2022-12-28T11:47:30.000Z", + "dataset": "salesforce.login_stream", + "id": "06af6d92-1167-467d-a826-ee8583f7134d", + "ingested": "2023-01-16T07:18:42Z", + "kind": "event", + "module": "salesforce", + "original": "{ \"EventDate\": \"2022-12-28T11:47:22Z\", \"AuthServiceId\": \"06af6d92deqFAwqDaS\", \"CountryIso\": \"IN\", \"Platform\": \"Unknown\", \"EvaluationTime\": 0.0, \"CipherSuite\": \"ECDHE-RSA-AES256-GCM-SHA384\", \"PostalCode\": \"395007\", \"ClientVersion\": \"N/A\", \"LoginGeoId\": \"04F5j00000FadrI\", \"LoginUrl\": \"login.salesforce.com\", \"LoginHistoryId\": \"0Ya5j00000GLxCdCAL\", \"CreatedById\": \"0055j000000q9s7AAA\", \"SessionKey\": \"vMASKIU6AxEr+Op5\", \"ApiType\": \"N/A\", \"AuthMethodReference\": \"RFC 8176\", \"LoginType\": \"Remote Access 2.0\", \"PolicyOutcome\": \"Notified\", \"Status\": \"Success\", \"AdditionalInfo\": \"{}\", \"ApiVersion\": \"N/A\", \"EventIdentifier\": \"06af6d92-1167-467d-a826-ee8583f7134d\", \"RelatedEventIdentifier\": \"bd76f3e7-9ee5-4400-9e7f-54de57ecd79c\", \"LoginLatitude\": 21.1888, \"City\": \"Surat\", \"Subdivision\": \"Gujarat\", \"SourceIp\": \"81.2.69.142\", \"Username\": \"user@elastic.co\", \"UserId\": \"0055j000000utlPAAQ\", \"CreatedDate\": \"2022-12-28T11:47:30Z\", \"Country\": \"India\", \"LoginLongitude\": 72.8293, \"TlsProtocol\": \"TLS 1.2\", \"LoginKey\": \"o3vhFaSRBb0OzpCl\", \"Application\": \"elastic integration\", \"UserType\": \"Standard\", \"PolicyId\": \"0NIB000000000KOOAY\", \"HttpMethod\": \"POST\", \"SessionLevel\": \"STANDARD\", \"Browser\": \"Unknown\" }", + "outcome": "success", + "type": [ + "info" + ], + "url": "login.salesforce.com" + }, + "http": { + "request": { + "body": { + "content": "{}" + }, + "method": "POST" + } + }, + "input": { + "type": "cometd" + }, + "related": { + "ip": [ + "81.2.69.142" + ] + }, + "salesforce": { + "instance_url": "https://instance-url.salesforce.com", + "login": { + "access_mode": "Stream", + "api": { + "type": "N/A", + "version": "N/A" + }, + "application": "elastic integration", + "auth": { + "method_reference": "RFC 8176", + "service_id": "06af6d92deqFAwqDaS" + }, + "channel_name": "/event/LoginEventStream", + "client_version": "N/A", + "evaluation_time": 0, + "geo_id": "04F5j00000FadrI", + "history_id": "0Ya5j00000GLxCdCAL", + "key": "o3vhFaSRBb0OzpCl", + "policy_id": "0NIB000000000KOOAY", + "policy_outcome": "Notified", + "related_event_identifier": "bd76f3e7-9ee5-4400-9e7f-54de57ecd79c", + "session": { + "key": "vMASKIU6AxEr+Op5", + "level": "STANDARD" + }, + "type": "Remote Access 2.0" + } + }, + "source": { + "geo": { + "city_name": "Surat", + "country_iso_code": "IN", + "country_name": "India", + "location": { + "lat": 21.1888, + "lon": 72.8293 + }, + "postal_code": "395007", + "region_name": "Gujarat" + }, + "ip": "81.2.69.142" + }, + "tags": [ + "preserve_original_event", + "salesforce-login_stream", + "forwarded" + ], + "tls": { + "cipher": "ECDHE-RSA-AES256-GCM-SHA384", + "version": "1.2", + "version_protocol": "TLS" + }, + "user": { + "email": "user@elastic.co", + "id": "0055j000000utlPAAQ", + "roles": "Standard" + }, + "user_agent": { + "name": "Unknown", + "os": { + "platform": "Unknown" + } + } +} \ No newline at end of file diff --git a/packages/salesforce/docs/README.md b/packages/salesforce/docs/README.md index 3125542a850..aabc633265d 100644 --- a/packages/salesforce/docs/README.md +++ b/packages/salesforce/docs/README.md @@ -13,13 +13,13 @@ As an example, users can use the data from this integration to understand the ac ## Data streams -The Salesforce integration collects log events using the REST API of Salesforce. +The Salesforce integration collects log events using the REST API and Streaming API of Salesforce. **Logs** help users to keep a record of events happening in Salesforce. -Log data streams collected by the Salesforce integration include [Login](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_login.htm), [Logout](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_logout.htm), [Apex](https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_objects_apexclass.htm) and [SetupAuditTrail](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_setupaudittrail.htm). +Log data streams collected by the Salesforce integration include [Login REST](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_login.htm), [Login Stream](https://developer.salesforce.com/docs/atlas.en-us.236.0.platform_events.meta/platform_events/sforce_api_objects_logineventstream.htm), [Logout REST](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_logout.htm), [Apex](https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_objects_apexclass.htm) and [SetupAuditTrail](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_setupaudittrail.htm). Data streams: -- `login_rest`: Tracks login activity of users who log in to Salesforce. +- `login_rest` and `login_stream`: Tracks login activity of users who log in to Salesforce. - `logout_rest`: Tracks logout activity of users who logout from Salesforce. - `apex`: Represents information about various Apex events like Callout, Execution, REST API, SOAP API, Trigger, etc. - `setupaudittrail`: Represents changes users made in the user's organization's Setup area for at least the last 180 days. @@ -69,7 +69,20 @@ In the user's Salesforce instance, ensure that `API Enabled permission` is selec 2. Click on the profile link associated with the `User Account` used for data collection. 3. Search for `API Enabled` permission on the same page. In case it’s not present, search it under `System Permissions` and check if `API Enabled` privilege is selected. If not, enable it for data collection. -## Set Up +For collecting data using `Streaming API`: + +In the user's Salesforce instance, ensure that `View Real-Time Event Monitoring Data` is selected for the user profile. Follow the below steps to enable the same: + +1. Go to `Setup` > `Quick Find` > `Users`, and Click on `Users`. +2. Click on the profile link associated with the `User Account` used for data collection. +3. Search for `View Real-Time Event Monitoring Data` permission on the same page. In case it’s not present, search it under `System Permissions` and check if `View Real-Time Event Monitoring Data` privilege is selected. If not, enable it for data collection. + +Also ensure that `Event Streaming` is enabled for `Login Event` and `Logout Event`. Follow the below steps to enable the same: + +1. Go to `Setup` > `Quick Find` > `Event Manager`, and Click on `Event Manager`. +2. For `Login Event` and `Logout Event` click on the down arrow button on the left corner and select `Enable Streaming`. + +## Setup For step-by-step instructions on how to set up an integration, see the [Getting started](https://www.elastic.co/guide/en/welcome-to-elastic/current/getting-started-observability.html) guide. @@ -531,6 +544,202 @@ An example event for `login_rest` looks as following: | user_agent.name | Name of the user agent. | keyword | | | +### Login Stream + +This is the `login_stream` data stream. It represents events containing details about the user's organization's login history. + +An example event for `login_stream` looks as following: + +```json +{ + "@timestamp": "2022-12-28T11:47:22.000Z", + "agent": { + "ephemeral_id": "ec47b43f-2817-4784-8632-afcaef0577c0", + "id": "19ec90b1-6453-4383-97de-c2add7c43ab2", + "name": "docker-fleet-agent", + "type": "filebeat", + "version": "8.7.0" + }, + "data_stream": { + "dataset": "salesforce.login_stream", + "namespace": "ep", + "type": "logs" + }, + "ecs": { + "version": "8.5.0" + }, + "elastic_agent": { + "id": "19ec90b1-6453-4383-97de-c2add7c43ab2", + "snapshot": false, + "version": "8.7.0" + }, + "event": { + "action": "login-attempt", + "agent_id_status": "verified", + "category": [ + "authentication" + ], + "created": "2022-12-28T11:47:30.000Z", + "dataset": "salesforce.login_stream", + "id": "06af6d92-1167-467d-a826-ee8583f7134d", + "ingested": "2023-01-16T07:18:42Z", + "kind": "event", + "module": "salesforce", + "original": "{ \"EventDate\": \"2022-12-28T11:47:22Z\", \"AuthServiceId\": \"06af6d92deqFAwqDaS\", \"CountryIso\": \"IN\", \"Platform\": \"Unknown\", \"EvaluationTime\": 0.0, \"CipherSuite\": \"ECDHE-RSA-AES256-GCM-SHA384\", \"PostalCode\": \"395007\", \"ClientVersion\": \"N/A\", \"LoginGeoId\": \"04F5j00000FadrI\", \"LoginUrl\": \"login.salesforce.com\", \"LoginHistoryId\": \"0Ya5j00000GLxCdCAL\", \"CreatedById\": \"0055j000000q9s7AAA\", \"SessionKey\": \"vMASKIU6AxEr+Op5\", \"ApiType\": \"N/A\", \"AuthMethodReference\": \"RFC 8176\", \"LoginType\": \"Remote Access 2.0\", \"PolicyOutcome\": \"Notified\", \"Status\": \"Success\", \"AdditionalInfo\": \"{}\", \"ApiVersion\": \"N/A\", \"EventIdentifier\": \"06af6d92-1167-467d-a826-ee8583f7134d\", \"RelatedEventIdentifier\": \"bd76f3e7-9ee5-4400-9e7f-54de57ecd79c\", \"LoginLatitude\": 21.1888, \"City\": \"Surat\", \"Subdivision\": \"Gujarat\", \"SourceIp\": \"81.2.69.142\", \"Username\": \"user@elastic.co\", \"UserId\": \"0055j000000utlPAAQ\", \"CreatedDate\": \"2022-12-28T11:47:30Z\", \"Country\": \"India\", \"LoginLongitude\": 72.8293, \"TlsProtocol\": \"TLS 1.2\", \"LoginKey\": \"o3vhFaSRBb0OzpCl\", \"Application\": \"elastic integration\", \"UserType\": \"Standard\", \"PolicyId\": \"0NIB000000000KOOAY\", \"HttpMethod\": \"POST\", \"SessionLevel\": \"STANDARD\", \"Browser\": \"Unknown\" }", + "outcome": "success", + "type": [ + "info" + ], + "url": "login.salesforce.com" + }, + "http": { + "request": { + "body": { + "content": "{}" + }, + "method": "POST" + } + }, + "input": { + "type": "cometd" + }, + "related": { + "ip": [ + "81.2.69.142" + ] + }, + "salesforce": { + "instance_url": "https://instance-url.salesforce.com", + "login": { + "access_mode": "Stream", + "api": { + "type": "N/A", + "version": "N/A" + }, + "application": "elastic integration", + "auth": { + "method_reference": "RFC 8176", + "service_id": "06af6d92deqFAwqDaS" + }, + "channel_name": "/event/LoginEventStream", + "client_version": "N/A", + "evaluation_time": 0, + "geo_id": "04F5j00000FadrI", + "history_id": "0Ya5j00000GLxCdCAL", + "key": "o3vhFaSRBb0OzpCl", + "policy_id": "0NIB000000000KOOAY", + "policy_outcome": "Notified", + "related_event_identifier": "bd76f3e7-9ee5-4400-9e7f-54de57ecd79c", + "session": { + "key": "vMASKIU6AxEr+Op5", + "level": "STANDARD" + }, + "type": "Remote Access 2.0" + } + }, + "source": { + "geo": { + "city_name": "Surat", + "country_iso_code": "IN", + "country_name": "India", + "location": { + "lat": 21.1888, + "lon": 72.8293 + }, + "postal_code": "395007", + "region_name": "Gujarat" + }, + "ip": "81.2.69.142" + }, + "tags": [ + "preserve_original_event", + "salesforce-login_stream", + "forwarded" + ], + "tls": { + "cipher": "ECDHE-RSA-AES256-GCM-SHA384", + "version": "1.2", + "version_protocol": "TLS" + }, + "user": { + "email": "user@elastic.co", + "id": "0055j000000utlPAAQ", + "roles": "Standard" + }, + "user_agent": { + "name": "Unknown", + "os": { + "platform": "Unknown" + } + } +} +``` + +**Exported fields** + +| Field | Description | Type | Unit | Metric Type | +|---|---|---|---|---| +| @timestamp | Event timestamp. | date | | | +| data_stream.dataset | Data stream dataset. | constant_keyword | | | +| data_stream.namespace | Data stream namespace. | constant_keyword | | | +| data_stream.type | Data stream type. | constant_keyword | | | +| ecs.version | ECS version this event conforms to. `ecs.version` is a required field and must exist in all events. When querying across multiple indices -- which may conform to slightly different ECS versions -- this field lets integrations adjust to the schema version of the events. | keyword | | | +| event.action | The action captured by the event. This describes the information in the event. It is more specific than `event.category`. Examples are `group-add`, `process-started`, `file-created`. The value is normally defined by the implementer. | keyword | | | +| event.agent_id_status | Agents are normally responsible for populating the `agent.id` field value. If the system receiving events is capable of validating the value based on authentication information for the client then this field can be used to reflect the outcome of that validation. For example if the agent's connection is authenticated with mTLS and the client cert contains the ID of the agent to which the cert was issued then the `agent.id` value in events can be checked against the certificate. If the values match then `event.agent_id_status: verified` is added to the event, otherwise one of the other allowed values should be used. If no validation is performed then the field should be omitted. The allowed values are: `verified` - The `agent.id` field value matches expected value obtained from auth metadata. `mismatch` - The `agent.id` field value does not match the expected value obtained from auth metadata. `missing` - There was no `agent.id` field in the event to validate. `auth_metadata_missing` - There was no auth metadata or it was missing information about the agent ID. | keyword | | | +| event.category | This is one of four ECS Categorization Fields, and indicates the second level in the ECS category hierarchy. `event.category` represents the "big buckets" of ECS categories. For example, filtering on `event.category:process` yields all events relating to process activity. This field is closely related to `event.type`, which is used as a subcategory. This field is an array. This will allow proper categorization of some events that fall in multiple categories. | keyword | | | +| event.created | event.created contains the date/time when the event was first read by an agent, or by your pipeline. This field is distinct from @timestamp in that @timestamp typically contain the time extracted from the original event. In most situations, these two timestamps will be slightly different. The difference can be used to calculate the delay between your source generating an event, and the time when your agent first processed it. This can be used to monitor your agent's or pipeline's ability to keep up with your event source. In case the two timestamps are identical, @timestamp should be used. | date | | | +| event.dataset | Name of the dataset. If an event source publishes more than one type of log or events (e.g. access log, error log), the dataset is used to specify which one the event comes from. It's recommended but not required to start the dataset name with the module name, followed by a dot, then the dataset name. | keyword | | | +| event.ingested | Timestamp when an event arrived in the central data store. This is different from `@timestamp`, which is when the event originally occurred. It's also different from `event.created`, which is meant to capture the first time an agent saw the event. In normal conditions, assuming no tampering, the timestamps should chronologically look like this: `@timestamp` \< `event.created` \< `event.ingested`. | date | | | +| event.kind | This is one of four ECS Categorization Fields, and indicates the highest level in the ECS category hierarchy. `event.kind` gives high-level information about what type of information the event contains, without being specific to the contents of the event. For example, values of this field distinguish alert events from metric events. The value of this field can be used to inform how these kinds of events should be handled. They may warrant different retention, different access control, it may also help understand whether the data coming in at a regular interval or not. | keyword | | | +| event.module | Name of the module this data is coming from. If your monitoring agent supports the concept of modules or plugins to process events of a given source (e.g. Apache logs), `event.module` should contain the name of this module. | keyword | | | +| event.original | Raw text message of entire event. Used to demonstrate log integrity or where the full log message (before splitting it up in multiple parts) may be required, e.g. for reindex. This field is not indexed and doc_values are disabled. It cannot be searched, but it can be retrieved from `_source`. If users wish to override this and index this field, please see `Field data types` in the `Elasticsearch Reference`. | keyword | | | +| event.outcome | This is one of four ECS Categorization Fields, and indicates the lowest level in the ECS category hierarchy. `event.outcome` simply denotes whether the event represents a success or a failure from the perspective of the entity that produced the event. Note that when a single transaction is described in multiple events, each event may populate different values of `event.outcome`, according to their perspective. Also note that in the case of a compound event (a single event that contains multiple logical events), this field should be populated with the value that best captures the overall success or failure from the perspective of the event producer. Further note that not all events will have an associated outcome. For example, this field is generally not populated for metric events, events with `event.type:info`, or any events for which an outcome does not make logical sense. | keyword | | | +| event.type | This is one of four ECS Categorization Fields, and indicates the third level in the ECS category hierarchy. `event.type` represents a categorization "sub-bucket" that, when used along with the `event.category` field values, enables filtering events down to a level appropriate for single visualization. This field is an array. This will allow proper categorization of some events that fall in multiple event types. | keyword | | | +| event.url | URL linking to an external system to continue investigation of this event. This URL links to another system where in-depth investigation of the specific occurrence of this event can take place. Alert events, indicated by `event.kind:alert`, are a common use case for this field. | keyword | | | +| http.request.body.content | The full HTTP request body. | wildcard | | | +| http.request.body.content.text | Multi-field of `http.request.body.content`. | match_only_text | | | +| http.request.method | HTTP request method. The value should retain its casing from the original event. For example, `GET`, `get`, and `GeT` are all considered valid values for this field. | keyword | | | +| input.type | Input type. | keyword | | | +| related.ip | All of the IPs seen on your event. | ip | | | +| salesforce.instance_url | The Instance URL of the Salesforce instance. | keyword | | | +| salesforce.login.access_mode | The mode of collecting logs from Salesforce - "REST" or "Stream". | keyword | | | +| salesforce.login.api.type | The type of API that's used to login. | keyword | | | +| salesforce.login.api.version | The version number of the API. If no version number is available, "Unknown" is returned. | keyword | | | +| salesforce.login.application | The application used to access the organization. | keyword | | | +| salesforce.login.auth.method_reference | The authentication method used by a third-party identification provider for an OpenID Connect single sign-on protocol. | keyword | | | +| salesforce.login.auth.service_id | The 18-character ID for an authentication service for a login event. | keyword | | | +| salesforce.login.channel_name | The Salesforce generic subscription Push Topic name. | keyword | | | +| salesforce.login.client_version | The version number of the login client. If no version number is available, "Unknown" is returned. | keyword | | | +| salesforce.login.evaluation_time | The amount of time it took to evaluate the transaction security policy, in milliseconds. | float | ms | gauge | +| salesforce.login.geo_id | The Salesforce ID of the geolocation information associated with the login user's IP address. | keyword | | | +| salesforce.login.history_id | Tracks a user session so you can correlate user activity with a particular login instance. | keyword | | | +| salesforce.login.key | The string that ties together all events in a given user's login session. The session starts with a login event and ends with either a logout event or the user session expiring. | keyword | | | +| salesforce.login.policy_id | The ID of the transaction security policy associated with this event. | keyword | | | +| salesforce.login.policy_outcome | The result of the transaction policy. | keyword | | | +| salesforce.login.related_event_identifier | Represents the EventIdentifier of the related event. | keyword | | | +| salesforce.login.session.key | The user's unique session ID. Use this value to identify all user events within a session. When a user logs out and logs in again, a new session is started. | keyword | | | +| salesforce.login.session.level | Session-level security controls user access to features that support it, such as connected apps and reporting. | keyword | | | +| salesforce.login.type | The type of login used to access the session. | keyword | | | +| source.geo.city_name | City name. | keyword | | | +| source.geo.continent_name | Name of the continent. | keyword | | | +| source.geo.country_iso_code | Country ISO code. | keyword | | | +| source.geo.country_name | Country name. | keyword | | | +| source.geo.location | Longitude and latitude. | geo_point | | | +| source.geo.postal_code | Postal code associated with the location. Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. | keyword | | | +| source.geo.region_iso_code | Region ISO code. | keyword | | | +| source.geo.region_name | Region name. | keyword | | | +| source.ip | IP address of the source (IPv4 or IPv6). | ip | | | +| tags | List of keywords used to tag each event. | keyword | | | +| tls.cipher | String indicating the cipher used during the current connection. | keyword | | | +| tls.version | Numeric part of the version parsed from the original string. | keyword | | | +| tls.version_protocol | Normalized lowercase protocol name parsed from original string. | keyword | | | +| user.email | User email address. | keyword | | | +| user.id | Unique identifier of the user. | keyword | | | +| user.roles | Array of user roles at the time of the event. | keyword | | | +| user_agent.name | Name of the user agent. | keyword | | | +| user_agent.os.platform | Operating system platform (such centos, ubuntu, windows). | keyword | | | + + ### Logout Rest This is the `logout_rest` data stream. It represents events containing details about the user's organization's logout history. diff --git a/packages/salesforce/img/salesforce-login.png b/packages/salesforce/img/salesforce-login.png index 40d70f93d21..7e6f0a531eb 100644 Binary files a/packages/salesforce/img/salesforce-login.png and b/packages/salesforce/img/salesforce-login.png differ diff --git a/packages/salesforce/kibana/dashboard/salesforce-1659aef0-574c-11ec-8f0b-05e8b06e1b10-pkg.json b/packages/salesforce/kibana/dashboard/salesforce-1659aef0-574c-11ec-8f0b-05e8b06e1b10-pkg.json index b847fb9fb7e..316198e7635 100644 --- a/packages/salesforce/kibana/dashboard/salesforce-1659aef0-574c-11ec-8f0b-05e8b06e1b10-pkg.json +++ b/packages/salesforce/kibana/dashboard/salesforce-1659aef0-574c-11ec-8f0b-05e8b06e1b10-pkg.json @@ -7,7 +7,6 @@ "panelsJSON": "{\"afac70de-aeee-46de-9b78-9e584d5c3f7e\":{\"order\":0,\"width\":\"large\",\"grow\":false,\"type\":\"optionsListControl\",\"explicitInput\":{\"fieldName\":\"salesforce.instance_url\",\"title\":\"Instance URL\",\"id\":\"afac70de-aeee-46de-9b78-9e584d5c3f7e\",\"singleSelect\":false,\"enhancements\":{},\"selectedOptions\":[]}}}" }, "description": "Login EventLogFile Data", - "hits": 0, "kibanaSavedObjectMeta": { "searchSourceJSON": { "filter": [], @@ -20,6 +19,8 @@ "optionsJSON": { "hidePanelTitles": false, "syncColors": false, + "syncCursor": true, + "syncTooltips": false, "useMargins": true }, "panelsJSON": [ @@ -40,7 +41,7 @@ ], "state": { "datasourceStates": { - "indexpattern": { + "formBased": { "layers": { "e1b2bc2f-ba01-4998-8cf8-a20d5e2f4da5": { "columnOrder": [ @@ -185,7 +186,7 @@ "panelIndex": "0e854818-b5d3-4758-b099-04d68167678a", "title": "Login success rate [Logs Salesforce]", "type": "lens", - "version": "8.5.0" + "version": "8.7.0" }, { "embeddableConfig": { @@ -209,7 +210,7 @@ ], "state": { "datasourceStates": { - "indexpattern": { + "formBased": { "layers": { "e1b2bc2f-ba01-4998-8cf8-a20d5e2f4da5": { "columnOrder": [ @@ -324,7 +325,7 @@ "panelIndex": "e75fee04-c83e-48ad-83bd-498189cabec7", "title": "Failed login attempts [Logs Salesforce]", "type": "lens", - "version": "8.5.0" + "version": "8.7.0" }, { "embeddableConfig": { @@ -343,7 +344,7 @@ ], "state": { "datasourceStates": { - "indexpattern": { + "formBased": { "layers": { "440fc980-229c-428f-b87b-78b25eeb6155": { "columnOrder": [ @@ -516,7 +517,7 @@ "panelIndex": "e780606f-6362-497e-9e17-940937ead5bf", "title": "Login over time [Logs Salesforce]", "type": "lens", - "version": "8.5.0" + "version": "8.7.0" }, { "embeddableConfig": { @@ -535,7 +536,7 @@ ], "state": { "datasourceStates": { - "indexpattern": { + "formBased": { "layers": { "9c7705b7-2344-40b4-a257-d8ced3dd0740": { "columnOrder": [ @@ -657,7 +658,7 @@ "panelIndex": "27d96d74-bfe5-4676-84fc-0f7e24594b5a", "title": "Total login events over time [Logs Salesforce]", "type": "lens", - "version": "8.5.0" + "version": "8.7.0" }, { "embeddableConfig": { @@ -676,7 +677,7 @@ ], "state": { "datasourceStates": { - "indexpattern": { + "formBased": { "layers": { "c99534c3-c26a-4456-837b-3a71c0c9423e": { "columnOrder": [ @@ -757,7 +758,9 @@ "layerId": "c99534c3-c26a-4456-837b-3a71c0c9423e", "layerType": "data", "legendDisplay": "default", - "metric": "9478baac-1153-4cda-a4b4-08db8af7580a", + "metrics": [ + "9478baac-1153-4cda-a4b4-08db8af7580a" + ], "nestedLegend": false, "numberDisplay": "percent", "primaryGroups": [ @@ -785,7 +788,7 @@ "panelIndex": "9ea2b92f-5fb6-4a83-b198-5275565a4bd6", "title": "Distribution of type of users [Logs Salesforce]", "type": "lens", - "version": "8.5.0" + "version": "8.7.0" }, { "embeddableConfig": { @@ -793,35 +796,36 @@ "references": [ { "id": "logs-*", - "name": "indexpattern-datasource-layer-21816ba6-c606-4532-9362-64890b01b81c", + "name": "indexpattern-datasource-layer-fe97c656-f063-45c6-8d2c-f681b01b9c25", "type": "index-pattern" }, { "id": "logs-*", - "name": "291ef01d-68cf-4c56-bc16-79b16ecb8195", + "name": "a739c3da-8335-4818-ae05-77815677253f", "type": "index-pattern" } ], "state": { + "adHocDataViews": {}, "datasourceStates": { - "indexpattern": { + "formBased": { "layers": { - "21816ba6-c606-4532-9362-64890b01b81c": { + "fe97c656-f063-45c6-8d2c-f681b01b9c25": { "columnOrder": [ - "20cea7a4-2d2b-4a01-8591-e8aa9a80d6c3", - "9ab68795-f5bc-485c-b0db-9e8f87d5b992" + "429bdef4-3ab3-4826-aa68-2c13f0dc2557", + "a1b52fa9-f635-4caf-be9a-4b9cbdaf3a4d" ], "columns": { - "20cea7a4-2d2b-4a01-8591-e8aa9a80d6c3": { + "429bdef4-3ab3-4826-aa68-2c13f0dc2557": { "customLabel": true, - "dataType": "ip", + "dataType": "string", "isBucketed": true, - "label": "IP Addresses", + "label": "User Agent", "operationType": "terms", "params": { "missingBucket": false, "orderBy": { - "columnId": "9ab68795-f5bc-485c-b0db-9e8f87d5b992", + "columnId": "a1b52fa9-f635-4caf-be9a-4b9cbdaf3a4d", "type": "column" }, "orderDirection": "desc", @@ -829,16 +833,16 @@ "parentFormat": { "id": "terms" }, - "size": 10 + "size": 5 }, "scale": "ordinal", - "sourceField": "source.ip" + "sourceField": "user_agent.name" }, - "9ab68795-f5bc-485c-b0db-9e8f87d5b992": { - "customLabel": true, + "a1b52fa9-f635-4caf-be9a-4b9cbdaf3a4d": { + "customLabel": false, "dataType": "number", "isBucketed": false, - "label": "Request count", + "label": "Count of records", "operationType": "count", "params": { "emptyAsNull": true @@ -860,7 +864,7 @@ "meta": { "alias": null, "disabled": false, - "index": "291ef01d-68cf-4c56-bc16-79b16ecb8195", + "index": "a739c3da-8335-4818-ae05-77815677253f", "key": "event.action", "negate": false, "params": { @@ -875,69 +879,49 @@ } } ], + "internalReferences": [], "query": { "language": "kuery", - "query": "event.dataset : salesforce.login*" + "query": "" }, "visualization": { - "axisTitlesVisibilitySettings": { - "x": true, - "yLeft": true, - "yRight": true - }, - "fittingFunction": "None", - "gridlinesVisibilitySettings": { - "x": true, - "yLeft": true, - "yRight": true - }, - "labelsOrientation": { - "x": 0, - "yLeft": 0, - "yRight": 0 - }, "layers": [ { - "accessors": [ - "9ab68795-f5bc-485c-b0db-9e8f87d5b992" - ], - "layerId": "21816ba6-c606-4532-9362-64890b01b81c", + "categoryDisplay": "default", + "layerId": "fe97c656-f063-45c6-8d2c-f681b01b9c25", "layerType": "data", - "seriesType": "bar_horizontal", - "xAccessor": "20cea7a4-2d2b-4a01-8591-e8aa9a80d6c3" + "legendDisplay": "default", + "metrics": [ + "a1b52fa9-f635-4caf-be9a-4b9cbdaf3a4d" + ], + "nestedLegend": false, + "numberDisplay": "percent", + "primaryGroups": [ + "429bdef4-3ab3-4826-aa68-2c13f0dc2557" + ] } ], - "legend": { - "isVisible": true, - "position": "right" - }, - "preferredSeriesType": "bar_horizontal", - "tickLabelsVisibilitySettings": { - "x": true, - "yLeft": true, - "yRight": true - }, - "valueLabels": "hide" + "shape": "donut" } }, "title": "", "type": "lens", - "visualizationType": "lnsXY" + "visualizationType": "lnsPie" }, "enhancements": {}, "hidePanelTitles": false }, "gridData": { - "h": 17, - "i": "4a2b88af-ad1a-416d-9553-d21b23882c22", + "h": 15, + "i": "4b6641b7-fa2a-4d84-a9f6-e358000702dc", "w": 24, "x": 24, - "y": 56 + "y": 41 }, - "panelIndex": "4a2b88af-ad1a-416d-9553-d21b23882c22", - "title": "Top 10 IP addresses by request count [Logs Salesforce]", + "panelIndex": "4b6641b7-fa2a-4d84-a9f6-e358000702dc", + "title": "Activity by browser/client [Logs Salesforce]", "type": "lens", - "version": "8.5.0" + "version": "8.7.0" }, { "embeddableConfig": { @@ -961,7 +945,7 @@ ], "state": { "datasourceStates": { - "indexpattern": { + "formBased": { "layers": { "26b85139-d8f7-4158-829c-eed584dc6310": { "columnOrder": [ @@ -1155,12 +1139,12 @@ "i": "b2b60887-159a-4a2f-a477-eece1cda9620", "w": 24, "x": 0, - "y": 56 + "y": 71 }, "panelIndex": "b2b60887-159a-4a2f-a477-eece1cda9620", "title": "Login events table [Logs Salesforce]", "type": "lens", - "version": "8.5.0" + "version": "8.7.0" }, { "embeddableConfig": { @@ -1168,36 +1152,180 @@ "references": [ { "id": "logs-*", - "name": "indexpattern-datasource-layer-fe97c656-f063-45c6-8d2c-f681b01b9c25", + "name": "indexpattern-datasource-layer-75cb4ead-3ea9-4a50-b9e3-93a364e95f02", "type": "index-pattern" }, { "id": "logs-*", - "name": "a739c3da-8335-4818-ae05-77815677253f", + "name": "facc7c18-e911-4ccf-b7a8-0239c491be02", "type": "index-pattern" } ], "state": { "adHocDataViews": {}, "datasourceStates": { - "indexpattern": { + "formBased": { "layers": { - "fe97c656-f063-45c6-8d2c-f681b01b9c25": { + "75cb4ead-3ea9-4a50-b9e3-93a364e95f02": { "columnOrder": [ - "429bdef4-3ab3-4826-aa68-2c13f0dc2557", - "a1b52fa9-f635-4caf-be9a-4b9cbdaf3a4d" + "8e5c4236-26b7-402d-b1ef-0af6d7028ebd", + "5a25315e-fd94-4e86-ba45-423bd31ab8bc" ], "columns": { - "429bdef4-3ab3-4826-aa68-2c13f0dc2557": { + "5a25315e-fd94-4e86-ba45-423bd31ab8bc": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "User count", + "operationType": "unique_count", + "params": { + "emptyAsNull": true + }, + "scale": "ratio", + "sourceField": "user.email" + }, + "8e5c4236-26b7-402d-b1ef-0af6d7028ebd": { "customLabel": true, "dataType": "string", "isBucketed": true, - "label": "User Agent", + "label": "Application type", "operationType": "terms", "params": { + "exclude": [], + "excludeIsRegex": false, + "include": [], + "includeIsRegex": false, "missingBucket": false, "orderBy": { - "columnId": "a1b52fa9-f635-4caf-be9a-4b9cbdaf3a4d", + "columnId": "5a25315e-fd94-4e86-ba45-423bd31ab8bc", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "parentFormat": { + "id": "terms" + }, + "secondaryFields": [], + "size": 10 + }, + "scale": "ordinal", + "sourceField": "salesforce.login.application" + } + }, + "incompleteColumns": {}, + "sampling": 1 + } + } + }, + "textBased": { + "layers": {} + } + }, + "filters": [ + { + "$state": { + "store": "appState" + }, + "meta": { + "alias": null, + "disabled": false, + "index": "facc7c18-e911-4ccf-b7a8-0239c491be02", + "key": "event.action", + "negate": false, + "params": { + "query": "login-attempt" + }, + "type": "phrase" + }, + "query": { + "match_phrase": { + "event.action": "login-attempt" + } + } + } + ], + "internalReferences": [], + "query": { + "language": "kuery", + "query": "event.dataset : salesforce.login*" + }, + "visualization": { + "layers": [ + { + "accessors": [ + "5a25315e-fd94-4e86-ba45-423bd31ab8bc" + ], + "layerId": "75cb4ead-3ea9-4a50-b9e3-93a364e95f02", + "layerType": "data", + "position": "top", + "seriesType": "bar_horizontal", + "showGridlines": false, + "xAccessor": "8e5c4236-26b7-402d-b1ef-0af6d7028ebd" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "bar_horizontal", + "title": "Empty XY chart", + "valueLabels": "hide" + } + }, + "title": "", + "type": "lens", + "visualizationType": "lnsXY" + }, + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "6115a6d5-d780-4272-b952-2af28343a5b6", + "w": 24, + "x": 24, + "y": 56 + }, + "panelIndex": "6115a6d5-d780-4272-b952-2af28343a5b6", + "title": "Top 10 Application type by user count [Logs Salesforce]", + "type": "lens", + "version": "8.7.0" + }, + { + "embeddableConfig": { + "attributes": { + "references": [ + { + "id": "logs-*", + "name": "indexpattern-datasource-layer-21816ba6-c606-4532-9362-64890b01b81c", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "291ef01d-68cf-4c56-bc16-79b16ecb8195", + "type": "index-pattern" + } + ], + "state": { + "datasourceStates": { + "formBased": { + "layers": { + "21816ba6-c606-4532-9362-64890b01b81c": { + "columnOrder": [ + "20cea7a4-2d2b-4a01-8591-e8aa9a80d6c3", + "9ab68795-f5bc-485c-b0db-9e8f87d5b992" + ], + "columns": { + "20cea7a4-2d2b-4a01-8591-e8aa9a80d6c3": { + "customLabel": true, + "dataType": "ip", + "isBucketed": true, + "label": "IP Addresses", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "9ab68795-f5bc-485c-b0db-9e8f87d5b992", "type": "column" }, "orderDirection": "desc", @@ -1205,16 +1333,16 @@ "parentFormat": { "id": "terms" }, - "size": 5 + "size": 10 }, "scale": "ordinal", - "sourceField": "user_agent.name" + "sourceField": "source.ip" }, - "a1b52fa9-f635-4caf-be9a-4b9cbdaf3a4d": { - "customLabel": false, + "9ab68795-f5bc-485c-b0db-9e8f87d5b992": { + "customLabel": true, "dataType": "number", "isBucketed": false, - "label": "Count of records", + "label": "Request count", "operationType": "count", "params": { "emptyAsNull": true @@ -1236,7 +1364,7 @@ "meta": { "alias": null, "disabled": false, - "index": "a739c3da-8335-4818-ae05-77815677253f", + "index": "291ef01d-68cf-4c56-bc16-79b16ecb8195", "key": "event.action", "negate": false, "params": { @@ -1251,47 +1379,69 @@ } } ], - "internalReferences": [], "query": { "language": "kuery", - "query": "" + "query": "event.dataset : salesforce.login*" }, "visualization": { + "axisTitlesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "fittingFunction": "None", + "gridlinesVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "labelsOrientation": { + "x": 0, + "yLeft": 0, + "yRight": 0 + }, "layers": [ { - "categoryDisplay": "default", - "layerId": "fe97c656-f063-45c6-8d2c-f681b01b9c25", + "accessors": [ + "9ab68795-f5bc-485c-b0db-9e8f87d5b992" + ], + "layerId": "21816ba6-c606-4532-9362-64890b01b81c", "layerType": "data", - "legendDisplay": "default", - "metric": "a1b52fa9-f635-4caf-be9a-4b9cbdaf3a4d", - "nestedLegend": false, - "numberDisplay": "percent", - "primaryGroups": [ - "429bdef4-3ab3-4826-aa68-2c13f0dc2557" - ] + "seriesType": "bar_horizontal", + "xAccessor": "20cea7a4-2d2b-4a01-8591-e8aa9a80d6c3" } ], - "shape": "donut" + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "bar_horizontal", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" } }, "title": "", "type": "lens", - "visualizationType": "lnsPie" + "visualizationType": "lnsXY" }, "enhancements": {}, "hidePanelTitles": false }, "gridData": { - "h": 15, - "i": "4b6641b7-fa2a-4d84-a9f6-e358000702dc", + "h": 17, + "i": "4a2b88af-ad1a-416d-9553-d21b23882c22", "w": 24, "x": 24, - "y": 41 + "y": 71 }, - "panelIndex": "4b6641b7-fa2a-4d84-a9f6-e358000702dc", - "title": "Activity by browser/client [Logs Salesforce]", + "panelIndex": "4a2b88af-ad1a-416d-9553-d21b23882c22", + "title": "Top 10 IP addresses by request count [Logs Salesforce]", "type": "lens", - "version": "8.5.0" + "version": "8.7.0" }, { "embeddableConfig": { @@ -1324,12 +1474,156 @@ "i": "bc6b147a-bd41-4f00-affe-4a7b7fbaab7a", "w": 48, "x": 0, - "y": 73 + "y": 88 }, "panelIndex": "bc6b147a-bd41-4f00-affe-4a7b7fbaab7a", "title": "Login activity by region [Logs Salesforce]", "type": "map", - "version": "8.5.0" + "version": "8.7.0" + }, + { + "embeddableConfig": { + "attributes": { + "references": [ + { + "id": "logs-*", + "name": "indexpattern-datasource-layer-75cb4ead-3ea9-4a50-b9e3-93a364e95f02", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "ca30f8ea-e4d6-4799-acb9-0638cdd01159", + "type": "index-pattern" + } + ], + "state": { + "adHocDataViews": {}, + "datasourceStates": { + "formBased": { + "layers": { + "75cb4ead-3ea9-4a50-b9e3-93a364e95f02": { + "columnOrder": [ + "f21fe70c-96b7-452f-9bdd-d0066baba7de", + "5a25315e-fd94-4e86-ba45-423bd31ab8bc" + ], + "columns": { + "5a25315e-fd94-4e86-ba45-423bd31ab8bc": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "User count", + "operationType": "unique_count", + "params": { + "emptyAsNull": true + }, + "scale": "ratio", + "sourceField": "user.email" + }, + "f21fe70c-96b7-452f-9bdd-d0066baba7de": { + "customLabel": true, + "dataType": "string", + "isBucketed": true, + "label": "Postal code", + "operationType": "terms", + "params": { + "exclude": [], + "excludeIsRegex": false, + "include": [], + "includeIsRegex": false, + "missingBucket": false, + "orderBy": { + "columnId": "5a25315e-fd94-4e86-ba45-423bd31ab8bc", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "parentFormat": { + "id": "terms" + }, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "source.geo.postal_code" + } + }, + "incompleteColumns": {}, + "sampling": 1 + } + } + }, + "textBased": { + "layers": {} + } + }, + "filters": [ + { + "$state": { + "store": "appState" + }, + "meta": { + "alias": null, + "disabled": false, + "index": "ca30f8ea-e4d6-4799-acb9-0638cdd01159", + "key": "event.action", + "negate": false, + "params": { + "query": "login-attempt" + }, + "type": "phrase" + }, + "query": { + "match_phrase": { + "event.action": "login-attempt" + } + } + } + ], + "internalReferences": [], + "query": { + "language": "kuery", + "query": "event.dataset : salesforce.login*" + }, + "visualization": { + "layers": [ + { + "accessors": [ + "5a25315e-fd94-4e86-ba45-423bd31ab8bc" + ], + "layerId": "75cb4ead-3ea9-4a50-b9e3-93a364e95f02", + "layerType": "data", + "position": "top", + "seriesType": "bar_horizontal", + "showGridlines": false, + "xAccessor": "f21fe70c-96b7-452f-9bdd-d0066baba7de" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "bar_horizontal", + "title": "Empty XY chart", + "valueLabels": "hide" + } + }, + "title": "", + "type": "lens", + "visualizationType": "lnsXY" + }, + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "a841d405-e28f-4eea-b7a4-5cfc0299a0c6", + "w": 24, + "x": 0, + "y": 56 + }, + "panelIndex": "a841d405-e28f-4eea-b7a4-5cfc0299a0c6", + "title": "Top 10 Postal code by user count [Logs Salesforce]", + "type": "lens", + "version": "8.7.0" } ], "refreshInterval": { @@ -1342,10 +1636,11 @@ "title": "[Logs Salesforce] Login Dashboard", "version": 1 }, - "coreMigrationVersion": "8.5.0", + "coreMigrationVersion": "8.7.0", + "created_at": "2023-04-21T08:29:17.849Z", "id": "salesforce-1659aef0-574c-11ec-8f0b-05e8b06e1b10-pkg", "migrationVersion": { - "dashboard": "8.5.0" + "dashboard": "8.7.0" }, "references": [ { @@ -1405,12 +1700,12 @@ }, { "id": "logs-*", - "name": "4a2b88af-ad1a-416d-9553-d21b23882c22:indexpattern-datasource-layer-21816ba6-c606-4532-9362-64890b01b81c", + "name": "4b6641b7-fa2a-4d84-a9f6-e358000702dc:indexpattern-datasource-layer-fe97c656-f063-45c6-8d2c-f681b01b9c25", "type": "index-pattern" }, { "id": "logs-*", - "name": "4a2b88af-ad1a-416d-9553-d21b23882c22:291ef01d-68cf-4c56-bc16-79b16ecb8195", + "name": "4b6641b7-fa2a-4d84-a9f6-e358000702dc:a739c3da-8335-4818-ae05-77815677253f", "type": "index-pattern" }, { @@ -1430,12 +1725,22 @@ }, { "id": "logs-*", - "name": "4b6641b7-fa2a-4d84-a9f6-e358000702dc:indexpattern-datasource-layer-fe97c656-f063-45c6-8d2c-f681b01b9c25", + "name": "6115a6d5-d780-4272-b952-2af28343a5b6:indexpattern-datasource-layer-75cb4ead-3ea9-4a50-b9e3-93a364e95f02", "type": "index-pattern" }, { "id": "logs-*", - "name": "4b6641b7-fa2a-4d84-a9f6-e358000702dc:a739c3da-8335-4818-ae05-77815677253f", + "name": "6115a6d5-d780-4272-b952-2af28343a5b6:facc7c18-e911-4ccf-b7a8-0239c491be02", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "4a2b88af-ad1a-416d-9553-d21b23882c22:indexpattern-datasource-layer-21816ba6-c606-4532-9362-64890b01b81c", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "4a2b88af-ad1a-416d-9553-d21b23882c22:291ef01d-68cf-4c56-bc16-79b16ecb8195", "type": "index-pattern" }, { @@ -1443,6 +1748,16 @@ "name": "bc6b147a-bd41-4f00-affe-4a7b7fbaab7a:layer_1_source_index_pattern", "type": "index-pattern" }, + { + "id": "logs-*", + "name": "a841d405-e28f-4eea-b7a4-5cfc0299a0c6:indexpattern-datasource-layer-75cb4ead-3ea9-4a50-b9e3-93a364e95f02", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "a841d405-e28f-4eea-b7a4-5cfc0299a0c6:ca30f8ea-e4d6-4799-acb9-0638cdd01159", + "type": "index-pattern" + }, { "id": "logs-*", "name": "controlGroup_afac70de-aeee-46de-9b78-9e584d5c3f7e:optionsListDataView", diff --git a/packages/salesforce/manifest.yml b/packages/salesforce/manifest.yml index 47824d318ef..f7cde336396 100644 --- a/packages/salesforce/manifest.yml +++ b/packages/salesforce/manifest.yml @@ -1,14 +1,14 @@ format_version: 1.0.0 name: salesforce title: Salesforce -version: 0.5.0 +version: 0.6.0 license: basic description: Collect logs from Salesforce with Elastic Agent. type: integration categories: - observability conditions: - kibana.version: ^8.5.0 + kibana.version: ^8.7.0 screenshots: - src: /img/salesforce-login.png title: Salesforce Login Dashboard @@ -31,52 +31,59 @@ icons: title: Salesforce size: 32x32 type: image/svg+xml +vars: + - name: instance_url + type: text + title: Instance URL + description: The Instance URL of the Salesforce instance. + required: true + show_user: true + default: https://instance-url.salesforce.com + - name: client_id + type: text + title: Client ID + description: OAuth 2.0 client ID. + required: true + show_user: true + default: client_id + - name: client_secret + type: password + title: Client Secret + description: OAuth 2.0 client secret. + required: true + show_user: true + default: client_secret + - name: username + type: text + title: Username + description: Email Id used while registering salesforce, (i.e. my.email@here.com). + required: true + show_user: true + default: username + - name: password + type: password + title: Password + description: The password used as part of the authentication flow. + required: true + show_user: true + default: password + - name: token_url + type: text + title: Token URL + description: The OAuth 2.0 token URL for Salesforce. + required: true + show_user: false + default: https://login.salesforce.com/services/oauth2/token policy_templates: - name: salesforce title: Salesforce logs description: Collect logs from Salesforce instances. inputs: - type: httpjson - vars: - - name: instance_url - type: text - title: Instance URL - description: The Instance URL of the Salesforce instance. - required: true - show_user: true - default: https://instance-url.salesforce.com - - name: client_id - type: text - title: Client ID - description: OAuth 2.0 client ID. - required: true - show_user: true - - name: client_secret - type: password - title: Client Secret - description: OAuth 2.0 client secret. - required: true - show_user: true - - name: username - type: text - title: Username - description: Email Id used while registering salesforce, (i.e. my.email@here.com). - required: true - show_user: true - - name: password - type: password - title: Password - description: The password used as part of the authentication flow. - required: true - show_user: true - - name: token_url - type: text - title: Token URL - description: The OAuth 2.0 token URL for Salesforce. - required: true - show_user: false - default: https://login.salesforce.com/services/oauth2/token - title: Collect Salesforce logs - description: Collecting logs from Salesforce instances. + title: Collect Salesforce logs using REST API + description: Collecting logs from Salesforce instances using REST API. + - type: cometd + title: Collect Salesforce logs using Streaming API + description: Collecting logs from Salesforce instances using Streaming API. owner: github: elastic/obs-service-integrations