AutomationFlows β€Ί Slack & Telegram β€Ί Monitor Jamf Policy Integrity and Send Slack Alerts for Changes

Monitor Jamf Policy Integrity and Send Slack Alerts for Changes

ByJean-Marie Rizkallah @mrrobotβœ“ on n8n.io

πŸ›‘οΈ Jamf Policy Integrity Monitor

Webhook triggerβ˜…β˜…β˜…β˜…β˜† complexity23 nodesCryptoData TableHTTP RequestXMLSlack
Slack & Telegram Trigger: Webhook Nodes: 23 Complexity: β˜…β˜…β˜…β˜…β˜† Added:

This workflow corresponds to n8n.io template #9287 β€” we link there as the canonical source.

This workflow follows the Datatable β†’ HTTP Request recipe pattern β€” see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide β†’

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "b944be24-1707-46da-8df2-7279dc87beea",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -288,
        336
      ],
      "parameters": {
        "path": "78761599-3932-41f1-9668-fd019bd40680",
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "e383809e-c269-4965-8594-d9c0d0a558f5",
      "name": "IDs",
      "type": "n8n-nodes-base.set",
      "position": [
        96,
        160
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "2a4c891d-1f1a-4c5b-9b15-9fbbc40f438e",
              "name": "jamf_policy_id1",
              "type": "string",
              "value": "86"
            },
            {
              "id": "479ac09d-f561-4c92-ae7b-840dbc261747",
              "name": "jamf_policy_id2",
              "type": "string",
              "value": "88"
            },
            {
              "id": "836034ea-5a17-4741-a7c2-cefdbc426b49",
              "name": "jamf_policy_id3",
              "type": "string",
              "value": "148"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "db2c7535-cbfd-42af-9431-ec6c9a1ce9a8",
      "name": "Split groups",
      "type": "n8n-nodes-base.code",
      "position": [
        288,
        160
      ],
      "parameters": {
        "jsCode": "const policy = items[0].json;\nconst result = [];\n\nfor (const key in policy) {\n  result.push({\n    json: {\n      key,\n      value: policy[key]\n    }\n  });\n}\n\nreturn result;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "4cfb00a3-8350-41ca-a02b-dc0467c4e208",
      "name": "Jamf Server",
      "type": "n8n-nodes-base.set",
      "position": [
        -80,
        160
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d5945b47-962f-4cea-8bb8-a8f61ee468ec",
              "name": "server",
              "type": "string",
              "value": ""
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c2348a64-e068-433d-9857-2d353828276e",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -288,
        160
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c7c8fed1-8bd1-445b-a32d-05d54c3e93e2",
      "name": "Hash_policy",
      "type": "n8n-nodes-base.crypto",
      "position": [
        880,
        160
      ],
      "parameters": {
        "type": "SHA256",
        "value": "={{JSON.stringify($json.policy)}}"
      },
      "typeVersion": 1
    },
    {
      "id": "044ba5a6-26dc-49d6-87c6-7f7931d6fab4",
      "name": "Condition hash Diff",
      "type": "n8n-nodes-base.if",
      "position": [
        1376,
        240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "305d116d-8d46-4dd0-bb7c-a20875dc1f07",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.hash }}",
              "rightValue": "={{ $('Hash_policy').item.json.data }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d34c5b21-6e2b-45c5-82d9-b0cc9421b9bd",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        -32
      ],
      "parameters": {
        "width": 320,
        "height": 404,
        "content": "## Set\n**Node: Jamf Server**\nSet your jamf BaseURL from your jamf URL\nhttps://yourServer.jamfcloud.com\n\n**Node: IDs**\nSet the policy ID to monitor"
      },
      "typeVersion": 1
    },
    {
      "id": "48807bc8-d4d2-4764-b34c-c10452d68420",
      "name": "Update Hash",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1648,
        224
      ],
      "parameters": {
        "columns": {
          "value": {
            "hash": "={{ $('Hash_policy').item.json.data }}"
          },
          "schema": [
            {
              "id": "policy_id",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "policy_id",
              "defaultMatch": false
            },
            {
              "id": "policy_name",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "policy_name",
              "defaultMatch": false
            },
            {
              "id": "hash",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "hash",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyName": "policy_id",
              "keyValue": "={{ $('XML to JSON').item.json.policy.general.id }}"
            }
          ]
        },
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "GF9AjDJX8m7bAab0",
          "cachedResultUrl": "/projects/264iKDXYyOICVJr8/datatables/GF9AjDJX8m7bAab0",
          "cachedResultName": "jamf_policies"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "68d57c39-8a80-4de9-8635-f34dbd2d7d4e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        224,
        -32
      ],
      "parameters": {
        "color": 3,
        "width": 220,
        "height": 404,
        "content": "## Split  \nSplit previous node array into items.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3d353ccc-b7b4-4482-8f52-94ff3b8f9c2a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        -32
      ],
      "parameters": {
        "color": 4,
        "width": 180,
        "height": 400,
        "content": "## Get  \nGet policy by ID"
      },
      "typeVersion": 1
    },
    {
      "id": "59d4b110-4ce6-4332-9a92-95a70fb20020",
      "name": "Get /id",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        512,
        160
      ],
      "parameters": {
        "url": "=https://{{ $('Jamf Server').item.json.server }}.jamfcloud.com/JSSResource/policies/id/{{ $json.value }}",
        "options": {},
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api",
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/xml"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "14449796-3ced-4fed-860a-55fd8c36caa8",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        -32
      ],
      "parameters": {
        "color": 5,
        "width": 180,
        "height": 400,
        "content": "## XML to JSON  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "6ff80123-f16a-4161-aad6-93faa1296f39",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        -32
      ],
      "parameters": {
        "color": 7,
        "width": 180,
        "height": 400,
        "content": "## Policy HASH\nHash the policy to monitor \n"
      },
      "typeVersion": 1
    },
    {
      "id": "4628148c-f2ae-4f55-820c-0ace384d4e5d",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1040,
        -32
      ],
      "parameters": {
        "color": 3,
        "width": 532,
        "height": 400,
        "content": "## Upsert and Monitor\nInsert the policy if it doesn't exist and then compare the HASH\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3fa8915a-7ffd-467e-9ecf-adff5200ef7f",
      "name": "Insert new Policy",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1248,
        80
      ],
      "parameters": {
        "columns": {
          "value": {
            "hash": "={{ $json.data }}",
            "policy_id": "={{ $json.policy.general.id }}",
            "policy_name": "={{ $json.policy.general.name }}"
          },
          "schema": [
            {
              "id": "policy_id",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "policy_id",
              "defaultMatch": false
            },
            {
              "id": "policy_name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "policy_name",
              "defaultMatch": false
            },
            {
              "id": "hash",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "hash",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "optimizeBulk": false
        },
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "GF9AjDJX8m7bAab0",
          "cachedResultUrl": "/projects/264iKDXYyOICVJr8/datatables/GF9AjDJX8m7bAab0",
          "cachedResultName": "jamf_policies"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7f5dc520-448e-4c37-984a-3a137f27542b",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        -32
      ],
      "parameters": {
        "color": 4,
        "width": 356,
        "height": 400,
        "content": "## Upsert and Notify\nUpdate policy with new HASH and notify via slack"
      },
      "typeVersion": 1
    },
    {
      "id": "3019b883-8663-4cd5-b6c5-708656197728",
      "name": "If Policy does not exist",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1088,
        80
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "policy_id",
              "keyValue": "={{ $json.policy.general.id }}"
            }
          ]
        },
        "operation": "rowNotExists",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "GF9AjDJX8m7bAab0",
          "cachedResultUrl": "/projects/264iKDXYyOICVJr8/datatables/GF9AjDJX8m7bAab0",
          "cachedResultName": "jamf_policies"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d752d43a-23bc-4f4b-bb2f-52310d02031f",
      "name": "Get Policy",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1216,
        240
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "policy_id",
              "keyValue": "={{ $json.policy.general.id }}"
            }
          ]
        },
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "GF9AjDJX8m7bAab0",
          "cachedResultUrl": "/projects/264iKDXYyOICVJr8/datatables/GF9AjDJX8m7bAab0",
          "cachedResultName": "jamf_policies"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c40c8a36-415d-4f0e-9ab0-1b022744ecc9",
      "name": "XML to JSON",
      "type": "n8n-nodes-base.xml",
      "position": [
        704,
        160
      ],
      "parameters": {
        "options": {},
        "dataPropertyName": "=data"
      },
      "typeVersion": 1
    },
    {
      "id": "5771408f-6435-450e-8e83-143c6f312aa1",
      "name": "Manual Execution",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -288,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "297db7c0-a007-49e2-82fa-9a0c61c3ba9b",
      "name": "Send Alert to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        1808,
        224
      ],
      "parameters": {
        "text": "=",
        "select": "channel",
        "blocksUi": "={\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"\u26a0\ufe0f Policy: <https://{{ $('Jamf Server').item.json.server }}.jamfcloud.com/policies.html?id={{ $json.policy_id }}&o=h|{{ $json.policy_name }}> modified\"\n\t\t\t}\n\t\t},\n\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t \"type\": \"mrkdwn\",\n\t\t\t\t \"text\": \"\ud83d\udcc6 DateTime: *{{new Date($json.updatedAt).toLocaleString('en-US', { dateStyle: 'medium', timeStyle: 'medium' }) }}*\"\n\t\t\t}\t\t\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t}\n\t]\n}",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "C092F1H4T41"
        },
        "messageType": "block",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "1595181f-f216-4a29-a817-22f1a5d48c44",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1424,
        80
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "connections": {
    "IDs": {
      "main": [
        [
          {
            "node": "Split groups",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get /id": {
      "main": [
        [
          {
            "node": "XML to JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Jamf Server",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Policy": {
      "main": [
        [
          {
            "node": "Condition hash Diff",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Hash_policy": {
      "main": [
        [
          {
            "node": "If Policy does not exist",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Policy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Jamf Server": {
      "main": [
        [
          {
            "node": "IDs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Hash": {
      "main": [
        [
          {
            "node": "Send Alert to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "XML to JSON": {
      "main": [
        [
          {
            "node": "Hash_policy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split groups": {
      "main": [
        [
          {
            "node": "Get /id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Execution": {
      "main": [
        [
          {
            "node": "Jamf Server",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Jamf Server",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert new Policy": {
      "main": [
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Condition hash Diff": {
      "main": [
        [
          {
            "node": "Update Hash",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Alert to Slack": {
      "main": [
        []
      ]
    },
    "If Policy does not exist": {
      "main": [
        [
          {
            "node": "Insert new Policy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing β€” you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

πŸ›‘οΈ Jamf Policy Integrity Monitor

Source: https://n8n.io/workflows/9287/ β€” original creator credit. Request a take-down β†’

More Slack & Telegram workflows β†’ Β· Browse all categories β†’

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

File Hash Reputation Checker is a security automation workflow that validates file hashes (MD5, SHA1, SHA256) and checks their reputation using the VirusTotal API. It is designed for SOC teams, securi

Slack, HTTP Request
Slack & Telegram

Notify_user_in_Slack_of_quarantined_email_and_create_Jira_ticket_if_opened. Uses httpRequest, jira, stickyNote, slack. Webhook trigger; 13 nodes.

HTTP Request, Jira, Slack
Slack & Telegram

This n8n workflow serves as an incident response and notification system for handling potentially malicious emails flagged by Sublime Security. It begins with a Webhook trigger that Sublime Security u

HTTP Request, Jira, Slack
Slack & Telegram

This workflow is built for n8n admins, automation agencies, solopreneurs, and ops teams running multiple workflows in production who need to know the moment something breaks.

HTTP Request, Slack
Slack & Telegram

This workflow solves the problem of manually copying line items from one deal to another in HubSpot, reducing manual work and minimizing errors. Triggers upon receiving a webhook with deal IDs. Retrie

HTTP Request, Slack