diff --git a/packages/salesforce/_dev/build/docs/README.md b/packages/salesforce/_dev/build/docs/README.md index fbb13e5e78e..f011cc19697 100644 --- a/packages/salesforce/_dev/build/docs/README.md +++ b/packages/salesforce/_dev/build/docs/README.md @@ -2,67 +2,68 @@ ## Overview -The Salesforce integration allows you to monitor a [Salesforce](https://www.salesforce.com/) instance. Salesforce is a customer relationship management (CRM) platform. It provides an ecosystem for businesses to manage marketing, sales, commerce, service, and IT teams from anywhere with one integrated CRM platform. +The Salesforce integration allows users to monitor a [Salesforce](https://www.salesforce.com/) instance. Salesforce is a customer relationship management (CRM) platform. It provides an ecosystem for businesses to manage marketing, sales, commerce, service, and IT teams from anywhere with one integrated CRM platform. Use the Salesforce integration to: -- Gain insights into login and other operational activities by the users of your organization. +- Gain insights into login and other operational activities by the users of the organization. - Create visualizations to monitor, measure and analyze the usage trend and key data, and derive business insights. - Create alerts to reduce the MTTD and also the MTTR by referencing relevant logs when troubleshooting an issue. -As an example, you can use the data from this integration to understand the activity patterns of users based on region or the distribution of users by license type. +As an example, users can use the data from this integration to understand the activity patterns of users based on region or the distribution of users by license type. ## Data streams The Salesforce integration collects log events using the REST API of Salesforce. -**Logs** help you 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) and [Apex](https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_objects_apexclass.htm). +**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). Data streams: - `login_rest`: 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. ## Compatibility This integration has been tested against Salesforce `Spring '22 (v54.0) release`. -In order to find out the Salesforce version of your Instance, see below: +In order to find out the Salesforce version of the user's instance, see below: -1. On the Home tab in Salesforce Classic, in the top right corner of the screen is a link to releases like `Summer '22`. This indicates your release. +1. On the Home tab in Salesforce Classic, in the top right corner of the screen is a link to releases like `Summer '22`. This indicates the release version of the salesforce instance. 2. An alternative way to find out the version of Salesforce is by hitting the following URL: - - Format: (Salesforce Instance URL)/services/data - - Example: `https://na9.salesforce.com/services/data` + - Format: (Salesforce Instance URL)/services/data + - Example: `https://na9.salesforce.com/services/data` Example response: ```xml - - - /services/data/v53.0 - 53.0 - - - - /services/data/v54.0 - 54.0 - - - - /services/data/v55.0 - 55.0 - + + + /services/data/v53.0 + 53.0 + + + + /services/data/v54.0 + 54.0 + + + + /services/data/v55.0 + 55.0 + ``` -The last one on the list is the release of your instance. In the example above, the version is `Summer '22` i.e. `v55.0`. +The last one on the list is the release of the user's salesforce instance. In the example above, the version is `Summer '22` i.e. `v55.0`. ## Prerequisites -You need Elasticsearch for storing and searching your data and Kibana for visualizing and managing it. -You can use our hosted Elasticsearch Service on Elastic Cloud, which is recommended or self-manage the Elastic Stack on your own hardware. +Users need Elasticsearch for storing and searching their data and Kibana for visualizing and managing it. +Users can use our hosted Elasticsearch Service on Elastic Cloud, which is recommended, or self-manage the Elastic Stack on their own hardware. -In your Salesforce instance, ensure that `API Enabled permission` is selected for the user profile. Follow the below steps to enable the same: +In the user's Salesforce instance, ensure that `API Enabled permission` 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. @@ -74,15 +75,15 @@ For step-by-step instructions on how to set up an integration, see the [Getting ## Configuration -You need the following information from your Salesforce instance to configure this integration in Elastic: +Users need the following information from the user's Salesforce instance to configure this integration in Elastic: ### Salesforce Instance URL -The instance your Salesforce Organization uses is indicated in the URL of your browser's address bar in Salesforce Classic. The value before 'salesforce.com' is your Salesforce Instance. +The instance the user's Salesforce Organization uses is indicated in the URL of the address bar in Salesforce Classic. The value before 'salesforce.com' is the user's Salesforce Instance. Example URL: `https://na9.salesforce.com/home/home.jsp` -In the above example, the value before 'salesforce.com' is your Salesforce Instance. In this example, the Salesforce Organization is located on NA9. +In the above example, the value before 'salesforce.com' is the user's Salesforce Instance. In this example, the Salesforce Organization is located on NA9. The Salesforce Instance URL is: `https://na9.salesforce.com` @@ -90,9 +91,9 @@ In Salesforce Lightning, it is available under the user name in the “View Prof ### Client Key and Client Secret for Authentication -In order to use this integration, you need to create a new Salesforce Application using OAuth. Follow the steps below to create a connected application in Salesforce: +In order to use this integration, users need to create a new Salesforce Application using OAuth. Follow the steps below to create a connected application in Salesforce: -1. Login to [Salesforce](https://login.salesforce.com/) with the same user credentials that you want to collect data with. +1. Login to [Salesforce](https://login.salesforce.com/) with the same user credentials that the user wants to collect data with. 2. Click on Setup on the top right menu bar. On the Setup page search `App Manager` in the `Search Setup` search box at the top of the page, then select `App Manager`. 3. Click *New Connected App*. 4. Provide a name for the connected application. This will be displayed in the App Manager and on its App Launcher tile. @@ -101,9 +102,9 @@ In order to use this integration, you need to create a new Salesforce Applicatio 7. Under the API (Enable OAuth Settings) section of the page, select *Enable OAuth Settings*. 8. In the Callback URL enter the Instance URL (Please refer to `Salesforce Instance URL`) 9. Select the following OAuth scopes to apply to the connected app: - - Manage user data via APIs (api). - - Perform requests at any time (refresh_token, offline_access). - - (Optional) In case of data collection, if any permission issues arise, add the Full access (full) scope. + - Manage user data via APIs (api). + - Perform requests at any time (refresh_token, offline_access). + - (Optional) In case of data collection, if any permission issues arise, add the Full access (full) scope. 10. Select *Require Secret for the Web Server Flow* to require the app's client secret in exchange for an access token. 11. Select *Require Secret for Refresh Token Flow* to require the app's client secret in the authorization request of a refresh token and hybrid refresh token flow. 12. Click Save. It may take approximately 10 minutes for the changes to take effect. @@ -122,7 +123,7 @@ Password used for authenticating the above user. ## Additional Information -Follow the steps below, in case you need to find the API version: +Follow the steps below, in case the user needs to find the API version: 1. Go to `Setup` > `Quick Find` > `Apex Classes`. 2. Click the `New` button. @@ -131,7 +132,7 @@ Follow the steps below, in case you need to find the API version: ## Validation -After the integration is successfully configured, clicking on the Assets tab of the Salesforce Integration should display a list of available dashboards. Click on the dashboard available for your configured datastream. It should be populated with the required data. +After the integration is successfully configured, clicking on the Assets tab of the Salesforce Integration should display a list of available dashboards. Click on the dashboard available for the user's configured datastream. It should be populated with the required data. ## Troubleshooting @@ -157,7 +158,7 @@ Please refer to the Prerequisites section above for more information. If the error continues follow these steps: 1. Go to `Setup` > `Quick Find` > `Manage Connected Apps`. -2. Click on the Connected App name created by you to generate the client id and client secret (Refer to Client Key and Client Secret for Authentication) under the Master Label. +2. Click on the Connected App name created by the user to generate the client id and client secret (Refer to Client Key and Client Secret for Authentication) under the Master Label. 3. Click on Edit Policies, and select `Relax IP restrictions` from the dropdown for IP Relaxation. ## Logs reference @@ -172,7 +173,7 @@ This is the `apex` data stream. Apex enables developers to access the Salesforce ### Login Rest -This is the `login_rest` data stream. It represents events containing details about your organization's user login history. +This is the `login_rest` data stream. It represents events containing details about the user's organization's login history. {{event "login_rest"}} @@ -180,8 +181,16 @@ This is the `login_rest` data stream. It represents events containing details ab ### Logout Rest -This is the `logout_rest` data stream. It represents events containing details about your organization's user logout history. +This is the `logout_rest` data stream. It represents events containing details about the user's organization's logout history. {{event "logout_rest"}} {{fields "logout_rest"}} + +### SetupAuditTrail + +This is the `setupaudittrail` data stream. It represents changes users made in the user's organization's Setup area for at least the last 180 days. + +{{event "setupaudittrail"}} + +{{fields "setupaudittrail"}} diff --git a/packages/salesforce/_dev/deploy/docker/files/config.yml b/packages/salesforce/_dev/deploy/docker/files/config.yml index 354a307bc76..461757fd10a 100644 --- a/packages/salesforce/_dev/deploy/docker/files/config.yml +++ b/packages/salesforce/_dev/deploy/docker/files/config.yml @@ -18,10 +18,10 @@ rules: - path: /services/data/v54.0/query methods: ["GET"] query_params: - q: ["SELECT Action,CreatedByContext,CreatedById,CreatedByIssuer,CreatedDate,DelegateUser,Display,Id,ResponsibleNamespacePrefix,Section FROM SetupAuditTrail ORDER BY CreatedDate ASC NULLS FIRST"] + q: ["SELECT Action,CreatedByContext,CreatedById,CreatedByIssuer,CreatedDate,DelegateUser,Display,Id,Section FROM SetupAuditTrail ORDER BY CreatedDate ASC NULLS FIRST"] responses: - status_code: 200 - body: '{"done":true,"records":[{"Action":"insertConnectedApplication","CreatedByContext":"Einstein","CreatedById":"0055j000000utlPAAQ","CreatedByIssuer":null,"CreatedDate":"2022-08-16T09:26:38.000+0000","DelegateUser":"user1","Display":"For user user@elastic.co, the User Verified Email status changed to verified","Id":"0Ym5j000019nwonCAA","ResponsibleNamespacePrefix":"namespaceprefix","Section":"Connected Apps","attributes":{"type":"SetupAuditTrail","url":"/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA"}}],"totalSize":160}' + body: '{"done":true,"records":[{"Action":"insertConnectedApplication","CreatedByContext":"Einstein","CreatedById":"0055j000000utlPAAQ","CreatedByIssuer":null,"CreatedDate":"2022-08-16T09:26:38.000+0000","DelegateUser":"user1","Display":"For user user@elastic.co, the User Verified Email status changed to verified","Id":"0Ym5j000019nwonCAA","Section":"Connected Apps","attributes":{"type":"SetupAuditTrail","url":"/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA"}}],"totalSize":160}' headers: content-type: ["text/json"] - path: /services/data/v54.0/sobjects/EventLogFile/0AT5j00002GVrfnGAD/LogFile diff --git a/packages/salesforce/changelog.yml b/packages/salesforce/changelog.yml index 7787168a659..06e391b89bc 100644 --- a/packages/salesforce/changelog.yml +++ b/packages/salesforce/changelog.yml @@ -1,5 +1,10 @@ # newer versions go on top +- version: 0.4.0 + changes: + - description: Salesforce integration package with "setupaudittrail" data stream. + link: https://github.com/elastic/integrations/pull/4356 + type: enhancement - version: 0.3.0 changes: - description: Salesforce integration package with "apex" data stream. diff --git a/packages/salesforce/data_stream/setupaudittrail/_dev/test/pipeline/test-common-config.yml b/packages/salesforce/data_stream/setupaudittrail/_dev/test/pipeline/test-common-config.yml new file mode 100644 index 00000000000..5622947e4b8 --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/_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/setupaudittrail/_dev/test/pipeline/test-setupaudittrail.log b/packages/salesforce/data_stream/setupaudittrail/_dev/test/pipeline/test-setupaudittrail.log new file mode 100644 index 00000000000..8021e715dff --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/_dev/test/pipeline/test-setupaudittrail.log @@ -0,0 +1 @@ +{"Action":"insertConnectedApplication","CreatedByContext":"Einstein","CreatedById":"0055j000000utlPAAQ","CreatedByIssuer":null,"CreatedDate":"2022-08-16T09:26:38.000+0000","DelegateUser":"user1","Display":"For user user@elastic.co, the User Verified Email status changed to verified","Id":"0Ym5j000019nwonCAA","Section":"Connected Apps","attributes":{"type":"SetupAuditTrail","url":"/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA"}} \ No newline at end of file diff --git a/packages/salesforce/data_stream/setupaudittrail/_dev/test/pipeline/test-setupaudittrail.log-expected.json b/packages/salesforce/data_stream/setupaudittrail/_dev/test/pipeline/test-setupaudittrail.log-expected.json new file mode 100644 index 00000000000..ae92f30bccd --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/_dev/test/pipeline/test-setupaudittrail.log-expected.json @@ -0,0 +1,41 @@ +{ + "expected": [ + { + "@timestamp": "2022-08-16T09:26:38.000Z", + "ecs": { + "version": "8.5.0" + }, + "event": { + "action": "insertConnectedApplication", + "created": "2022-08-16T09:26:38.000Z", + "dataset": "salesforce.setupaudittrail", + "id": "0Ym5j000019nwonCAA", + "kind": "event", + "module": "salesforce", + "original": "{\"Action\":\"insertConnectedApplication\",\"CreatedByContext\":\"Einstein\",\"CreatedById\":\"0055j000000utlPAAQ\",\"CreatedByIssuer\":null,\"CreatedDate\":\"2022-08-16T09:26:38.000+0000\",\"DelegateUser\":\"user1\",\"Display\":\"For user user@elastic.co, the User Verified Email status changed to verified\",\"Id\":\"0Ym5j000019nwonCAA\",\"Section\":\"Connected Apps\",\"attributes\":{\"type\":\"SetupAuditTrail\",\"url\":\"/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA\"}}", + "type": [ + "admin" + ], + "url": "/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA" + }, + "salesforce": { + "setup_audit_trail": { + "access_mode": "REST", + "created_by_context": "Einstein", + "created_by_id": "0055j000000utlPAAQ", + "delegate_user": "user1", + "display": "For user user@elastic.co, the User Verified Email status changed to verified", + "event_type": "SetupAuditTrail", + "section": "Connected Apps" + } + }, + "tags": [ + "preserve_original_event" + ], + "user": { + "id": "0055j000000utlPAAQ", + "name": "user@elastic.co" + } + } + ] +} \ No newline at end of file diff --git a/packages/salesforce/data_stream/setupaudittrail/_dev/test/system/test-default-config.yml b/packages/salesforce/data_stream/setupaudittrail/_dev/test/system/test-default-config.yml new file mode 100644 index 00000000000..c6aa6813ff0 --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/_dev/test/system/test-default-config.yml @@ -0,0 +1,12 @@ +input: httpjson +service: salesforce +vars: + instance_url: http://{{Hostname}}:{{Port}} + 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 +data_stream: + vars: + preserve_original_event: true diff --git a/packages/salesforce/data_stream/setupaudittrail/agent/stream/httpjson.yml.hbs b/packages/salesforce/data_stream/setupaudittrail/agent/stream/httpjson.yml.hbs new file mode 100644 index 00000000000..d3cebb0412e --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/agent/stream/httpjson.yml.hbs @@ -0,0 +1,44 @@ +config_version: 2 +interval: {{period}} +request.method: GET +auth.oauth2: + enabled: true + client.id: {{client_id}} + client.secret: {{client_secret}} + token_url: {{token_url}} + user: {{username}} + password: {{password}} +request.url: {{instance_url}}/services/data/v54.0/query?q=setupaudittrail+rest +request.transforms: + - set: + target: url.params.q + value: "SELECT Action,CreatedByContext,CreatedById,CreatedByIssuer,CreatedDate,DelegateUser,Display,Id,Section FROM SetupAuditTrail WHERE CreatedDate > [[.cursor.last_published_setupaudittrail]] ORDER BY CreatedDate ASC NULLS FIRST" + default: "SELECT Action,CreatedByContext,CreatedById,CreatedByIssuer,CreatedDate,DelegateUser,Display,Id,Section FROM SetupAuditTrail ORDER BY CreatedDate ASC NULLS FIRST" +response.split: + target: body.records +response.pagination: +- set: + target: url.value + value: '[[if (ne .last_response.body.done true)]]{{instance_url}}[[.last_response.body.nextRecordsUrl]][[end]]' + fail_on_template_error: true +cursor: + last_published_setupaudittrail: + value: '[[.last_event.CreatedDate]]' +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/setupaudittrail/elasticsearch/ingest_pipeline/default.yml b/packages/salesforce/data_stream/setupaudittrail/elasticsearch/ingest_pipeline/default.yml new file mode 100644 index 00000000000..9fb9c6f8458 --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/elasticsearch/ingest_pipeline/default.yml @@ -0,0 +1,145 @@ +--- +description: Pipeline for parsing Salesforce SetupAuditTrail logs. +processors: +- json: + field: message + target_field: json + ignore_failure: true +- rename: + field: message + target_field: event.original + ignore_missing: true + ignore_failure: true +- set: + field: salesforce.setup_audit_trail.access_mode + value: "REST" + ignore_failure: true + ignore_empty_value: true +- date: + field: json.CreatedDate + target_field: "@timestamp" + formats: + - ISO8601 + ignore_failure: true +- rename: + field: json.attributes.type + target_field: salesforce.setup_audit_trail.event_type + ignore_missing: true + ignore_failure: true +- rename: + field: json.CreatedByContext + target_field: salesforce.setup_audit_trail.created_by_context + ignore_missing: true + ignore_failure: true +- rename: + field: json.CreatedById + target_field: salesforce.setup_audit_trail.created_by_id + ignore_missing: true + ignore_failure: true +- rename: + field: json.CreatedByIssuer + target_field: salesforce.setup_audit_trail.created_by_issuer + ignore_missing: true + ignore_failure: true +- rename: + field: json.DelegateUser + target_field: salesforce.setup_audit_trail.delegate_user + ignore_missing: true + ignore_failure: true +- rename: + field: json.Display + target_field: salesforce.setup_audit_trail.display + ignore_missing: true + ignore_failure: true +- rename: + field: json.Section + target_field: salesforce.setup_audit_trail.section + ignore_missing: true + ignore_failure: true +- set: + field: ecs.version + value: "8.5.0" + ignore_failure: true + ignore_empty_value: true +- rename: + field: json.Id + target_field: event.id + ignore_missing: true + ignore_failure: true +- rename: + field: json.Action + target_field: event.action + ignore_missing: true + ignore_failure: true +- rename: + field: json.attributes.url + target_field: event.url + ignore_missing: true + ignore_failure: true +- date: + field: json.CreatedDate + target_field: event.created + formats: + - ISO8601 + ignore_failure: true +- set: + field: event.type + value: ["admin"] + ignore_failure: true + ignore_empty_value: true +- set: + field: event.kind + value: "event" + ignore_failure: true + ignore_empty_value: true +- set: + field: event.dataset + value: "salesforce.setupaudittrail" + ignore_failure: true + ignore_empty_value: true +- set: + field: event.module + value: "salesforce" + ignore_failure: true + ignore_empty_value: true +- set: + field: user.id + copy_from: salesforce.setup_audit_trail.created_by_id + ignore_failure: true + ignore_empty_value: true +- dissect: + field: salesforce.setup_audit_trail.display + pattern: "For user %{user.name}, %{?}" + ignore_failure: 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_missing: true + ignore_failure: true +- remove: + field: event.original + if: "ctx.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true +on_failure: +- set: + field: error.message + value: '{{{_ingest.on_failure_message}}}' diff --git a/packages/salesforce/data_stream/setupaudittrail/fields/base-fields.yml b/packages/salesforce/data_stream/setupaudittrail/fields/base-fields.yml new file mode 100644 index 00000000000..3500f7ce8c2 --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/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/setupaudittrail/fields/ecs.yml b/packages/salesforce/data_stream/setupaudittrail/fields/ecs.yml new file mode 100644 index 00000000000..180a757d8b7 --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/fields/ecs.yml @@ -0,0 +1,28 @@ +- external: ecs + name: ecs.version +- external: ecs + name: error.message +- external: ecs + name: event.action +- external: ecs + name: event.created +- external: ecs + name: event.dataset +- external: ecs + name: event.id +- external: ecs + name: event.ingested +- external: ecs + name: event.kind +- external: ecs + name: event.module +- external: ecs + name: event.type +- external: ecs + name: event.url +- external: ecs + name: tags +- external: ecs + name: user.id +- external: ecs + name: user.name diff --git a/packages/salesforce/data_stream/setupaudittrail/fields/fields.yml b/packages/salesforce/data_stream/setupaudittrail/fields/fields.yml new file mode 100644 index 00000000000..e540673a155 --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/fields/fields.yml @@ -0,0 +1,33 @@ +- name: salesforce + type: group + fields: + - name: instance_url + type: keyword + description: The Instance URL of the Salesforce instance. + - name: setup_audit_trail + type: group + fields: + - name: access_mode + type: keyword + description: Type of API from which the event is collected. + - name: created_by_context + type: keyword + description: The context under which the Setup change was made. For example, if Einstein uses cloud-to-cloud services to make a change in Setup, the value of this field is Einstein. + - name: created_by_id + type: keyword + description: The id under which the Setup change was made. For example, if Einstein uses cloud-to-cloud services to make a change in Setup, the value of this field is id of Einstein. + - name: created_by_issuer + type: keyword + description: Reserved for future use. + - name: delegate_user + type: keyword + description: The Login-As user who executed the action in Setup. If a Login-As user didn't perform the action, this field is empty string. This field is available in API version 35.0 and later. + - name: display + type: keyword + description: 'The full description of changes made in Setup. For example, if the event.action field has a value of PermSetCreate, the Display field has a value like "Created permission set MAD: with user license Salesforce."' + - name: event_type + type: keyword + description: Event type. + - name: section + type: keyword + description: The section in the Setup menu where the action occurred. For example, Manage Users or Company Profile. diff --git a/packages/salesforce/data_stream/setupaudittrail/manifest.yml b/packages/salesforce/data_stream/setupaudittrail/manifest.yml new file mode 100644 index 00000000000..949cc70ca7c --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/manifest.yml @@ -0,0 +1,40 @@ +type: logs +title: Salesforce setupaudittrail logs +streams: + - input: httpjson + vars: + - name: period + type: text + title: Period + description: Period of fetching logs, i.e. 1s/1m/1h. + multi: false + required: true + show_user: false + default: 1h + - name: tags + type: text + title: Tags + multi: true + required: true + show_user: false + default: + - salesforce-setupaudittrail + - 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: httpjson.yml.hbs + title: Salesforce SetupAuditTrail logs + description: Collect Salesforce SetupAuditTrail logs. diff --git a/packages/salesforce/data_stream/setupaudittrail/sample_event.json b/packages/salesforce/data_stream/setupaudittrail/sample_event.json new file mode 100644 index 00000000000..0d75af9cddf --- /dev/null +++ b/packages/salesforce/data_stream/setupaudittrail/sample_event.json @@ -0,0 +1,62 @@ +{ + "@timestamp": "2022-08-16T09:26:38.000Z", + "agent": { + "ephemeral_id": "cf463665-f17d-4155-8434-4f93e0fabd18", + "id": "511d10d2-be41-45d0-9712-40b7ce035864", + "name": "docker-fleet-agent", + "type": "filebeat", + "version": "8.4.1" + }, + "data_stream": { + "dataset": "salesforce.setupaudittrail", + "namespace": "ep", + "type": "logs" + }, + "ecs": { + "version": "8.5.0" + }, + "elastic_agent": { + "id": "511d10d2-be41-45d0-9712-40b7ce035864", + "snapshot": false, + "version": "8.4.1" + }, + "event": { + "action": "insertConnectedApplication", + "agent_id_status": "verified", + "created": "2022-08-16T09:26:38.000Z", + "dataset": "salesforce.setupaudittrail", + "id": "0Ym5j000019nwonCAA", + "ingested": "2023-01-04T15:34:45Z", + "kind": "event", + "module": "salesforce", + "original": "{\"Action\":\"insertConnectedApplication\",\"CreatedByContext\":\"Einstein\",\"CreatedById\":\"0055j000000utlPAAQ\",\"CreatedByIssuer\":null,\"CreatedDate\":\"2022-08-16T09:26:38.000+0000\",\"DelegateUser\":\"user1\",\"Display\":\"For user user@elastic.co, the User Verified Email status changed to verified\",\"Id\":\"0Ym5j000019nwonCAA\",\"Section\":\"Connected Apps\",\"attributes\":{\"type\":\"SetupAuditTrail\",\"url\":\"/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA\"}}", + "type": [ + "admin" + ], + "url": "/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA" + }, + "input": { + "type": "httpjson" + }, + "salesforce": { + "instance_url": "http://elastic-package-service_salesforce_1:8010", + "setup_audit_trail": { + "access_mode": "REST", + "created_by_context": "Einstein", + "created_by_id": "0055j000000utlPAAQ", + "delegate_user": "user1", + "display": "For user user@elastic.co, the User Verified Email status changed to verified", + "event_type": "SetupAuditTrail", + "section": "Connected Apps" + } + }, + "tags": [ + "preserve_original_event", + "salesforce-setupaudittrail", + "forwarded" + ], + "user": { + "id": "0055j000000utlPAAQ", + "name": "user@elastic.co" + } +} \ No newline at end of file diff --git a/packages/salesforce/docs/README.md b/packages/salesforce/docs/README.md index c0c9a8524ad..3125542a850 100644 --- a/packages/salesforce/docs/README.md +++ b/packages/salesforce/docs/README.md @@ -2,67 +2,68 @@ ## Overview -The Salesforce integration allows you to monitor a [Salesforce](https://www.salesforce.com/) instance. Salesforce is a customer relationship management (CRM) platform. It provides an ecosystem for businesses to manage marketing, sales, commerce, service, and IT teams from anywhere with one integrated CRM platform. +The Salesforce integration allows users to monitor a [Salesforce](https://www.salesforce.com/) instance. Salesforce is a customer relationship management (CRM) platform. It provides an ecosystem for businesses to manage marketing, sales, commerce, service, and IT teams from anywhere with one integrated CRM platform. Use the Salesforce integration to: -- Gain insights into login and other operational activities by the users of your organization. +- Gain insights into login and other operational activities by the users of the organization. - Create visualizations to monitor, measure and analyze the usage trend and key data, and derive business insights. - Create alerts to reduce the MTTD and also the MTTR by referencing relevant logs when troubleshooting an issue. -As an example, you can use the data from this integration to understand the activity patterns of users based on region or the distribution of users by license type. +As an example, users can use the data from this integration to understand the activity patterns of users based on region or the distribution of users by license type. ## Data streams The Salesforce integration collects log events using the REST API of Salesforce. -**Logs** help you 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) and [Apex](https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_objects_apexclass.htm). +**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). Data streams: - `login_rest`: 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. ## Compatibility This integration has been tested against Salesforce `Spring '22 (v54.0) release`. -In order to find out the Salesforce version of your Instance, see below: +In order to find out the Salesforce version of the user's instance, see below: -1. On the Home tab in Salesforce Classic, in the top right corner of the screen is a link to releases like `Summer '22`. This indicates your release. +1. On the Home tab in Salesforce Classic, in the top right corner of the screen is a link to releases like `Summer '22`. This indicates the release version of the salesforce instance. 2. An alternative way to find out the version of Salesforce is by hitting the following URL: - - Format: (Salesforce Instance URL)/services/data - - Example: `https://na9.salesforce.com/services/data` + - Format: (Salesforce Instance URL)/services/data + - Example: `https://na9.salesforce.com/services/data` Example response: ```xml - - - /services/data/v53.0 - 53.0 - - - - /services/data/v54.0 - 54.0 - - - - /services/data/v55.0 - 55.0 - + + + /services/data/v53.0 + 53.0 + + + + /services/data/v54.0 + 54.0 + + + + /services/data/v55.0 + 55.0 + ``` -The last one on the list is the release of your instance. In the example above, the version is `Summer '22` i.e. `v55.0`. +The last one on the list is the release of the user's salesforce instance. In the example above, the version is `Summer '22` i.e. `v55.0`. ## Prerequisites -You need Elasticsearch for storing and searching your data and Kibana for visualizing and managing it. -You can use our hosted Elasticsearch Service on Elastic Cloud, which is recommended or self-manage the Elastic Stack on your own hardware. +Users need Elasticsearch for storing and searching their data and Kibana for visualizing and managing it. +Users can use our hosted Elasticsearch Service on Elastic Cloud, which is recommended, or self-manage the Elastic Stack on their own hardware. -In your Salesforce instance, ensure that `API Enabled permission` is selected for the user profile. Follow the below steps to enable the same: +In the user's Salesforce instance, ensure that `API Enabled permission` 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. @@ -74,15 +75,15 @@ For step-by-step instructions on how to set up an integration, see the [Getting ## Configuration -You need the following information from your Salesforce instance to configure this integration in Elastic: +Users need the following information from the user's Salesforce instance to configure this integration in Elastic: ### Salesforce Instance URL -The instance your Salesforce Organization uses is indicated in the URL of your browser's address bar in Salesforce Classic. The value before 'salesforce.com' is your Salesforce Instance. +The instance the user's Salesforce Organization uses is indicated in the URL of the address bar in Salesforce Classic. The value before 'salesforce.com' is the user's Salesforce Instance. Example URL: `https://na9.salesforce.com/home/home.jsp` -In the above example, the value before 'salesforce.com' is your Salesforce Instance. In this example, the Salesforce Organization is located on NA9. +In the above example, the value before 'salesforce.com' is the user's Salesforce Instance. In this example, the Salesforce Organization is located on NA9. The Salesforce Instance URL is: `https://na9.salesforce.com` @@ -90,9 +91,9 @@ In Salesforce Lightning, it is available under the user name in the “View Prof ### Client Key and Client Secret for Authentication -In order to use this integration, you need to create a new Salesforce Application using OAuth. Follow the steps below to create a connected application in Salesforce: +In order to use this integration, users need to create a new Salesforce Application using OAuth. Follow the steps below to create a connected application in Salesforce: -1. Login to [Salesforce](https://login.salesforce.com/) with the same user credentials that you want to collect data with. +1. Login to [Salesforce](https://login.salesforce.com/) with the same user credentials that the user wants to collect data with. 2. Click on Setup on the top right menu bar. On the Setup page search `App Manager` in the `Search Setup` search box at the top of the page, then select `App Manager`. 3. Click *New Connected App*. 4. Provide a name for the connected application. This will be displayed in the App Manager and on its App Launcher tile. @@ -101,9 +102,9 @@ In order to use this integration, you need to create a new Salesforce Applicatio 7. Under the API (Enable OAuth Settings) section of the page, select *Enable OAuth Settings*. 8. In the Callback URL enter the Instance URL (Please refer to `Salesforce Instance URL`) 9. Select the following OAuth scopes to apply to the connected app: - - Manage user data via APIs (api). - - Perform requests at any time (refresh_token, offline_access). - - (Optional) In case of data collection, if any permission issues arise, add the Full access (full) scope. + - Manage user data via APIs (api). + - Perform requests at any time (refresh_token, offline_access). + - (Optional) In case of data collection, if any permission issues arise, add the Full access (full) scope. 10. Select *Require Secret for the Web Server Flow* to require the app's client secret in exchange for an access token. 11. Select *Require Secret for Refresh Token Flow* to require the app's client secret in the authorization request of a refresh token and hybrid refresh token flow. 12. Click Save. It may take approximately 10 minutes for the changes to take effect. @@ -122,7 +123,7 @@ Password used for authenticating the above user. ## Additional Information -Follow the steps below, in case you need to find the API version: +Follow the steps below, in case the user needs to find the API version: 1. Go to `Setup` > `Quick Find` > `Apex Classes`. 2. Click the `New` button. @@ -131,7 +132,7 @@ Follow the steps below, in case you need to find the API version: ## Validation -After the integration is successfully configured, clicking on the Assets tab of the Salesforce Integration should display a list of available dashboards. Click on the dashboard available for your configured datastream. It should be populated with the required data. +After the integration is successfully configured, clicking on the Assets tab of the Salesforce Integration should display a list of available dashboards. Click on the dashboard available for the user's configured datastream. It should be populated with the required data. ## Troubleshooting @@ -157,7 +158,7 @@ Please refer to the Prerequisites section above for more information. If the error continues follow these steps: 1. Go to `Setup` > `Quick Find` > `Manage Connected Apps`. -2. Click on the Connected App name created by you to generate the client id and client secret (Refer to Client Key and Client Secret for Authentication) under the Master Label. +2. Click on the Connected App name created by the user to generate the client id and client secret (Refer to Client Key and Client Secret for Authentication) under the Master Label. 3. Click on Edit Policies, and select `Relax IP restrictions` from the dropdown for IP Relaxation. ## Logs reference @@ -361,7 +362,7 @@ An example event for `apex` looks as following: ### Login Rest -This is the `login_rest` data stream. It represents events containing details about your organization's user login history. +This is the `login_rest` data stream. It represents events containing details about the user's organization's login history. An example event for `login_rest` looks as following: @@ -532,7 +533,7 @@ An example event for `login_rest` looks as following: ### Logout Rest -This is the `logout_rest` data stream. It represents events containing details about your organization's user logout history. +This is the `logout_rest` data stream. It represents events containing details about the user's organization's logout history. An example event for `logout_rest` looks as following: @@ -685,3 +686,109 @@ An example event for `logout_rest` looks as following: | user.id | Unique identifier of the user. | keyword | | user.roles | Array of user roles at the time of the event. | keyword | + +### SetupAuditTrail + +This is the `setupaudittrail` data stream. It represents changes users made in the user's organization's Setup area for at least the last 180 days. + +An example event for `setupaudittrail` looks as following: + +```json +{ + "@timestamp": "2022-08-16T09:26:38.000Z", + "agent": { + "ephemeral_id": "cf463665-f17d-4155-8434-4f93e0fabd18", + "id": "511d10d2-be41-45d0-9712-40b7ce035864", + "name": "docker-fleet-agent", + "type": "filebeat", + "version": "8.4.1" + }, + "data_stream": { + "dataset": "salesforce.setupaudittrail", + "namespace": "ep", + "type": "logs" + }, + "ecs": { + "version": "8.5.0" + }, + "elastic_agent": { + "id": "511d10d2-be41-45d0-9712-40b7ce035864", + "snapshot": false, + "version": "8.4.1" + }, + "event": { + "action": "insertConnectedApplication", + "agent_id_status": "verified", + "created": "2022-08-16T09:26:38.000Z", + "dataset": "salesforce.setupaudittrail", + "id": "0Ym5j000019nwonCAA", + "ingested": "2023-01-04T15:34:45Z", + "kind": "event", + "module": "salesforce", + "original": "{\"Action\":\"insertConnectedApplication\",\"CreatedByContext\":\"Einstein\",\"CreatedById\":\"0055j000000utlPAAQ\",\"CreatedByIssuer\":null,\"CreatedDate\":\"2022-08-16T09:26:38.000+0000\",\"DelegateUser\":\"user1\",\"Display\":\"For user user@elastic.co, the User Verified Email status changed to verified\",\"Id\":\"0Ym5j000019nwonCAA\",\"Section\":\"Connected Apps\",\"attributes\":{\"type\":\"SetupAuditTrail\",\"url\":\"/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA\"}}", + "type": [ + "admin" + ], + "url": "/services/data/v54.0/sobjects/SetupAuditTrail/0Ym5j000019nwonCAA" + }, + "input": { + "type": "httpjson" + }, + "salesforce": { + "instance_url": "http://elastic-package-service_salesforce_1:8010", + "setup_audit_trail": { + "access_mode": "REST", + "created_by_context": "Einstein", + "created_by_id": "0055j000000utlPAAQ", + "delegate_user": "user1", + "display": "For user user@elastic.co, the User Verified Email status changed to verified", + "event_type": "SetupAuditTrail", + "section": "Connected Apps" + } + }, + "tags": [ + "preserve_original_event", + "salesforce-setupaudittrail", + "forwarded" + ], + "user": { + "id": "0055j000000utlPAAQ", + "name": "user@elastic.co" + } +} +``` + +**Exported fields** + +| Field | Description | 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 | +| error.message | Error message. | match_only_text | +| 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.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.id | Unique ID to describe the event. | 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.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 | +| input.type | Input type. | keyword | +| salesforce.instance_url | The Instance URL of the Salesforce instance. | keyword | +| salesforce.setup_audit_trail.access_mode | Type of API from which the event is collected. | keyword | +| salesforce.setup_audit_trail.created_by_context | The context under which the Setup change was made. For example, if Einstein uses cloud-to-cloud services to make a change in Setup, the value of this field is Einstein. | keyword | +| salesforce.setup_audit_trail.created_by_id | The id under which the Setup change was made. For example, if Einstein uses cloud-to-cloud services to make a change in Setup, the value of this field is id of Einstein. | keyword | +| salesforce.setup_audit_trail.created_by_issuer | Reserved for future use. | keyword | +| salesforce.setup_audit_trail.delegate_user | The Login-As user who executed the action in Setup. If a Login-As user didn't perform the action, this field is empty string. This field is available in API version 35.0 and later. | keyword | +| salesforce.setup_audit_trail.display | The full description of changes made in Setup. For example, if the event.action field has a value of PermSetCreate, the Display field has a value like "Created permission set MAD: with user license Salesforce." | keyword | +| salesforce.setup_audit_trail.event_type | Event type. | keyword | +| salesforce.setup_audit_trail.section | The section in the Setup menu where the action occurred. For example, Manage Users or Company Profile. | keyword | +| tags | List of keywords used to tag each event. | keyword | +| user.id | Unique identifier of the user. | keyword | +| user.name | Short name or login of the user. | keyword | +| user.name.text | Multi-field of `user.name`. | match_only_text | + diff --git a/packages/salesforce/img/salesforce-setupaudittrail.png b/packages/salesforce/img/salesforce-setupaudittrail.png new file mode 100644 index 00000000000..a0c083c5179 Binary files /dev/null and b/packages/salesforce/img/salesforce-setupaudittrail.png differ diff --git a/packages/salesforce/kibana/dashboard/salesforce-790da810-5749-11ec-8f0b-05e8b06e1b10-pkg.json b/packages/salesforce/kibana/dashboard/salesforce-790da810-5749-11ec-8f0b-05e8b06e1b10-pkg.json new file mode 100644 index 00000000000..05ea5bae66b --- /dev/null +++ b/packages/salesforce/kibana/dashboard/salesforce-790da810-5749-11ec-8f0b-05e8b06e1b10-pkg.json @@ -0,0 +1,754 @@ +{ + "attributes": { + "controlGroupInput": { + "chainingSystem": "HIERARCHICAL", + "controlStyle": "oneLine", + "ignoreParentSettingsJSON": "{\"ignoreFilters\":false,\"ignoreQuery\":false,\"ignoreTimerange\":false,\"ignoreValidations\":false}", + "panelsJSON": "{\"19ec3993-9d43-486c-aabc-682e1d63bb52\":{\"order\":0,\"width\":\"large\",\"grow\":false,\"type\":\"optionsListControl\",\"explicitInput\":{\"fieldName\":\"salesforce.instance_url\",\"title\":\"Instance URL\",\"id\":\"19ec3993-9d43-486c-aabc-682e1d63bb52\",\"enhancements\":{},\"selectedOptions\":[]}}}" + }, + "description": "SetupAuditTrail EventLogFile Data", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "optionsJSON": { + "hidePanelTitles": false, + "syncColors": true, + "syncTooltips": true, + "useMargins": true + }, + "panelsJSON": [ + { + "embeddableConfig": { + "attributes": { + "references": [ + { + "id": "logs-*", + "name": "indexpattern-datasource-layer-d9d1a80f-da0d-4de3-b81b-915a1451dfae", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "a8681385-2b53-4897-bb47-37815be3d5a3", + "type": "index-pattern" + } + ], + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "d9d1a80f-da0d-4de3-b81b-915a1451dfae": { + "columnOrder": [ + "c330a448-da57-4033-9575-6fc498a6a00e", + "de7e5b08-824f-4884-b4af-4cca15a26500", + "aebdaa57-11d2-4742-b5d1-8c9359992816" + ], + "columns": { + "aebdaa57-11d2-4742-b5d1-8c9359992816": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "Request count", + "operationType": "count", + "params": { + "emptyAsNull": true + }, + "scale": "ratio", + "sourceField": "___records___" + }, + "c330a448-da57-4033-9575-6fc498a6a00e": { + "customLabel": true, + "dataType": "string", + "isBucketed": true, + "label": "Actions", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "aebdaa57-11d2-4742-b5d1-8c9359992816", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": false, + "parentFormat": { + "id": "terms" + }, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "event.action" + }, + "de7e5b08-824f-4884-b4af-4cca15a26500": { + "dataType": "string", + "isBucketed": true, + "label": "Top 10 values of salesforce.setup_audit_trail.delegate_user", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "aebdaa57-11d2-4742-b5d1-8c9359992816", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": false, + "parentFormat": { + "id": "terms" + }, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "salesforce.setup_audit_trail.delegate_user" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [ + { + "$state": { + "store": "appState" + }, + "meta": { + "alias": null, + "disabled": false, + "index": "a8681385-2b53-4897-bb47-37815be3d5a3", + "key": "event.dataset", + "negate": false, + "params": { + "query": "salesforce.setupaudittrail" + }, + "type": "phrase" + }, + "query": { + "match_phrase": { + "event.dataset": "salesforce.setupaudittrail" + } + } + } + ], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "layers": [ + { + "accessors": [ + "aebdaa57-11d2-4742-b5d1-8c9359992816" + ], + "layerId": "d9d1a80f-da0d-4de3-b81b-915a1451dfae", + "layerType": "data", + "position": "top", + "seriesType": "bar_stacked", + "showGridlines": false, + "splitAccessor": "de7e5b08-824f-4884-b4af-4cca15a26500", + "xAccessor": "c330a448-da57-4033-9575-6fc498a6a00e" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "bar_stacked", + "title": "Empty XY chart", + "valueLabels": "hide" + } + }, + "title": "", + "type": "lens", + "visualizationType": "lnsXY" + }, + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "86d0aa67-c1da-4027-9368-9d0c7b393ee7", + "w": 24, + "x": 0, + "y": 0 + }, + "panelIndex": "86d0aa67-c1da-4027-9368-9d0c7b393ee7", + "title": "Top 10 Actions performed by delegated users [Logs Salesforce]", + "type": "lens", + "version": "8.4.1" + }, + { + "embeddableConfig": { + "attributes": { + "references": [ + { + "id": "logs-*", + "name": "indexpattern-datasource-layer-05728583-cb7a-4904-bf30-f70c545f1fa4", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "246a7b37-7e2a-465c-9a07-dd9fe33e8f73", + "type": "index-pattern" + } + ], + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "05728583-cb7a-4904-bf30-f70c545f1fa4": { + "columnOrder": [ + "89925259-d88b-4002-b3f3-c3112592864c", + "20311ced-e7b9-4fa5-b732-e03d621d74d3" + ], + "columns": { + "20311ced-e7b9-4fa5-b732-e03d621d74d3": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "Request count", + "operationType": "count", + "params": { + "emptyAsNull": true + }, + "scale": "ratio", + "sourceField": "___records___" + }, + "89925259-d88b-4002-b3f3-c3112592864c": { + "customLabel": true, + "dataType": "string", + "isBucketed": true, + "label": "Sections affected", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "20311ced-e7b9-4fa5-b732-e03d621d74d3", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": false, + "parentFormat": { + "id": "terms" + }, + "size": 10 + }, + "scale": "ordinal", + "sourceField": "salesforce.setup_audit_trail.section" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [ + { + "$state": { + "store": "appState" + }, + "meta": { + "alias": null, + "disabled": false, + "index": "246a7b37-7e2a-465c-9a07-dd9fe33e8f73", + "key": "event.dataset", + "negate": false, + "params": { + "query": "salesforce.setupaudittrail" + }, + "type": "phrase" + }, + "query": { + "match_phrase": { + "event.dataset": "salesforce.setupaudittrail" + } + } + } + ], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "layers": [ + { + "accessors": [ + "20311ced-e7b9-4fa5-b732-e03d621d74d3" + ], + "layerId": "05728583-cb7a-4904-bf30-f70c545f1fa4", + "layerType": "data", + "position": "top", + "seriesType": "bar", + "showGridlines": false, + "xAccessor": "89925259-d88b-4002-b3f3-c3112592864c" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "bar", + "title": "Empty XY chart", + "valueLabels": "hide" + } + }, + "title": "", + "type": "lens", + "visualizationType": "lnsXY" + }, + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "86eca459-ead0-451d-a319-db689af6fecd", + "w": 24, + "x": 24, + "y": 0 + }, + "panelIndex": "86eca459-ead0-451d-a319-db689af6fecd", + "title": "Top 10 Sections affected [Logs Salesforce]", + "type": "lens", + "version": "8.4.1" + }, + { + "embeddableConfig": { + "attributes": { + "references": [ + { + "id": "logs-*", + "name": "indexpattern-datasource-layer-d6fa34de-c164-4cf2-9a9e-55550d4f5c2b", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "f97777fd-460c-442e-a11e-c7d9669dd9bf", + "type": "index-pattern" + } + ], + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "d6fa34de-c164-4cf2-9a9e-55550d4f5c2b": { + "columnOrder": [ + "9ab2ae83-58e0-40c1-9152-2944132777a6", + "ffd5fa44-6891-4efd-acd4-b156aabaaf75", + "a047794a-dd3e-4988-b425-f542cc15fe3a" + ], + "columns": { + "9ab2ae83-58e0-40c1-9152-2944132777a6": { + "dataType": "string", + "isBucketed": true, + "label": "Top 10 values of event.action", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "a047794a-dd3e-4988-b425-f542cc15fe3a", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": false, + "parentFormat": { + "id": "terms" + }, + "secondaryFields": [], + "size": 10 + }, + "scale": "ordinal", + "sourceField": "event.action" + }, + "a047794a-dd3e-4988-b425-f542cc15fe3a": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "Actions ", + "operationType": "count", + "params": { + "emptyAsNull": true + }, + "scale": "ratio", + "sourceField": "___records___" + }, + "ffd5fa44-6891-4efd-acd4-b156aabaaf75": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "dropPartials": false, + "includeEmptyRows": true, + "interval": "auto" + }, + "scale": "interval", + "sourceField": "@timestamp" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [ + { + "$state": { + "store": "appState" + }, + "meta": { + "alias": null, + "disabled": false, + "index": "f97777fd-460c-442e-a11e-c7d9669dd9bf", + "key": "event.dataset", + "negate": false, + "params": { + "query": "salesforce.setupaudittrail" + }, + "type": "phrase" + }, + "query": { + "match_phrase": { + "event.dataset": "salesforce.setupaudittrail" + } + } + } + ], + "query": { + "language": "kuery", + "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": [ + "a047794a-dd3e-4988-b425-f542cc15fe3a" + ], + "layerId": "d6fa34de-c164-4cf2-9a9e-55550d4f5c2b", + "layerType": "data", + "position": "top", + "seriesType": "bar_stacked", + "showGridlines": false, + "splitAccessor": "9ab2ae83-58e0-40c1-9152-2944132777a6", + "xAccessor": "ffd5fa44-6891-4efd-acd4-b156aabaaf75" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "bar_stacked", + "tickLabelsVisibilitySettings": { + "x": true, + "yLeft": true, + "yRight": true + }, + "valueLabels": "hide" + } + }, + "title": "", + "type": "lens", + "visualizationType": "lnsXY" + }, + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 15, + "i": "0e7e3952-b099-4b91-b6f3-9e0239707f87", + "w": 48, + "x": 0, + "y": 15 + }, + "panelIndex": "0e7e3952-b099-4b91-b6f3-9e0239707f87", + "title": "Top 10 Actions over time [Logs Salesforce]", + "type": "lens", + "version": "8.4.1" + }, + { + "embeddableConfig": { + "attributes": { + "references": [ + { + "id": "logs-*", + "name": "indexpattern-datasource-layer-9411e1eb-536a-4d98-b1b7-fa41dc157d88", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "5a0205d1-985c-4a0d-add8-df232085ab36", + "type": "index-pattern" + } + ], + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "9411e1eb-536a-4d98-b1b7-fa41dc157d88": { + "columnOrder": [ + "b1691588-4383-4e6c-891a-f50799eb68ac", + "e7fbf4fb-e128-45d7-b95b-476844ae7ee2", + "d4503031-9bf0-4daf-a418-507a3a1b89ef", + "3553424c-661b-48dc-b323-8d33c94375a6", + "53e49d01-1e96-4aad-bdb3-43e5471fb163" + ], + "columns": { + "3553424c-661b-48dc-b323-8d33c94375a6": { + "customLabel": true, + "dataType": "string", + "filter": { + "language": "kuery", + "query": "event.action: *" + }, + "isBucketed": false, + "label": "Action", + "operationType": "last_value", + "params": { + "sortField": "@timestamp" + }, + "scale": "ordinal", + "sourceField": "event.action" + }, + "53e49d01-1e96-4aad-bdb3-43e5471fb163": { + "customLabel": true, + "dataType": "string", + "filter": { + "language": "kuery", + "query": "salesforce.setup_audit_trail.display: *" + }, + "isBucketed": false, + "label": "Display", + "operationType": "last_value", + "params": { + "sortField": "@timestamp" + }, + "scale": "ordinal", + "sourceField": "salesforce.setup_audit_trail.display" + }, + "b1691588-4383-4e6c-891a-f50799eb68ac": { + "dataType": "string", + "isBucketed": true, + "label": "Top 10000 values of _id", + "operationType": "terms", + "params": { + "missingBucket": false, + "orderBy": { + "columnId": "e7fbf4fb-e128-45d7-b95b-476844ae7ee2", + "type": "column" + }, + "orderDirection": "desc", + "otherBucket": true, + "parentFormat": { + "id": "terms" + }, + "size": 10000 + }, + "scale": "ordinal", + "sourceField": "_id" + }, + "d4503031-9bf0-4daf-a418-507a3a1b89ef": { + "customLabel": true, + "dataType": "string", + "filter": { + "language": "kuery", + "query": "salesforce.setup_audit_trail.section: *" + }, + "isBucketed": false, + "label": "Section", + "operationType": "last_value", + "params": { + "sortField": "@timestamp" + }, + "scale": "ordinal", + "sourceField": "salesforce.setup_audit_trail.section" + }, + "e7fbf4fb-e128-45d7-b95b-476844ae7ee2": { + "customLabel": true, + "dataType": "date", + "filter": { + "language": "kuery", + "query": "@timestamp: *" + }, + "isBucketed": false, + "label": "Timestamp", + "operationType": "last_value", + "params": { + "sortField": "@timestamp" + }, + "scale": "ratio", + "sourceField": "@timestamp" + } + }, + "incompleteColumns": {} + } + } + } + }, + "filters": [ + { + "$state": { + "store": "appState" + }, + "meta": { + "alias": null, + "disabled": false, + "index": "5a0205d1-985c-4a0d-add8-df232085ab36", + "key": "event.dataset", + "negate": false, + "params": { + "query": "salesforce.setupaudittrail" + }, + "type": "phrase" + }, + "query": { + "match_phrase": { + "event.dataset": "salesforce.setupaudittrail" + } + } + } + ], + "query": { + "language": "kuery", + "query": "salesforce.setup_audit_trail.section : * or event.action : * or salesforce.setup_audit_trail.display : *" + }, + "visualization": { + "columns": [ + { + "columnId": "b1691588-4383-4e6c-891a-f50799eb68ac", + "hidden": true, + "isTransposed": false + }, + { + "alignment": "left", + "columnId": "e7fbf4fb-e128-45d7-b95b-476844ae7ee2", + "isTransposed": false + }, + { + "alignment": "left", + "columnId": "d4503031-9bf0-4daf-a418-507a3a1b89ef", + "isTransposed": false + }, + { + "alignment": "left", + "columnId": "53e49d01-1e96-4aad-bdb3-43e5471fb163", + "isTransposed": false + }, + { + "alignment": "left", + "columnId": "3553424c-661b-48dc-b323-8d33c94375a6", + "isTransposed": false + } + ], + "headerRowHeight": "auto", + "layerId": "9411e1eb-536a-4d98-b1b7-fa41dc157d88", + "layerType": "data", + "paging": { + "enabled": true, + "size": 10 + }, + "rowHeight": "auto" + } + }, + "title": "", + "type": "lens", + "visualizationType": "lnsDatatable" + }, + "enhancements": {}, + "hidePanelTitles": false + }, + "gridData": { + "h": 18, + "i": "86bc6d31-3998-4a2e-ad1e-e2c373abeca8", + "w": 48, + "x": 0, + "y": 30 + }, + "panelIndex": "86bc6d31-3998-4a2e-ad1e-e2c373abeca8", + "title": "Changes made in the setup [Logs Salesforce]", + "type": "lens", + "version": "8.4.1" + } + ], + "refreshInterval": { + "pause": true, + "value": 0 + }, + "timeFrom": "now-7d/d", + "timeRestore": true, + "timeTo": "now", + "title": "[Logs Salesforce] Setup Audit Trail Dashboard", + "version": 1 + }, + "coreMigrationVersion": "8.4.1", + "id": "salesforce-790da810-5749-11ec-8f0b-05e8b06e1b10-pkg", + "migrationVersion": { + "dashboard": "8.4.0" + }, + "references": [ + { + "id": "logs-*", + "name": "86d0aa67-c1da-4027-9368-9d0c7b393ee7:indexpattern-datasource-layer-d9d1a80f-da0d-4de3-b81b-915a1451dfae", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "86d0aa67-c1da-4027-9368-9d0c7b393ee7:a8681385-2b53-4897-bb47-37815be3d5a3", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "86eca459-ead0-451d-a319-db689af6fecd:indexpattern-datasource-layer-05728583-cb7a-4904-bf30-f70c545f1fa4", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "86eca459-ead0-451d-a319-db689af6fecd:246a7b37-7e2a-465c-9a07-dd9fe33e8f73", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "0e7e3952-b099-4b91-b6f3-9e0239707f87:indexpattern-datasource-layer-d6fa34de-c164-4cf2-9a9e-55550d4f5c2b", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "0e7e3952-b099-4b91-b6f3-9e0239707f87:f97777fd-460c-442e-a11e-c7d9669dd9bf", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "86bc6d31-3998-4a2e-ad1e-e2c373abeca8:indexpattern-datasource-layer-9411e1eb-536a-4d98-b1b7-fa41dc157d88", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "86bc6d31-3998-4a2e-ad1e-e2c373abeca8:5a0205d1-985c-4a0d-add8-df232085ab36", + "type": "index-pattern" + }, + { + "id": "logs-*", + "name": "controlGroup_19ec3993-9d43-486c-aabc-682e1d63bb52:optionsListDataView", + "type": "index-pattern" + } + ], + "type": "dashboard" +} \ No newline at end of file diff --git a/packages/salesforce/manifest.yml b/packages/salesforce/manifest.yml index 97d8659cecd..b1ebf2d0ba6 100644 --- a/packages/salesforce/manifest.yml +++ b/packages/salesforce/manifest.yml @@ -1,7 +1,7 @@ format_version: 1.0.0 name: salesforce title: Salesforce -version: 0.3.0 +version: 0.4.0 license: basic description: Collect logs from Salesforce with Elastic Agent. type: integration @@ -18,6 +18,10 @@ screenshots: title: Salesforce Logout Dashboard size: 1366x1912 type: image/png + - src: /img/salesforce-setupaudittrail.png + title: Salesforce SetupAuditTrail Dashboard + size: 1366x1912 + type: image/png - src: /img/salesforce-apex.png title: Salesforce Apex Dashboard size: 1366x1912