diff --git a/packages/jamf_pro/_dev/build/docs/README.md b/packages/jamf_pro/_dev/build/docs/README.md index 882db4596869..a23162eb0881 100644 --- a/packages/jamf_pro/_dev/build/docs/README.md +++ b/packages/jamf_pro/_dev/build/docs/README.md @@ -1,4 +1,3 @@ - # Jamf Pro integration Jamf Pro is a comprehensive management solution designed to help organizations deploy, configure, secure, and manage Apple devices. This integration enables organizations to seamlessly monitor and protect their Mac fleet through Elastic, providing a unified view of security events across all endpoints and facilitating a more effective response to threats. This integration encompasses both event and inventory data ingestion from Jamf Pro. @@ -6,94 +5,115 @@ Jamf Pro is a comprehensive management solution designed to help organizations d ## Data streams - * __inventory__ provides Inventory data for computers. Includes: hardware, OS, etc. Saves each device as a separate log record. - This data stream utilizes `/v1/computers-inventory` endpoint from Jamf Pro API. +- **`inventory`** Provides Inventory data for computers. Includes: hardware, OS, etc. Saves each device as a separate log record. +This data stream utilizes the Jamf Pro API's `/v1/computers-inventory` endpoint. -* __events__ catches events, generated by [Jamf Pro Webhooks](https://developer.jamf.com/developer-guide/docs/webhooks) This datastream requires opening a port on kibana system +- **`events`** Receives events sent by [Jamf Pro Webhooks](https://developer.jamf.com/developer-guide/docs/webhooks). +This data stream requires opening a port on the Elastic Agent host. ## Requirements -### Inventory +#### Inventory -* __Jamf Pro Active License and OAuth2 Credentials:__ -This connector utilizes Jamf Pro API, therefore active license- Jamf __Business__ or __Enterprise__ is a requirement(Jamf __Now__ doesn't have access to API) +- **Jamf Pro Active License and OAuth2 Credentials** +This connector utilizes Jamf Pro API, therefore an active license - either Jamf **Business** or **Enterprise** - is required (Jamf _**Now**_ does not have access to the API) -### Events +#### Events + +- **HTTP(S) port open for incoming connections** +A port for incoming connections (`9202` by default) will be set during policy configuration. This port on host must be accessible from the Jamf server. -* __HTTP(S) Port opened for connection:__ On setting up the data_stream a port should be defined (9202 by default). To run the listener this port on host must be available from Jamf server. +- **Jamf Pro webhooks** +Please refer to the Jamf Pro documentation about [Setting up webhooks](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/Webhooks.html). +**NOTE**: For HTTPS usage, a valid, trusted certificate is essential; Jamf Pro webhooks cannot accept a self-signed certificate. If necessary, the HTTP protocol may serve as a fallback option. Although Jamf Pro webhooks do not require HTTPS, its use is strongly recommended for security reasons. -* __Jamf Pro webhooks__ -[Setting up webhooks ](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/Webhooks.html) in Jamf Pro Dashboard. -__NOTE__: For HTTPS usage, a valid verified certificate is essential; Jamf Pro webhooks cannot accept a self-signed certificate. If necessary, the HTTP protocol may serve as a fallback option. Although Jamf Pro webhooks do not require HTTPS, its use is strongly recommended for security reasons. ## Setup ### Step 1: Create an Application in Jamf Pro: -To create a connection to Jamf Pro, an [application must be created](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/API_Roles_and_Clients.html) first. -Credentials generated during this process are required for the subsequent steps. +To create a connection to Jamf Pro, an [application must be created](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/API_Roles_and_Clients.html) first. Credentials generated during this process are required for the subsequent steps. -__Permission required for Jamf Pro application__ -- _Read Computer Inventory Collection_: Access to read inventory data from the computer collection. -- _Read Computers_: Allows the application to access and read data from computers. -__Jamf Pro API Credentials__ -**client_id** is an app specific ID, it is generated on createin step and available from app settings -**client_secret** generated after app is created, it is available only after creation. Can be regenerated if lost. +**Permissions required by the Jamf Pro application**: +- **Read Computer Inventory Collection**: Access to read inventory data from the computer collection. +- **Read Computers**: Allows the application to access and read data from computers. + +**Jamf Pro API Credentials** +- **`client_id`** is an app specific ID generated during app creation, and is available in the app settings. +- **`client_secret`** is only available once after app creation. Can be regenerated if lost. Permissions can be set up on app creation or can be updated for existing app ### Step 2: Integration Setup: -To set up the *Inventory* data stream these three fields are required: -- jamf_pro host -- cliet_id -- client_secret -*Events* data_stream is a passive listener, it should be created before webhook will be created at Jamf Pro Dashboard. -Network settings should be defined by IT or Security person: -**Listen Address** -**Listen Port** -**URL** -Auth settings will be required on Jamf Pro Webhook settings: -**Secret Header** -**Secret Value** - -### Step 3: Create a Webhook in Jamf Pro: -Following [official documentation](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/Webhooks.html): -Settings: -* _Webhook URL_ must be in form `https://your-elastic-agent:9202/jamf-pro-events` Note note: `9202` is a port and `/jamf-pro-events` are default values and can be changed this connector's setup. -* _Authentication type_: `None` and `Header Authentication` are supported. -`None` will expect _Webhook URL_ is available with no authorization required, no `secret header` and `secret value` were set on integration setup. -`Header Authentication` will require Auth token name and value set on integration setup - -| Jamf Pro Setting | Corresponding Connector Setting | Value example | -|-------------------------|---------------------------------|---------------------------------------------------| -| _Webhook URL_ | Port + URL | `https://your-elastic-agent:${PORT}${URL}` | -| _Authentication type_ | | Header Authentication | -| _Header Authentication_ | Secret Header + Secret Value | {"Authorization":"${Header}", "Token":"${Value}"} | - -* _Content Type_: `JSON` -* _Webhook Event_: Event to be selected. In case set of events is required, 1:1 webhooks should be created. -Connector provides UI to display `ComputerAdded` and `ComputerCheckIn` events. + +To set up the inventory data stream these three fields are required: +- `api_host` (the Jamf Pro host) +- `client_id` +- `client_secret` + +The events data stream is a passive listener, it should be set up before webhooks are created in the Jamf Pro Dashboard. +The following network settings should be confirmed by an IT or security person: +- Listen Address +- Listen Port +- URL + +Auth settings will be required for the Jamf Pro Webhook settings: +- Secret Header +- Secret Value + +### Step 3: Create Webhooks in Jamf Pro: + +Please follow the Jamf Pro [Webhooks documentation](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/Webhooks.html). + +You will require the following settings: +- **Webhook URL**: must be in form `https://your-elastic-agent:9202/jamf-pro-events` +Note: `9202` is a port and `/jamf-pro-events` are default values and can be changed this connector's setup. + +- **Authentication type**: "None" and "Header Authentication" are supported. +"None" means the (target) Webhook URL is available without authentication, so no secret header or secret value were set during integration policy configuration. +"Header Authentication" will require an auth token name and value, set during integration policy configuration. + +| Jamf Pro setting | Corresponding integration setting | Example value | +|-------------------------|-----------------------------------|-----------------------------------------------------| +| _Webhook URL_ | Port + URL | `https://your-elastic-agent:${PORT}${URL}` | +| _Authentication type_ | | Header Authentication | +| _Header Authentication_ | Secret Header + Secret Value | `{"Authorization":"${Header}", "Token":"${Value}"}` | + +- **Content Type**: `JSON` + +- **Webhook Event**: Event to be selected. In case set of events is required, 1:1 webhooks should be created. ## Logs ### Inventory -Documents from inventory are saved under `logs-*` and can be found on discover page with filtering by `event.dataset :"jamf_pro.inventory"` -By default these sections are included into Jamf API query: - - _GENERAL_ - - _HARDWARE_ - - _OPERATING_SYSTEM_ -All the sections can be enabled or disabled on connector's settings page +Inventory documents can be found in `logs-*` by setting the filter `event.dataset :"jamf_pro.inventory"`. + +By default these sections are included inventory documents: + - `GENERAL` + - `HARDWARE` + - `OPERATING_SYSTEM` + +All the sections can be enabled or disabled on the integration policy settings page. + +Here is an example inventory document: {{event "inventory"}} +The following non-ECS fields are used in inventory documents: + {{fields "inventory"}} ### Events + Documents from events data_stream are saved under `logs-*` and can be found on discover page with filtering by `event.dataset :"jamf_pro.events"` +Here is an example real-time event document: + {{event "events"}} -{{fields "events"}} \ No newline at end of file +The following non-ECS fields are used in real-time event documents: + +{{fields "events"}} diff --git a/packages/jamf_pro/_dev/deploy/docker/files/config.yml b/packages/jamf_pro/_dev/deploy/docker/files/config.yml index a7b0b091c5d7..24432d3569c6 100644 --- a/packages/jamf_pro/_dev/deploy/docker/files/config.yml +++ b/packages/jamf_pro/_dev/deploy/docker/files/config.yml @@ -9,7 +9,12 @@ rules: Content-Type: - 'application/json' body: | - {"access_token":"xxxx","expires_in":3600,"token_type":"Bearer","refresh_token":"yyyy"} + { + "access_token": "xxxx", + "expires_in": 3600, + "token_type": "Bearer", + "refresh_token": "yyyy" + } - path: /api/v1/computers-inventory methods: ["GET"] query_params: @@ -17,10 +22,132 @@ rules: responses: - status_code: 200 body: | - {"totalCount":1,"results":[{"id":"3","udid":"5982CE36-4526-580B-B4B9-ECC6782535BA","general":{"name":"acme-C07DM3AZQ6NV","lastReportedIp":"10.122.26.87","lastIpAddress":"10.122.26.87","jamfBinaryVersion":"11.4.1-t1712591696","platform":"Mac","barcode1":"null","remoteManagement":{"managed":true},"supervised":false,"mdmCapable":{"capable":false,"capableUsers":[]},"reportDate":"2024-06-19T15:54:37.692Z","lastContactTime":"2024-04-18T14:26:51.514Z","lastEnrolledDate":"2023-02-22T10:46:17.199Z","initialEntryDate":"2024-06-19","site":{"id":"-1","name":"None"},"itunesStoreAccountActive":false,"enrolledViaAutomatedDeviceEnrollment":false,"userApprovedMdm":false,"declarativeDeviceManagementEnabled":false,"managementId":"1a59c510-b3a9-41cb-8afa-3d4187ac60d0","extensionAttributes":[]},"diskEncryption":null,"localUserAccounts":null,"purchasing":null,"printers":null,"storage":null,"applications":null,"userAndLocation":null,"configurationProfiles":null,"services":null,"plugins":null,"hardware":null,"certificates":null,"attachments":null,"packageReceipts":null,"fonts":null,"security":null,"operatingSystem":null,"licensedSoftware":null,"softwareUpdates":null,"groupMemberships":null,"extensionAttributes":null,"contentCaching":null,"ibeacons":null}]} + { + "totalCount": 1, + "results": [ + { + "id": "3", + "udid": "5982CE36-4526-580B-B4B9-ECC6782535BA", + "general": { + "name": "acme-C07DM3AZQ6NV", + "lastReportedIp": "10.122.26.87", + "lastIpAddress": "10.122.26.87", + "jamfBinaryVersion": "11.4.1-t1712591696", + "platform": "Mac", + "barcode1": "null", + "remoteManagement": { + "managed": true + }, + "supervised": false, + "mdmCapable": { + "capable": false, + "capableUsers": [] + }, + "reportDate": "2024-06-19T15:54:37.692Z", + "lastContactTime": "2024-04-18T14:26:51.514Z", + "lastEnrolledDate": "2023-02-22T10:46:17.199Z", + "initialEntryDate": "2024-06-19", + "site": { + "id": "-1", + "name": "None" + }, + "itunesStoreAccountActive": false, + "enrolledViaAutomatedDeviceEnrollment": false, + "userApprovedMdm": false, + "declarativeDeviceManagementEnabled": false, + "managementId": "1a59c510-b3a9-41cb-8afa-3d4187ac60d0", + "extensionAttributes": [] + }, + "diskEncryption": null, + "localUserAccounts": null, + "purchasing": null, + "printers": null, + "storage": null, + "applications": null, + "userAndLocation": null, + "configurationProfiles": null, + "services": null, + "plugins": null, + "hardware": null, + "certificates": null, + "attachments": null, + "packageReceipts": null, + "fonts": null, + "security": null, + "operatingSystem": null, + "licensedSoftware": null, + "softwareUpdates": null, + "groupMemberships": null, + "extensionAttributes": null, + "contentCaching": null, + "ibeacons": null + } + ] + } - path: /api/v1/computers-inventory methods: ["GET"] responses: - status_code: 200 body: | - {"totalCount":2,"results":[{"id":"3","udid":"5982CE36-4526-580B-B4B9-ECC6782535BC","general":{"name":"acme-C07DM3AZQ6NV","lastReportedIp":"10.122.26.87","lastIpAddress":"10.122.26.87","jamfBinaryVersion":"11.4.1-t1712591696","platform":"Mac","barcode1":"null","remoteManagement":{"managed":true},"supervised":false,"mdmCapable":{"capable":false,"capableUsers":[]},"reportDate":"2024-06-19T15:54:37.692Z","lastContactTime":"2024-04-18T14:26:51.514Z","lastEnrolledDate":"2023-02-22T10:46:17.199Z","initialEntryDate":"2024-06-19","site":{"id":"-1","name":"None"},"itunesStoreAccountActive":false,"enrolledViaAutomatedDeviceEnrollment":false,"userApprovedMdm":false,"declarativeDeviceManagementEnabled":false,"managementId":"1a59c510-b3a9-41cb-8afa-3d4187ac60d0","extensionAttributes":[]},"diskEncryption":null,"localUserAccounts":null,"purchasing":null,"printers":null,"storage":null,"applications":null,"userAndLocation":null,"configurationProfiles":null,"services":null,"plugins":null,"hardware":null,"certificates":null,"attachments":null,"packageReceipts":null,"fonts":null,"security":null,"operatingSystem":null,"licensedSoftware":null,"softwareUpdates":null,"groupMemberships":null,"extensionAttributes":null,"contentCaching":null,"ibeacons":null}]} + { + "totalCount": 2, + "results": [ + { + "id": "3", + "udid": "5982CE36-4526-580B-B4B9-ECC6782535BC", + "general": { + "name": "acme-C07DM3AZQ6NV", + "lastReportedIp": "10.122.26.87", + "lastIpAddress": "10.122.26.87", + "jamfBinaryVersion": "11.4.1-t1712591696", + "platform": "Mac", + "barcode1": "null", + "remoteManagement": { + "managed": true + }, + "supervised": false, + "mdmCapable": { + "capable": false, + "capableUsers": [] + }, + "reportDate": "2024-06-19T15:54:37.692Z", + "lastContactTime": "2024-04-18T14:26:51.514Z", + "lastEnrolledDate": "2023-02-22T10:46:17.199Z", + "initialEntryDate": "2024-06-19", + "site": { + "id": "-1", + "name": "None" + }, + "itunesStoreAccountActive": false, + "enrolledViaAutomatedDeviceEnrollment": false, + "userApprovedMdm": false, + "declarativeDeviceManagementEnabled": false, + "managementId": "1a59c510-b3a9-41cb-8afa-3d4187ac60d0", + "extensionAttributes": [] + }, + "diskEncryption": null, + "localUserAccounts": null, + "purchasing": null, + "printers": null, + "storage": null, + "applications": null, + "userAndLocation": null, + "configurationProfiles": null, + "services": null, + "plugins": null, + "hardware": null, + "certificates": null, + "attachments": null, + "packageReceipts": null, + "fonts": null, + "security": null, + "operatingSystem": null, + "licensedSoftware": null, + "softwareUpdates": null, + "groupMemberships": null, + "extensionAttributes": null, + "contentCaching": null, + "ibeacons": null + } + ] + } diff --git a/packages/jamf_pro/changelog.yml b/packages/jamf_pro/changelog.yml index 9d5c65c7e175..453a1beebd18 100644 --- a/packages/jamf_pro/changelog.yml +++ b/packages/jamf_pro/changelog.yml @@ -1,3 +1,9 @@ +# newer versions go on top +- version: "0.1.1" + changes: + - description: Various minor improvements and fixes + type: bugfix + link: https://github.com/elastic/integrations/pull/11065 - version: "0.1.0" changes: - description: Initial Release of Jamf Pro integration diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-added.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-added.json-expected.json index 7ce60053fb9f..34e1ac513e0f 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-added.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-added.json-expected.json @@ -63,8 +63,15 @@ "os": { "version": "92.5786" }, + "related": { + "user": [ + "John Doe", + "kghrqq@email.com" + ] + }, "user": { - "email": "kghrqq@email.com" + "email": "kghrqq@email.com", + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-check-in.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-check-in.json-expected.json index 89839c4e5075..8461d7be3986 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-check-in.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-check-in.json-expected.json @@ -66,6 +66,16 @@ }, "os": { "version": "87.2388" + }, + "related": { + "user": [ + "John Doe", + "icpurt@email.com" + ] + }, + "user": { + "email": "icpurt@email.com", + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-inventory-completed.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-inventory-completed.json-expected.json index cb4d4de97036..a85fea15f03f 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-inventory-completed.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-inventory-completed.json-expected.json @@ -63,8 +63,15 @@ "os": { "version": "57.4997" }, + "related": { + "user": [ + "John Doe", + "nadjix@email.com" + ] + }, "user": { - "email": "nadjix@email.com" + "email": "nadjix@email.com", + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-patch-policy-completed.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-patch-policy-completed.json-expected.json index b4fc7b58a95b..39667fb2b921 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-patch-policy-completed.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-patch-policy-completed.json-expected.json @@ -72,6 +72,16 @@ }, "os": { "version": "17.1406" + }, + "related": { + "user": [ + "John Doe", + "febjoz@email.com" + ] + }, + "user": { + "email": "febjoz@email.com", + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-policy-finished.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-policy-finished.json-expected.json index 38197bad4874..626cef636272 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-policy-finished.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-policy-finished.json-expected.json @@ -66,6 +66,16 @@ }, "os": { "version": "37.5296" + }, + "related": { + "user": [ + "John Doe", + "fsekfn@email.com" + ] + }, + "user": { + "email": "fsekfn@email.com", + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-push-capability-changed.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-push-capability-changed.json-expected.json index 88b1427d46bc..ab253f36c716 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-push-capability-changed.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-computer-push-capability-changed.json-expected.json @@ -63,8 +63,15 @@ "os": { "version": "27.2234" }, + "related": { + "user": [ + "John Doe", + "xftowe@email.com" + ] + }, "user": { - "email": "xftowe@email.com" + "email": "xftowe@email.com", + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-check-in.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-check-in.json-expected.json index be8574fb2311..6cddd7da2fac 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-check-in.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-check-in.json-expected.json @@ -60,6 +60,14 @@ }, "os": { "version": "04.8092" + }, + "related": { + "user": [ + "John Doe" + ] + }, + "user": { + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-command-completed.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-command-completed.json-expected.json index 98a4c324724f..556d3474cf20 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-command-completed.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-command-completed.json-expected.json @@ -60,6 +60,14 @@ }, "os": { "version": "99.4028" + }, + "related": { + "user": [ + "John Doe" + ] + }, + "user": { + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-enrolled.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-enrolled.json-expected.json index 7b4918d08eee..323597e41072 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-enrolled.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-enrolled.json-expected.json @@ -60,6 +60,14 @@ }, "os": { "version": "85.9454" + }, + "related": { + "user": [ + "John Doe" + ] + }, + "user": { + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-inventory-completed.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-inventory-completed.json-expected.json index 0f5850c7f672..0a6cf9fcdf01 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-inventory-completed.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-inventory-completed.json-expected.json @@ -60,6 +60,14 @@ }, "os": { "version": "67.8497" + }, + "related": { + "user": [ + "John Doe" + ] + }, + "user": { + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-push-sent.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-push-sent.json-expected.json index 163cc78bc2b5..316a13985429 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-push-sent.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-push-sent.json-expected.json @@ -60,6 +60,14 @@ }, "os": { "version": "11.3415" + }, + "related": { + "user": [ + "John Doe" + ] + }, + "user": { + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-unenrolled.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-unenrolled.json-expected.json index 1b5a8f266440..3a738b9d9c75 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-unenrolled.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-mobile-device-unenrolled.json-expected.json @@ -60,6 +60,14 @@ }, "os": { "version": "34.8068" + }, + "related": { + "user": [ + "John Doe" + ] + }, + "user": { + "name": "John Doe" } } ] diff --git a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-patch-software-title-updated.json-expected.json b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-patch-software-title-updated.json-expected.json index 1050a86b136c..99f25d32f149 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-patch-software-title-updated.json-expected.json +++ b/packages/jamf_pro/data_stream/events/_dev/test/pipeline/test-patch-software-title-updated.json-expected.json @@ -11,7 +11,7 @@ "events": { "event": { "jss_id": 128, - "last_update": 1725443872001, + "last_update": "2024-09-04T09:57:52.001Z", "latest_version": "W97C0H", "name": "ENLOV", "report_urls": "BMH3D0" diff --git a/packages/jamf_pro/data_stream/events/_dev/test/system/test-http-endpoint-config.yml b/packages/jamf_pro/data_stream/events/_dev/test/system/test-http-endpoint-config.yml index ace891ef73ae..5fef1ff94a70 100644 --- a/packages/jamf_pro/data_stream/events/_dev/test/system/test-http-endpoint-config.yml +++ b/packages/jamf_pro/data_stream/events/_dev/test/system/test-http-endpoint-config.yml @@ -10,3 +10,5 @@ data_stream: secret_value: mysecrettoken preserve_original_event: true preserve_duplicate_custom_fields: true +assert: + hit_count: 1 diff --git a/packages/jamf_pro/data_stream/events/agent/stream/http_endpoint.yml.hbs b/packages/jamf_pro/data_stream/events/agent/stream/http_endpoint.yml.hbs index f4c666e78bd1..06bc99f816c9 100644 --- a/packages/jamf_pro/data_stream/events/agent/stream/http_endpoint.yml.hbs +++ b/packages/jamf_pro/data_stream/events/agent/stream/http_endpoint.yml.hbs @@ -1,6 +1,7 @@ listen_address: {{listen_address}} listen_port: {{listen_port}} url: {{url}} +prefix: json {{#if secret_header}} secret.header: {{secret_header}} {{/if}} @@ -32,4 +33,4 @@ ssl: {{ssl}} {{#if processors}} processors: {{processors}} -{{/if}} \ No newline at end of file +{{/if}} diff --git a/packages/jamf_pro/data_stream/events/elasticsearch/ingest_pipeline/default.yml b/packages/jamf_pro/data_stream/events/elasticsearch/ingest_pipeline/default.yml index 71c3130ea4a4..7482a8b411dd 100644 --- a/packages/jamf_pro/data_stream/events/elasticsearch/ingest_pipeline/default.yml +++ b/packages/jamf_pro/data_stream/events/elasticsearch/ingest_pipeline/default.yml @@ -1,6 +1,7 @@ --- description: Pipeline for processing sample logs processors: + - set: field: ecs.version value: '8.11.0' @@ -8,17 +9,19 @@ processors: - rename: field: json target_field: jamf_pro.events - if: ctx.json != null + # all valid events will now have jamf_pro.events.{event,webhook} - convert: field: jamf_pro.events.event.management_id type: string - if: "ctx.jamf_pro.events.event?.management_id != null && !(ctx.jamf_pro.events.event?.management_id instanceof String)" + if: > + ctx.jamf_pro.events.event?.management_id != null && + !(ctx.jamf_pro.events.event.management_id instanceof String) - rename: field: jamf_pro.events.event.computer target_field: jamf_pro.events.event.is_computer - if: (ctx.jamf_pro.events.event.computer === true || ctx.jamf_pro.events.event.computer === false) + if: ctx.jamf_pro.events.event.computer instanceof boolean - script: description: Convert Additional Info keys to snake case. @@ -49,15 +52,15 @@ processors: } return snakeCaseMap; } - + if(ctx.jamf_pro.events != null) { ctx.jamf_pro.events = keysToSnakeCase(ctx.jamf_pro.events); } - ############## # Timestamps # ############## + - date: field: jamf_pro.events.webhook.event_timestamp target_field: jamf_pro.events.webhook.event_timestamp @@ -67,44 +70,47 @@ processors: - date: field: jamf_pro.events.event.last_update target_field: jamf_pro.events.event.last_update - if: "ctx.jamf_pro.events?.last_update != null" + if: ctx.jamf_pro.events.event.last_update != null formats: - UNIX_MS - + ############## # IP src # ############## - set: - if: "ctx.jamf_pro.events.event?.ip_address != null && ctx.jamf_pro.events.event?.ip_address != ''" + if: "ctx.jamf_pro.events.event.ip_address != null && ctx.jamf_pro.events.event.ip_address != ''" field: host.ip value: - '{{{jamf_pro.events.event.ip_address}}}' ignore_empty_value: true - set: - if: "ctx.jamf_pro.events.event?.computer != null && ctx.jamf_pro.events.event?.computer?.reported_ip_address != null && ctx.jamf_pro.events.event?.computer?.reported_ip_address != ''" + if: > + ctx.jamf_pro.events.event.computer?.reported_ip_address != null && + ctx.jamf_pro.events.event.computer.reported_ip_address != '' field: host.ip value: - - "{{jamf_pro.events.event.computer.reported_ip_address}}" + - "{{{jamf_pro.events.event.computer.reported_ip_address}}}" ignore_empty_value: true ############## # User src # ############## + - set: field: user.name - copy_from: jamf_pro.events.event?.username + copy_from: jamf_pro.events.event.username ignore_empty_value: true - set: field: user.name - copy_from: jamf_pro.events.event.?computer.username + copy_from: jamf_pro.events.event.computer.username ignore_empty_value: true - set: field: user.email - copy_from: jamf_pro.events.event.?computer.email_address + copy_from: jamf_pro.events.event.computer.email_address ignore_empty_value: true - set: @@ -117,12 +123,12 @@ processors: ############## - set: - if: ctx.jamf_pro.events.event?.os_version != null + if: ctx.jamf_pro.events.event.os_version != null field: os.version copy_from: jamf_pro.events.event.os_version - set: - if: ctx.jamf_pro.events.event?.computer?.os_version != null + if: ctx.jamf_pro.events.event.computer?.os_version != null field: os.version copy_from: jamf_pro.events.event.computer.os_version @@ -137,20 +143,28 @@ processors: ignore_empty_value: true - geoip: - if: ctx.host?.ip != null && ctx.host?.ip != '' + if: ctx.host?.ip != null && ctx.host.ip != '' field: host.ip target_field: host.geo ignore_missing: true -- set: +- append: field: related.user - copy_from: user.name - ignore_empty_value: true + value: "{{{user.name}}}" + if: ctx.user?.name != null && ctx.user.name != "" + +- append: + field: related.user + value: "{{{user.email}}}" + if: ctx.user?.email != null && ctx.user.email != "" - set: field: event.kind value: event +################## +# Error handling # +################## on_failure: - set: @@ -159,4 +173,3 @@ on_failure: - append: field: error.message value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}' - diff --git a/packages/jamf_pro/data_stream/events/sample_event.json b/packages/jamf_pro/data_stream/events/sample_event.json index 50b3db4b4985..af2ef4bb8556 100644 --- a/packages/jamf_pro/data_stream/events/sample_event.json +++ b/packages/jamf_pro/data_stream/events/sample_event.json @@ -1,29 +1,29 @@ { - "@timestamp": "2024-09-06T17:08:38.976Z", + "@timestamp": "2024-09-10T16:37:20.274Z", "agent": { - "ephemeral_id": "38f21e3b-5732-4f42-ab13-98df7888bfec", - "id": "7aa8a892-09c3-46be-a0ae-180627b773b8", - "name": "elastic-agent-85919", + "ephemeral_id": "65fb36ce-0e96-4f1f-99fe-5a19a14acfa1", + "id": "920d1c20-a89f-4166-b97e-42186275db28", + "name": "elastic-agent-21773", "type": "filebeat", - "version": "8.13.4" + "version": "8.14.3" }, "data_stream": { "dataset": "jamf_pro.events", - "namespace": "17929", + "namespace": "75060", "type": "logs" }, "ecs": { "version": "8.11.0" }, "elastic_agent": { - "id": "7aa8a892-09c3-46be-a0ae-180627b773b8", + "id": "920d1c20-a89f-4166-b97e-42186275db28", "snapshot": false, - "version": "8.13.4" + "version": "8.14.3" }, "event": { "agent_id_status": "verified", "dataset": "jamf_pro.events", - "ingested": "2024-09-06T17:08:39Z", + "ingested": "2024-09-10T16:37:21Z", "kind": "event", "original": "{\"event\":{\"alternateMacAddress\":\"be:aa:e5:54:94:db\",\"building\":\"1S8NPV\",\"department\":\"XDO4C5\",\"deviceName\":\"VPNYC\",\"emailAddress\":\"kghrqq@email.com\",\"ipAddress\":\"89.160.20.156\",\"jssID\":\"1500747557\",\"macAddress\":\"be:aa:e5:54:94:db\",\"managementId\":\"6319330669\",\"model\":\"LJ68RT\",\"osBuild\":\"26.6913\",\"osVersion\":\"92.5786\",\"phone\":\"2183546\",\"position\":\"B64JIO\",\"realName\":\"CPK79\",\"reportedIpAddress\":\"89.160.20.156\",\"room\":\"HQC6S9\",\"serialNumber\":\"7967177\",\"udid\":\"7265694772\",\"userDirectory_id\":\"0389771137\",\"username\":\"John Doe\"},\"webhook\":{\"eventTimestamp\":1725443872001,\"id\":\"8131946016\",\"name\":\"PU17M\",\"webhookEvent\":\"ComputerAdded\"}}" }, @@ -86,6 +86,12 @@ "os": { "version": "92.5786" }, + "related": { + "user": [ + "John Doe", + "kghrqq@email.com" + ] + }, "tags": [ "preserve_original_event", "preserve_duplicate_custom_fields", @@ -93,6 +99,7 @@ "jamf_pro-events" ], "user": { - "email": "kghrqq@email.com" + "email": "kghrqq@email.com", + "name": "John Doe" } } \ No newline at end of file diff --git a/packages/jamf_pro/data_stream/inventory/agent/stream/cel.yml.hbs b/packages/jamf_pro/data_stream/inventory/agent/stream/cel.yml.hbs index 693689b32b26..e4620184afe1 100644 --- a/packages/jamf_pro/data_stream/inventory/agent/stream/cel.yml.hbs +++ b/packages/jamf_pro/data_stream/inventory/agent/stream/cel.yml.hbs @@ -14,7 +14,7 @@ auth: secret: {{client_secret}} token_url: "{{api_host}}/api/oauth/token" endpoint_params: - grant_type: "client_credentials" + grant_type: "client_credentials" interval: {{interval}} max_executions: {{max_executions}} @@ -30,119 +30,127 @@ publisher_pipeline.disable_host: true {{/contains}} keep_null: true -program: | +program: |- request( - "GET", - state.url.trim_right("/") + "?" + { - "section" : state.sections, - "page-size": [string(state.page_size)], - "sort": ["general.reportDate:asc"], - ?"filter": has(state.?cursor.last_report_date) && (state.?cursor.last_report_date.orValue("") != "") ? - optional.of(['general.reportDate>="'+state.cursor.last_report_date+'"']) - : - optional.none(), - }.format_query() - ).with({ - "Header": ({ - "Content-Type": ["application/json"] - }) - }).do_request().as(resp, - bytes(resp.Body).decode_json().as(body, - resp.StatusCode != 200 ? - { - "events": [{ - "error": { "message": "response: " + string(resp.StatusCode) }, - "event": { "original": resp.Body } - }] - } - : - state.with({ - "events": body.results.map(e, { - "message": e, - ?"event.original": state.?preserve_original_event.orValue(false) ? optional.of(e.encode_json()) : optional.none() - }), - "want_more": body.totalCount > size(body.results), - "cursor": { - "last_report_date": ((size(body.results) == 0 ) || (size(body.results) == body.totalCount))? - state.?cursor.last_report_date.orValue("") : - string(body.results[size(body.results)-1].general.reportDate) - }, - }) - ) + "GET", + state.url.trim_right("/") + "?" + { + "section": state.sections, + "page-size": [string(state.page_size)], + "sort": ["general.reportDate:asc"], + ?"filter": (has(state.?cursor.last_report_date) && state.?cursor.last_report_date.orValue("") != "") ? + optional.of(["general.reportDate>=\"" + state.cursor.last_report_date + "\""]) + : + optional.none(), + }.format_query() + ).with( + { + "Header": { + "Content-Type": ["application/json"], + }, + } + ).do_request().as(resp, + bytes(resp.Body).decode_json().as(body, (resp.StatusCode != 200) ? + { + "events": [ + { + "error": {"message": "response: " + string(resp.StatusCode)}, + "event": {"original": resp.Body}, + }, + ], + } + : + state.with( + { + "events": body.results.map(e, + { + "message": e, + ?"event.original": state.?preserve_original_event.orValue(false) ? optional.of(e.encode_json()) : optional.none(), + } + ), + "want_more": body.totalCount > size(body.results), + "cursor": { + "last_report_date": (size(body.results) == 0 || size(body.results) == body.totalCount) ? + state.?cursor.last_report_date.orValue("") + : + string(body.results[size(body.results) - 1].general.reportDate), + }, + } + ) + ) ) state: preserve_original_event: {{preserve_original_event}} page_size: {{page_size}} sections: - {{#if enable_section_general }} + {{#if enable_section_general }} - GENERAL {{/if}} - {{#if enable_section_hardware }} + {{#if enable_section_hardware }} - HARDWARE {{/if}} - {{#if enable_section_operating_system }} + {{#if enable_section_operating_system }} - OPERATING_SYSTEM {{/if}} - {{#if enable_section_disk_encryption }} + {{#if enable_section_disk_encryption }} - DISK_ENCRYPTION {{/if}} - {{#if enable_section_purchasing }} + {{#if enable_section_purchasing }} - PURCHASING {{/if}} - {{#if enable_section_applications }} + {{#if enable_section_applications }} - APPLICATIONS {{/if}} - {{#if enable_section_storage }} + {{#if enable_section_storage }} - STORAGE {{/if}} - {{#if enable_section_user_and_location }} + {{#if enable_section_user_and_location }} - USER_AND_LOCATION {{/if}} - {{#if enable_section_configuration_profiles }} + {{#if enable_section_configuration_profiles }} - CONFIGURATION_PROFILES {{/if}} - {{#if enable_section_printers }} + {{#if enable_section_printers }} - PRINTERS {{/if}} - {{#if enable_section_services }} + {{#if enable_section_services }} - SERVICES {{/if}} - {{#if enable_section_local_user_accounts }} + {{#if enable_section_local_user_accounts }} - LOCAL_USER_ACCOUNTS {{/if}} - {{#if enable_section_certificates }} + {{#if enable_section_certificates }} - CERTIFICATES {{/if}} - {{#if enable_section_attachments }} + {{#if enable_section_attachments }} - ATTACHMENTS {{/if}} - {{#if enable_section_plugins }} + {{#if enable_section_plugins }} - PLUGINS {{/if}} - {{#if enable_section_package_receipts }} + {{#if enable_section_package_receipts }} - PACKAGE_RECEIPTS {{/if}} - {{#if enable_section_fonts }} + {{#if enable_section_fonts }} - FONTS {{/if}} - {{#if enable_section_security }} + {{#if enable_section_security }} - SECURITY {{/if}} - {{#if enable_section_licensed_software }} + {{#if enable_section_licensed_software }} - LICENSED_SOFTWARE {{/if}} - {{#if enable_section_ibeacons }} + {{#if enable_section_ibeacons }} - IBEACONS {{/if}} - {{#if enable_section_software_updates }} + {{#if enable_section_software_updates }} - SOFTWARE_UPDATES {{/if}} - {{#if enable_section_extension_attributes }} + {{#if enable_section_extension_attributes }} - EXTENSION_ATTRIBUTES {{/if}} - {{#if enable_section_content_caching }} + {{#if enable_section_content_caching }} - CONTENT_CACHING {{/if}} - {{#if enable_section_group_memberships }} + {{#if enable_section_group_memberships }} - GROUP_MEMBERSHIPS {{/if}} diff --git a/packages/jamf_pro/data_stream/inventory/elasticsearch/ingest_pipeline/default.yml b/packages/jamf_pro/data_stream/inventory/elasticsearch/ingest_pipeline/default.yml index 3b6129b43b58..5e3631f56aa6 100644 --- a/packages/jamf_pro/data_stream/inventory/elasticsearch/ingest_pipeline/default.yml +++ b/packages/jamf_pro/data_stream/inventory/elasticsearch/ingest_pipeline/default.yml @@ -1,29 +1,29 @@ --- -description: Processing inventory data from Jamf Pro API +description: Process inventory data from the Jamf Pro API processors: -- fingerprint: - if: ctx.udid != null - fields: - - udid - target_field: "_id" - ignore_missing: true + - rename: field: message target_field: jamf_pro.inventory - + +- fingerprint: + fields: + - jamf_pro.inventory.udid + target_field: "_id" + - script: description: Drops null/empty values recursively. lang: painless source: | boolean dropEmptyFields(Object object) { if (object == null || object == "") { - return true; + return true; } else if (object instanceof Map) { - ((Map) object).values().removeIf(value -> dropEmptyFields(value)); - return (((Map) object).size() == 0); + ((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); + ((List) object).removeIf(value -> dropEmptyFields(value)); + return (((List) object).length == 0); } return false; } @@ -58,8 +58,8 @@ processors: } return snakeCaseMap; } - - if(ctx.jamf_pro.inventory != null) { + + if (ctx.jamf_pro.inventory != null) { ctx.jamf_pro.inventory = keysToSnakeCase(ctx.jamf_pro.inventory); } @@ -76,17 +76,16 @@ processors: ############## - append: - if: "ctx?.jamf_pro.inventory.general != null && ctx?.jamf_pro.inventory.general.last_ip_address != ''" + if: "ctx.jamf_pro.inventory.general != null && ctx.jamf_pro.inventory.general.last_ip_address != ''" field: host.ip value: '{{{jamf_pro.inventory.general.last_ip_address}}}' ignore_failure: true - - set: field: host.address copy_from: host.ip ignore_empty_value: true - append: - if: "ctx?.jamf_pro.inventory.hardware != null && ctx?.jamf_pro.inventory.hardware.mac_address != ''" + if: "ctx.jamf_pro.inventory.hardware != null && ctx.jamf_pro.inventory.hardware.mac_address != ''" field: host.mac value: '{{{jamf_pro.inventory.hardware.mac_address}}}' ignore_failure: true @@ -138,12 +137,15 @@ processors: - append: field: event.type value: user - if: ctx.jamf_pro.inventory?.user_and_location != null - + if: ctx.jamf_pro.inventory.user_and_location != null - append: field: event.type - value: device - if: ctx.jamf_pro.inventory?.hardware != null + value: info + if: ctx.jamf_pro.inventory.hardware != null + +################## +# Error handling # +################## on_failure: - set: @@ -152,4 +154,3 @@ on_failure: - append: field: error.message value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}' - diff --git a/packages/jamf_pro/data_stream/inventory/sample_event.json b/packages/jamf_pro/data_stream/inventory/sample_event.json index 8cfec4f4dc53..b927fd20fb1a 100644 --- a/packages/jamf_pro/data_stream/inventory/sample_event.json +++ b/packages/jamf_pro/data_stream/inventory/sample_event.json @@ -1,29 +1,29 @@ { - "@timestamp": "2024-09-06T17:11:03.384Z", + "@timestamp": "2024-09-10T16:38:08.084Z", "agent": { - "ephemeral_id": "606e214f-a4ba-4d60-a509-e92dce3aea7b", - "id": "5c020b93-46b5-432b-8bf0-e5c708b598d2", - "name": "elastic-agent-58789", + "ephemeral_id": "032b2039-1b4d-4eae-b52c-d08936b47ca5", + "id": "ba358bea-2bfe-4de2-9315-576d52fe94fc", + "name": "elastic-agent-46649", "type": "filebeat", - "version": "8.13.4" + "version": "8.14.3" }, "data_stream": { "dataset": "jamf_pro.inventory", - "namespace": "31710", + "namespace": "72595", "type": "logs" }, "ecs": { "version": "8.11.0" }, "elastic_agent": { - "id": "5c020b93-46b5-432b-8bf0-e5c708b598d2", + "id": "ba358bea-2bfe-4de2-9315-576d52fe94fc", "snapshot": false, - "version": "8.13.4" + "version": "8.14.3" }, "event": { "agent_id_status": "verified", "dataset": "jamf_pro.inventory", - "ingested": "2024-09-06T17:11:06Z", + "ingested": "2024-09-10T16:38:11Z", "kind": "asset" }, "host": { diff --git a/packages/jamf_pro/docs/README.md b/packages/jamf_pro/docs/README.md index f66f18592db0..902450c9d558 100644 --- a/packages/jamf_pro/docs/README.md +++ b/packages/jamf_pro/docs/README.md @@ -1,4 +1,3 @@ - # Jamf Pro integration Jamf Pro is a comprehensive management solution designed to help organizations deploy, configure, secure, and manage Apple devices. This integration enables organizations to seamlessly monitor and protect their Mac fleet through Elastic, providing a unified view of security events across all endpoints and facilitating a more effective response to threats. This integration encompasses both event and inventory data ingestion from Jamf Pro. @@ -6,116 +5,130 @@ Jamf Pro is a comprehensive management solution designed to help organizations d ## Data streams - * __inventory__ provides Inventory data for computers. Includes: hardware, OS, etc. Saves each device as a separate log record. - This data stream utilizes `/v1/computers-inventory` endpoint from Jamf Pro API. +- **`inventory`** Provides Inventory data for computers. Includes: hardware, OS, etc. Saves each device as a separate log record. +This data stream utilizes the Jamf Pro API's `/v1/computers-inventory` endpoint. -* __events__ catches events, generated by [Jamf Pro Webhooks](https://developer.jamf.com/developer-guide/docs/webhooks) This datastream requires opening a port on kibana system +- **`events`** Receives events sent by [Jamf Pro Webhooks](https://developer.jamf.com/developer-guide/docs/webhooks). +This data stream requires opening a port on the Elastic Agent host. ## Requirements -### Inventory +#### Inventory -* __Jamf Pro Active License and OAuth2 Credentials:__ -This connector utilizes Jamf Pro API, therefore active license- Jamf __Business__ or __Enterprise__ is a requirement(Jamf __Now__ doesn't have access to API) +- **Jamf Pro Active License and OAuth2 Credentials** +This connector utilizes Jamf Pro API, therefore an active license - either Jamf **Business** or **Enterprise** - is required (Jamf _**Now**_ does not have access to the API) -### Events +#### Events -* __HTTP(S) Port opened for connection:__ On setting up the data_stream a port should be defined (9202 by default). To run the listener this port on host must be available from Jamf server. +- **HTTP(S) port open for incoming connections** +A port for incoming connections (`9202` by default) will be set during policy configuration. This port on host must be accessible from the Jamf server. + +- **Jamf Pro webhooks** +Please refer to the Jamf Pro documentation about [Setting up webhooks](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/Webhooks.html). +**NOTE**: For HTTPS usage, a valid, trusted certificate is essential; Jamf Pro webhooks cannot accept a self-signed certificate. If necessary, the HTTP protocol may serve as a fallback option. Although Jamf Pro webhooks do not require HTTPS, its use is strongly recommended for security reasons. -* __Jamf Pro webhooks__ -[Setting up webhooks ](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/Webhooks.html) in Jamf Pro Dashboard. -__NOTE__: For HTTPS usage, a valid verified certificate is essential; Jamf Pro webhooks cannot accept a self-signed certificate. If necessary, the HTTP protocol may serve as a fallback option. Although Jamf Pro webhooks do not require HTTPS, its use is strongly recommended for security reasons. ## Setup ### Step 1: Create an Application in Jamf Pro: -To create a connection to Jamf Pro, an [application must be created](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/API_Roles_and_Clients.html) first. -Credentials generated during this process are required for the subsequent steps. +To create a connection to Jamf Pro, an [application must be created](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/API_Roles_and_Clients.html) first. Credentials generated during this process are required for the subsequent steps. + +**Permissions required by the Jamf Pro application**: +- **Read Computer Inventory Collection**: Access to read inventory data from the computer collection. +- **Read Computers**: Allows the application to access and read data from computers. -__Permission required for Jamf Pro application__ -- _Read Computer Inventory Collection_: Access to read inventory data from the computer collection. -- _Read Computers_: Allows the application to access and read data from computers. -__Jamf Pro API Credentials__ -**client_id** is an app specific ID, it is generated on createin step and available from app settings -**client_secret** generated after app is created, it is available only after creation. Can be regenerated if lost. +**Jamf Pro API Credentials** +- **`client_id`** is an app specific ID generated during app creation, and is available in the app settings. +- **`client_secret`** is only available once after app creation. Can be regenerated if lost. Permissions can be set up on app creation or can be updated for existing app ### Step 2: Integration Setup: -To set up the *Inventory* data stream these three fields are required: -- jamf_pro host -- cliet_id -- client_secret -*Events* data_stream is a passive listener, it should be created before webhook will be created at Jamf Pro Dashboard. -Network settings should be defined by IT or Security person: -**Listen Address** -**Listen Port** -**URL** -Auth settings will be required on Jamf Pro Webhook settings: -**Secret Header** -**Secret Value** - -### Step 3: Create a Webhook in Jamf Pro: -Following [official documentation](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/Webhooks.html): -Settings: -* _Webhook URL_ must be in form `https://your-elastic-agent:9202/jamf-pro-events` Note note: `9202` is a port and `/jamf-pro-events` are default values and can be changed this connector's setup. -* _Authentication type_: `None` and `Header Authentication` are supported. -`None` will expect _Webhook URL_ is available with no authorization required, no `secret header` and `secret value` were set on integration setup. -`Header Authentication` will require Auth token name and value set on integration setup - -| Jamf Pro Setting | Corresponding Connector Setting | Value example | -|-------------------------|---------------------------------|---------------------------------------------------| -| _Webhook URL_ | Port + URL | `https://your-elastic-agent:${PORT}${URL}` | -| _Authentication type_ | | Header Authentication | -| _Header Authentication_ | Secret Header + Secret Value | {"Authorization":"${Header}", "Token":"${Value}"} | - -* _Content Type_: `JSON` -* _Webhook Event_: Event to be selected. In case set of events is required, 1:1 webhooks should be created. -Connector provides UI to display `ComputerAdded` and `ComputerCheckIn` events. + +To set up the inventory data stream these three fields are required: +- `api_host` (the Jamf Pro host) +- `client_id` +- `client_secret` + +The events data stream is a passive listener, it should be set up before webhooks are created in the Jamf Pro Dashboard. +The following network settings should be confirmed by an IT or security person: +- Listen Address +- Listen Port +- URL + +Auth settings will be required for the Jamf Pro Webhook settings: +- Secret Header +- Secret Value + +### Step 3: Create Webhooks in Jamf Pro: + +Please follow the Jamf Pro [Webhooks documentation](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/Webhooks.html). + +You will require the following settings: +- **Webhook URL**: must be in form `https://your-elastic-agent:9202/jamf-pro-events` +Note: `9202` is a port and `/jamf-pro-events` are default values and can be changed this connector's setup. + +- **Authentication type**: "None" and "Header Authentication" are supported. +"None" means the (target) Webhook URL is available without authentication, so no secret header or secret value were set during integration policy configuration. +"Header Authentication" will require an auth token name and value, set during integration policy configuration. + +| Jamf Pro setting | Corresponding integration setting | Example value | +|-------------------------|-----------------------------------|-----------------------------------------------------| +| _Webhook URL_ | Port + URL | `https://your-elastic-agent:${PORT}${URL}` | +| _Authentication type_ | | Header Authentication | +| _Header Authentication_ | Secret Header + Secret Value | `{"Authorization":"${Header}", "Token":"${Value}"}` | + +- **Content Type**: `JSON` + +- **Webhook Event**: Event to be selected. In case set of events is required, 1:1 webhooks should be created. ## Logs ### Inventory -Documents from inventory are saved under `logs-*` and can be found on discover page with filtering by `event.dataset :"jamf_pro.inventory"` -By default these sections are included into Jamf API query: - - _GENERAL_ - - _HARDWARE_ - - _OPERATING_SYSTEM_ -All the sections can be enabled or disabled on connector's settings page +Inventory documents can be found in `logs-*` by setting the filter `event.dataset :"jamf_pro.inventory"`. + +By default these sections are included inventory documents: + - `GENERAL` + - `HARDWARE` + - `OPERATING_SYSTEM` + +All the sections can be enabled or disabled on the integration policy settings page. + +Here is an example inventory document: An example event for `inventory` looks as following: ```json { - "@timestamp": "2024-09-06T17:11:03.384Z", + "@timestamp": "2024-09-10T16:38:08.084Z", "agent": { - "ephemeral_id": "606e214f-a4ba-4d60-a509-e92dce3aea7b", - "id": "5c020b93-46b5-432b-8bf0-e5c708b598d2", - "name": "elastic-agent-58789", + "ephemeral_id": "032b2039-1b4d-4eae-b52c-d08936b47ca5", + "id": "ba358bea-2bfe-4de2-9315-576d52fe94fc", + "name": "elastic-agent-46649", "type": "filebeat", - "version": "8.13.4" + "version": "8.14.3" }, "data_stream": { "dataset": "jamf_pro.inventory", - "namespace": "31710", + "namespace": "72595", "type": "logs" }, "ecs": { "version": "8.11.0" }, "elastic_agent": { - "id": "5c020b93-46b5-432b-8bf0-e5c708b598d2", + "id": "ba358bea-2bfe-4de2-9315-576d52fe94fc", "snapshot": false, - "version": "8.13.4" + "version": "8.14.3" }, "event": { "agent_id_status": "verified", "dataset": "jamf_pro.inventory", - "ingested": "2024-09-06T17:11:06Z", + "ingested": "2024-09-10T16:38:11Z", "kind": "asset" }, "host": { @@ -180,6 +193,8 @@ An example event for `inventory` looks as following: } ``` +The following non-ECS fields are used in inventory documents: + **Exported fields** | Field | Description | Type | @@ -361,37 +376,40 @@ An example event for `inventory` looks as following: ### Events + Documents from events data_stream are saved under `logs-*` and can be found on discover page with filtering by `event.dataset :"jamf_pro.events"` +Here is an example real-time event document: + An example event for `events` looks as following: ```json { - "@timestamp": "2024-09-06T17:08:38.976Z", + "@timestamp": "2024-09-10T16:37:20.274Z", "agent": { - "ephemeral_id": "38f21e3b-5732-4f42-ab13-98df7888bfec", - "id": "7aa8a892-09c3-46be-a0ae-180627b773b8", - "name": "elastic-agent-85919", + "ephemeral_id": "65fb36ce-0e96-4f1f-99fe-5a19a14acfa1", + "id": "920d1c20-a89f-4166-b97e-42186275db28", + "name": "elastic-agent-21773", "type": "filebeat", - "version": "8.13.4" + "version": "8.14.3" }, "data_stream": { "dataset": "jamf_pro.events", - "namespace": "17929", + "namespace": "75060", "type": "logs" }, "ecs": { "version": "8.11.0" }, "elastic_agent": { - "id": "7aa8a892-09c3-46be-a0ae-180627b773b8", + "id": "920d1c20-a89f-4166-b97e-42186275db28", "snapshot": false, - "version": "8.13.4" + "version": "8.14.3" }, "event": { "agent_id_status": "verified", "dataset": "jamf_pro.events", - "ingested": "2024-09-06T17:08:39Z", + "ingested": "2024-09-10T16:37:21Z", "kind": "event", "original": "{\"event\":{\"alternateMacAddress\":\"be:aa:e5:54:94:db\",\"building\":\"1S8NPV\",\"department\":\"XDO4C5\",\"deviceName\":\"VPNYC\",\"emailAddress\":\"kghrqq@email.com\",\"ipAddress\":\"89.160.20.156\",\"jssID\":\"1500747557\",\"macAddress\":\"be:aa:e5:54:94:db\",\"managementId\":\"6319330669\",\"model\":\"LJ68RT\",\"osBuild\":\"26.6913\",\"osVersion\":\"92.5786\",\"phone\":\"2183546\",\"position\":\"B64JIO\",\"realName\":\"CPK79\",\"reportedIpAddress\":\"89.160.20.156\",\"room\":\"HQC6S9\",\"serialNumber\":\"7967177\",\"udid\":\"7265694772\",\"userDirectory_id\":\"0389771137\",\"username\":\"John Doe\"},\"webhook\":{\"eventTimestamp\":1725443872001,\"id\":\"8131946016\",\"name\":\"PU17M\",\"webhookEvent\":\"ComputerAdded\"}}" }, @@ -454,6 +472,12 @@ An example event for `events` looks as following: "os": { "version": "92.5786" }, + "related": { + "user": [ + "John Doe", + "kghrqq@email.com" + ] + }, "tags": [ "preserve_original_event", "preserve_duplicate_custom_fields", @@ -461,11 +485,14 @@ An example event for `events` looks as following: "jamf_pro-events" ], "user": { - "email": "kghrqq@email.com" + "email": "kghrqq@email.com", + "name": "John Doe" } } ``` +The following non-ECS fields are used in real-time event documents: + **Exported fields** | Field | Description | Type | @@ -596,3 +623,4 @@ An example event for `events` looks as following: | jamf_pro.events.webhook.id | | integer | | jamf_pro.events.webhook.name | | keyword | | jamf_pro.events.webhook.webhook_event | | keyword | + diff --git a/packages/jamf_pro/kibana/dashboard/jamf_pro-90cf12f3-9a11-466b-8c28-5a07a85bc038.json b/packages/jamf_pro/kibana/dashboard/jamf_pro-90cf12f3-9a11-466b-8c28-5a07a85bc038.json old mode 100755 new mode 100644 diff --git a/packages/jamf_pro/manifest.yml b/packages/jamf_pro/manifest.yml index 230efc5053b9..474e18bd44e4 100644 --- a/packages/jamf_pro/manifest.yml +++ b/packages/jamf_pro/manifest.yml @@ -1,10 +1,10 @@ format_version: 3.1.5 name: jamf_pro title: "Jamf Pro" -version: 0.1.0 +version: 0.1.1 source: license: "Elastic-2.0" -description: "A connector for Jamf Pro API" +description: "Collect logs and inventory data from Jamf Pro with Elastic Agent" type: integration categories: - cloud