Workflow: develop a modular n8n workflow that supports Webhook Slack Create Webhook
Integrations: executeWorkflow, httpRequest, if, merge, noOp, respondToWebhook, set, slack, stickyNote, switch, venafiTlsProtectCloud, webhook

{"meta": {"instanceId": "cb484ba7b742928a2048bf8829668bed5b5ad9787579adea888f05980292a4a7"}, "nodes": [{"id": "1092ab50-67a0-4e50-8c10-f05f70b45f56", "name": "Venafi TLS Protect Cloud", "type": "n8n-nodes-base.venafiTlsProtectCloud", "position": [2860, 1700], "parameters": {"options": {}, "commonName": "={{ $('Parse Webhook').item.json.response.view.state.values.domain_name_block.domain_name_input.value.match(/^(\\*\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$/g).toString() }}", "generateCsr": true, "applicationId": "f3c15c80-7151-11ef-9a22-abeac49f7094", "additionalFields": {"organizationalUnits": ["={{ $json.name }}"]}, "certificateIssuingTemplateId": "d28d82b1-714b-11ef-9026-7bb80b32867a"}, "credentials": {"venafiTlsProtectCloudApi": {"id": "WU38IpfutNNkJWuo", "name": "Venafi TLS Protect Cloud account"}}, "typeVersion": 1}, {"id": "0c1f1b92-2da4-413f-a4cc-68c816e8511c", "name": "Parse Webhook", "type": "n8n-nodes-base.set", "position": [440, 1100], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "e63f9299-a19d-4ba1-93b0-59f458769fb2", "name": "response", "type": "object", "value": "={{ $json.body.payload }}"}]}}, "typeVersion": 3.3}, {"id": "95fb1907-c9e0-4164-b0b0-c3691bb46b9a", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [108.34675483142371, 741.4892041682327], "parameters": {"color": 7, "width": 466.8168310000617, "height": 556.7924159157113, "content": "![Imgur](https://i.imgur.com/iKyMV0N.png)\n## Events Webhook Trigger\nThe first node receives all messages from Slack API via Subscription Events API. You can find more information about setting up the subscription events API by [clicking here](https://api.slack.com/apis/connections/events-api). \n\nThe second node extracts the payload from slack into an object that n8n can understand.  "}, "typeVersion": 1}, {"id": "4dd8cbbe-278c-4c86-bcd7-9fb0eff619b2", "name": "Sticky Note15", "type": "n8n-nodes-base.stickyNote", "position": [580, 420], "parameters": {"color": 7, "width": 566.0553219408072, "height": 999.0925226187064, "content": "![n8n](https://i.imgur.com/lKnBNnH.png)\n## Efficient Slack Interaction Handling with n8n\n\nThis section of the workflow is designed to efficiently manage and route messages and submissions from Slack based on specific triggers and conditions. When a Slack interaction occurs\u2014such as a user triggering a vulnerability scan or generating a report through a modal\u2014the workflow intelligently routes the message to the appropriate action:\n\n- **Dynamic Routing**: Uses conditions to determine the nature of the Slack interaction, whether it's a direct command to initiate a scan or a request to generate a report.\n- **Modal Management**: Differentiates actions based on modal titles and `callback_id`s, ensuring that each type of submission is processed according to its context.\n- **Streamlined Responses**: After routing, the workflow promptly handles the necessary responses or actions, including closing modal popups and responding to Slack with appropriate confirmation or data.\n\n**Purpose**: This mechanism ensures that all interactions within Slack are handled quickly and accurately, automating responses and actions in real-time to enhance user experience and workflow efficiency."}, "typeVersion": 1}, {"id": "db8aabd8-d00d-4d50-9f97-443eba7c7c90", "name": "Sticky Note11", "type": "n8n-nodes-base.stickyNote", "position": [1153.6255461332685, 516.1718360212528], "parameters": {"color": 7, "width": 396.6025898621133, "height": 652.6603582798184, "content": "![Imgur](https://i.imgur.com/iKyMV0N.png)\n## Display Modal Popup\nThis section pops open a modal window that is later used to send data into Virustotal, then depending on those results, to Venafi or Slack for manual approval. \n\nModals can be customized to perform all sorts of actions. And they are natively mobile! Additionally, messages themselves can perform actions if you include inputs like buttons or field inputs. \n\nLearn more about them by [clicking here](https://api.slack.com/surfaces/modals)"}, "typeVersion": 1}, {"id": "a86e0b86-0740-4b77-831a-52413983818e", "name": "Close Modal Popup", "type": "n8n-nodes-base.respondToWebhook", "position": [960, 1200], "parameters": {"options": {}, "respondWith": "noData"}, "typeVersion": 1.1}, {"id": "a5abc206-6b10-42bc-9196-bcedacdb3726", "name": "Sticky Note8", "type": "n8n-nodes-base.stickyNote", "position": [-580, 740], "parameters": {"width": 675.1724774900403, "height": 972.8853473866498, "content": "![n8n](https://i.imgur.com/lKnBNnH.png)\n## Enhance Security Operations with the Venafi Slack CertBot!\n\nOur **Venafi Slack CertBot** is strategically designed to facilitate immediate security operations directly from Slack. This tool allows end users to request Certificate Signing Requests that are automatically approved or passed to the Secops team for manual approval depending on the Virustotal analysis of the requested domain. Not only does this help centralize requests, but it helps an organization maintain the security certifications by allowing automated processes to log and analyze requests in real time. \n\n**Workflow Highlights:**\n- **Interactive Modals**: Utilizes Slack modals to gather user inputs for scan configurations and report generation, providing a user-friendly interface for complex operations.\n- **Dynamic Workflow Execution**: Integrates seamlessly with Venafi to execute CSR generation and if any issues are found, AI can generate a custom report that is then passed to a slack teams channel for manual approval with the press of a single button.\n\n**Operational Flow:**\n- **Parse Webhook Data**: Captures and parses incoming data from Slack to understand user commands accurately.\n- **Execute Actions**: Depending on the user's selection, the workflow triggers other actions within the flow like automatic Virustotal Scanning.\n- **Respond to Slack**: Ensures that every interaction is acknowledged, maintaining a smooth user experience by managing modal popups and sending appropriate responses.\n\n\n**Setup Instructions:**\n- Verify that Slack and Qualys API integrations are correctly configured for seamless interaction.\n- Customize the modal interfaces to align with your organization's operational protocols and security policies.\n- Test the workflow to ensure that it responds accurately to Slack commands and that the integration with Qualys is functioning as expected.\n\n\n**Need Assistance?**\n- Explore Venafi's [Documentation](https://docs.venafi.com/) or get help from the [n8n Community](https://community.n8n.io) for more detailed guidance on setup and customization.\n\nDeploy this bot within your Slack environment to significantly enhance the efficiency and responsiveness of your security operations, enabling proactive management of CSR's."}, "typeVersion": 1}, {"id": "352680c7-3b77-4fc1-81eb-8b5495747d89", "name": "Respond to Slack Webhook - Vulnerability", "type": "n8n-nodes-base.respondToWebhook", "position": [960, 1000], "parameters": {"options": {}, "respondWith": "noData"}, "typeVersion": 1.1}, {"id": "7e2991c3-14ee-478c-b9b6-9dd58590dde9", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [1160, 860], "parameters": {"color": 5, "width": 376.26546828439086, "height": 113.6416448104651, "content": "### \ud83d\ude4b Don't forget your slack credentials!\nThankfully n8n makes it easy, as long as you've added credentials to a normal slack node, these http nodes are a snap to change via the drop down. "}, "typeVersion": 1}, {"id": "97b8942b-1ec5-437f-9c51-2188cc9a9d6f", "name": "Venafi Request Certificate", "type": "n8n-nodes-base.httpRequest", "position": [1240, 1000], "parameters": {"url": "https://slack.com/api/views.open", "method": "POST", "options": {}, "jsonBody": "=  {\n    \"trigger_id\": \"{{ $('Parse Webhook').item.json['response']['trigger_id'] }}\",\n    \"external_id\": \"Idea Selector\",\n    \"view\": {\n\t\"type\": \"modal\",\n\t\"callback_id\": \"certificate_request_modal\",\n\t\"title\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Request New Certificate\"\n\t},\n\t\"submit\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Request\"\n\t},\n\t\"close\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Cancel\"\n\t},\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"image\",\n\t\t\t\"image_url\": \"https://img.securityinfowatch.com/files/base/cygnus/siw/image/2022/10/Venafi_logo.63459e2b03b7b.png?auto=format%2Ccompress&w=640&width=640\",\n\t\t\t\"alt_text\": \"delicious tacos\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"domain_name_block\",\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Domain Name\"\n\t\t\t},\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"domain_name_input\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Enter the domain name\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"validity_period_block\",\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Validity Period\"\n\t\t\t},\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"static_select\",\n\t\t\t\t\"action_id\": \"validity_period_select\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Select a validity period\"\n\t\t\t\t},\n\t\t\t\t\"options\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"1 Year\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"value\": \"P1Y\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"2 Years\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"value\": \"P2Y\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"optional_note_block\",\n\t\t\t\"optional\": true,\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Optional Note\"\n\t\t\t},\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"optional_note_input\",\n\t\t\t\t\"multiline\": true,\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Add any extra information (e.g., usage context, urgency)\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n}", "sendBody": true, "jsonQuery": "{\n  \"Content-type\": \"application/json\"\n}", "sendQuery": true, "specifyBody": "json", "specifyQuery": "json", "authentication": "predefinedCredentialType", "nodeCredentialType": "slackApi"}, "credentials": {"slackApi": {"id": "hkcQkp6qhtiMzBEX", "name": "certbot"}}, "typeVersion": 4.2}, {"id": "12c50bad-8aab-4bab-8790-153d9e484762", "name": "Extract Fields", "type": "n8n-nodes-base.set", "position": [1200, 1460], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "39808a24-60f6-4f4b-8f4c-4c2aa3850b4f", "name": "domain", "type": "string", "value": "={{ $json.response.view.state.values.domain_name_block.domain_name_input.value }}"}, {"id": "27c905be-18cc-434f-8af0-a08ee23a168f", "name": "validity", "type": "string", "value": "={{ $json.response.view.state.values.validity_period_block.validity_period_select.selected_option.value }}"}, {"id": "ba1382e5-0629-4276-9858-34bcb59cc85a", "name": "note", "type": "string", "value": "={{ $json.response.view.state.values.optional_note_block.optional_note_input.value }}"}]}}, "typeVersion": 3.4}, {"id": "f16a97d7-639e-4ec9-b003-b4ee4fdf8666", "name": "Get Slack User ID", "type": "n8n-nodes-base.set", "position": [1200, 2020], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "53dfe019-d91d-4f5c-b279-f8b3fde98bf1", "name": "id", "type": "string", "value": "={{ $json.response.user.id }}"}]}}, "typeVersion": 3.4}, {"id": "2a6af9ae-3916-4993-b2b3-a737f54f7a37", "name": "Translate Slack User ID to Email", "type": "n8n-nodes-base.executeWorkflow", "position": [1520, 2020], "parameters": {"options": {"waitForSubWorkflow": true}, "workflowId": {"__rl": true, "mode": "list", "value": "afeVlIVyoIF8Psu4", "cachedResultName": "Slack ID to Email"}}, "typeVersion": 1.1}, {"id": "19541f84-0d97-4711-80ed-d36a5d517d9b", "name": "VirusTotal HTTP Request", "type": "n8n-nodes-base.httpRequest", "position": [1440, 1460], "parameters": {"": "", "url": "=https://www.virustotal.com/api/v3/domains/{{ $json.domain }}", "method": "GET", "options": {}, "sendBody": false, "sendQuery": false, "curlImport": "", "infoMessage": "", "sendHeaders": true, "authentication": "none", "specifyHeaders": "keypair", "headerParameters": {"parameters": [{"name": "accept", "value": "application/json"}, {"name": "X-Apikey", "value": "455144dac89b783b2f5421578b9ab4072adebfc011c969ba384d1c8f0e2ce39e"}]}, "httpVariantWarning": "", "provideSslCertificates": false}, "credentials": {"virusTotalApi": {"id": "JRK1xDyMiseROCmY", "name": "VirusTotal account 2"}}, "typeVersion": 4.2, "extendsCredential": "virusTotalApi"}, {"id": "4a0e0a71-b433-479b-87b7-7200537009af", "name": "Summarize output to save on tokens", "type": "n8n-nodes-base.set", "position": [1760, 1460], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "2c4689a3-4b72-4240-8a0f-2fa00d33c553", "name": "data.attributes.last_analysis_stats.malicious", "type": "number", "value": "={{ $json.data.attributes.last_analysis_stats.malicious }}"}, {"id": "59db6f41-1cf1-4feb-8120-8c50fadc5c9e", "name": "data.attributes.last_analysis_stats.suspicious", "type": "number", "value": "={{ $json.data.attributes.last_analysis_stats.suspicious }}"}, {"id": "b55e7d39-0358-4863-8147-c5ce2b65ea96", "name": "data.attributes.last_analysis_stats.undetected", "type": "number", "value": "={{ $json.data.attributes.last_analysis_stats.undetected }}"}, {"id": "ecd98a37-cb8b-48cd-bd3d-9c8bf777c5ca", "name": "data.attributes.last_analysis_stats.harmless", "type": "number", "value": "={{ $json.data.attributes.last_analysis_stats.harmless }}"}, {"id": "72a776d5-70d7-4c30-b8fc-f7da382bc626", "name": "data.attributes.last_analysis_stats.timeout", "type": "number", "value": "={{ $json.data.attributes.last_analysis_stats.timeout }}"}, {"id": "b85d8e8a-620c-4bb7-97db-d780f273deee", "name": "data.attributes.reputation", "type": "number", "value": "={{ $json.data.attributes.reputation }}"}]}}, "typeVersion": 3.4}, {"id": "3d641c80-8a2a-4888-9ee3-ecd82f8d0d8b", "name": "Auto Issue Certificate Based on 0 Malicious Reports", "type": "n8n-nodes-base.if", "position": [2300, 1840], "parameters": {"options": {}, "conditions": {"options": {"version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "795c6ff5-ac4a-4b67-b2fe-369fba276194", "operator": {"type": "number", "operation": "lte"}, "leftValue": "={{ $json.data.attributes.last_analysis_stats.malicious }}", "rightValue": 0}]}}, "typeVersion": 2.2}, {"id": "3f6e9bf2-6c6c-4316-8d14-1b004122fa67", "name": "Auto Issue Certificate", "type": "n8n-nodes-base.noOp", "position": [2560, 1700], "parameters": {}, "typeVersion": 1}, {"id": "fa34e736-65c4-4bc1-a391-794225a588d2", "name": "Generate Report For Manual Approval", "type": "n8n-nodes-base.noOp", "position": [2540, 2220], "parameters": {}, "typeVersion": 1}, {"id": "178afe87-cdef-46f0-8166-68b661349189", "name": "Get Slack Team ID", "type": "n8n-nodes-base.set", "position": [1220, 2220], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "53dfe019-d91d-4f5c-b279-f8b3fde98bf1", "name": "id", "type": "string", "value": "={{ $json.response.team.id }}"}]}}, "typeVersion": 3.4}, {"id": "c4d89085-f7f4-4073-bfe2-cd156275710c", "name": "Execute Workflow", "type": "n8n-nodes-base.executeWorkflow", "position": [1520, 2220], "parameters": {"options": {}, "workflowId": {"__rl": true, "mode": "list", "value": "ZIl9VdWh7BiVRRBT", "cachedResultName": "Slack Team ID to Name"}}, "typeVersion": 1.1}, {"id": "51d85502-ea61-423b-a6c4-66ed8397d685", "name": "Merge User and Team Data", "type": "n8n-nodes-base.merge", "position": [1820, 2140], "parameters": {"mode": "combine", "options": {}, "combineBy": "combineByPosition"}, "typeVersion": 3}, {"id": "febb1be8-7cad-46f1-a854-2ff1432216cb", "name": "OpenAI", "type": "@n8n/n8n-nodes-langchain.openAi", "position": [2720, 2220], "parameters": {"modelId": {"__rl": true, "mode": "list", "value": "gpt-4o-mini", "cachedResultName": "GPT-4O-MINI"}, "options": {}, "messages": {"values": [{"content": "=Analyze the following VirusTotal scan results and summarize the overall risk as Low, Medium, or High based on the number of engines flagging the domain (excluding \"clean\" or \"unrated\" results). Use the following criteria for risk rating:\n\nLow: No significant threats detected; domain is clean.\nMedium: Minor issues detected; may require further review.\nHigh: Significant threats like phishing or malware; manual review recommended.\n\nHere are the scan results for the domain {{ $('Parse Webhook').item.json.response.view.state.values.domain_name_block.domain_name_input.value }}:\n\nMalicious: {{ $json.data.attributes.last_analysis_stats.malicious }}\nSuspicious: {{ $json.data.attributes.last_analysis_stats.suspicious }}\nUndetected: {{ $json.data.attributes.last_analysis_stats.undetected }}\nHarmless: {{ $json.data.attributes.last_analysis_stats.harmless }}\nTimeout: {{ $json.data.attributes.last_analysis_stats.timeout }}\nReputation: {{ $json.data.attributes.reputation }}\n\nProvide an overall risk rating and suggest next steps based on your analysis. Please keep it concise. "}, {"role": "system", "content": "Analyze the VirusTotal scan results and categorize the domain\u2019s risk as Low, Medium, or High:\n\nIdentify Risks: Focus on results flagged as anything other than \"clean\" or \"unrated.\"\nAssess Risk:\nLow: No major threats flagged, domain is safe.\nMedium: Minor issues flagged, review recommended.\nHigh: Significant threats flagged (e.g., phishing, malware), manual review needed.\nRecommendation:\nLow: Auto-issue the certificate.\nMedium/High: Recommend manual review."}]}}, "credentials": {"openAiApi": {"id": "2KVzlb0XZRZkoObj", "name": "angel openai auth"}}, "typeVersion": 1.5}, {"id": "04ffe7bb-be5d-4ce0-b17c-68276673f585", "name": "Sticky Note16", "type": "n8n-nodes-base.stickyNote", "position": [1160, 1680], "parameters": {"color": 7, "width": 833.9929589980072, "height": 705.5291769708515, "content": "![n8n](https://i.imgur.com/qXWqiOd.png)\n## Run Workflows within other Workflows like Functions\n\nThis section of the workflow contains 2 subworkflows that translate the Slack User ID to an email and name, and the Slack Team ID into the team name and Avatar of the team to make the slack messages more visual. This allows you to reuse these flows like you would use a function in code. \n\nThese nodes run parallel to each other so they will not override the data generated by each thread, and then are joined using the Merge nodes. "}, "typeVersion": 1}, {"id": "a2b48f56-946b-4ae7-ade4-5b84b1a99bb9", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [1160, 1180], "parameters": {"color": 7, "width": 832.2724669887743, "height": 485.55399396506067, "content": "![VirusTotal](https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/VirusTotal_logo.svg/320px-VirusTotal_logo.svg.png)\n## URL Analysis with VirusTotal\nThe first node receives all messages from Slack API via Subscription Events API. You can find more information about setting up the subscription events API by [clicking here](https://api.slack.com/apis/connections/events-api). \n\nThe second node extracts the payload from slack into an object that n8n can understand.  "}, "typeVersion": 1}, {"id": "c38c30f3-acb1-40e4-acc5-3fd4f6b8e643", "name": "Merge Requestor and VT Data", "type": "n8n-nodes-base.merge", "position": [2100, 1840], "parameters": {"mode": "combine", "options": {}, "combineBy": "combineByPosition"}, "typeVersion": 3}, {"id": "2e2c6100-b82e-4cdf-a290-33c2898de652", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [2480, 1420], "parameters": {"color": 7, "width": 547.705272240834, "height": 485.55399396506067, "content": "![VirusTotal](https://img.securityinfowatch.com/files/base/cygnus/siw/image/2022/10/Venafi_logo.63459e2b03b7b.png?auto=format%2Ccompress&w=250&width=250)\n## Automatic CSR Generation via Venafi\nContextual data from the Slack user's webhook is used to gather the needed contextual data, such as the name of the Slack team/group the user is in and their email and name if needed. \n\nFor automatic CSR Generation to work, ensure you have a Vsatelite deployed and active. "}, "typeVersion": 1}, {"id": "4c168cd6-e5d2-4d82-9fe3-3b8431db3dcd", "name": "Sticky Note12", "type": "n8n-nodes-base.stickyNote", "position": [3040, 1309.0359710471785], "parameters": {"color": 7, "width": 367.3323860824746, "height": 831.2760849855022, "content": "![Imgur](https://i.imgur.com/iKyMV0N.png)\n## Send Contextual Message to Slack\nThis section pops open a modal window that is later used to send data into TheHive. \n\nModals can be customized to perform all sorts of actions. And they are natively mobile! You can see a screenshot of the Slack Modals on the right. \n\nLearn more about them by [clicking here](https://api.slack.com/surfaces/modals)"}, "typeVersion": 1}, {"id": "08687e15-90e0-42da-95a4-ada8b7ddcd36", "name": "Sticky Note17", "type": "n8n-nodes-base.stickyNote", "position": [2000, 1421.1618229241317], "parameters": {"color": 7, "width": 465.44793569024944, "height": 676.0664675646049, "content": "![n8n](https://i.imgur.com/lKnBNnH.png)\n## Efficient Slack Interaction Handling with n8n\n\nThis section of the workflow is designed to efficiently manage and route messages and submissions from Slack based on specific triggers and conditions. When a Slack interaction occurs\u2014such as a user triggering a vulnerability scan or generating a report through a modal\u2014the workflow intelligently routes the message to the appropriate action:"}, "typeVersion": 1}, {"id": "7098d247-5f39-4c61-a055-d7e9d12c2a64", "name": "Sticky Note6", "type": "n8n-nodes-base.stickyNote", "position": [2480, 1920], "parameters": {"color": 7, "width": 544.2406462166426, "height": 546.0036529662652, "content": "![OpenAI](https://i.imgur.com/o89G0If.png)\n## Parse Response with AI Model \nThis workflow currently uses OpenAI to power it's responses, but you can replace the AI Agent node below and set your own local AI LLM using the n8n options offered. "}, "typeVersion": 1}, {"id": "3f2ea251-6f4e-4701-8456-d3020169f802", "name": "Send Auto Generated Confirmation", "type": "n8n-nodes-base.slack", "position": [3160, 1700], "parameters": {"text": "test", "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\": \"*:lock: CSR Auto-Issued Successfully!*\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\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\": \"*Team:* {{ $('Merge Requestor and VT Data').item.json.name }}\\n*Requested by:* <@{{ $('Parse Webhook').item.json.response.user.id }}>\\n*Email:* {{ $('Merge User and Team Data').item.json.email }}\\n*Date Issued:* {{ $json.creationDate }}\"\n\t\t\t},\n\t\t\t\"accessory\": {\n\t\t\t\t\"type\": \"image\",\n\t\t\t\t\"image_url\": \"{{ $('Merge User and Team Data').item.json.team.icon.image_132 }}\",\n\t\t\t\t\"alt_text\": \"Team Avatar\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"context\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*CSR Details:*\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"fields\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*Common Name:* {{ $('Parse Webhook').item.json.response.view.state.values.domain_name_block.domain_name_input.value }}\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*Organization:* n8n.io\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*Issued By:* Venafi CA\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*Validity Period:* {{ DateTime.fromISO($json.creationDate).toFormat('MMMM dd, yyyy') }} to {{ DateTime.fromISO($json.creationDate).plus({ years: 1 }).toFormat('MMMM dd, yyyy') }}\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"actions\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \"View CSR Details\"\n\t\t\t\t\t},\n\t\t\t\t\t\"url\": \"https://eval-32690260.venafi.cloud/issuance/certificate-requests?id={{ $json.id }}\",\n\t\t\t\t\t\"style\": \"primary\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \"Revoke CSR\"\n\t\t\t\t\t},\n\t\t\t\t\t\"style\": \"danger\",\n\t\t\t\t\t\"value\": \"revoke_csr\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}", "channelId": {"__rl": true, "mode": "id", "value": "C07MB8PGZ36"}, "messageType": "block", "otherOptions": {}}, "credentials": {"slackApi": {"id": "hkcQkp6qhtiMzBEX", "name": "certbot"}}, "typeVersion": 2.2}, {"id": "17b7cc2e-32ff-4670-a756-bb41627dc14a", "name": "Send Message Request for Manual Approval", "type": "n8n-nodes-base.slack", "position": [3160, 1940], "parameters": {"text": "test", "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\": \":warning: *CSR Pending Approval*\\n\\nThe Certificate Signing Request for the following domain was not auto-approved. Please review the details and press the button below to submit the request for manual approval.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\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\": \"*Team:* {{ $('Merge Requestor and VT Data').item.json.name }}\\n*Submitted by:* <@{{ $('Parse Webhook').item.json.response.user.id }}>\\n*Requestor Email:* {{ $('Merge Requestor and VT Data').item.json.email }}\\n*Date Submitted:* {{ DateTime.fromISO($json.creationDate).toFormat('MMMM dd, yyyy') }}\\n*Domain:* {{ $('Parse Webhook').item.json.response.view.state.values.domain_name_block.domain_name_input.value }}\\n\\n:mag: *AI Analysis*\\n> The AI detected the following potential issues with the CSR:\\n> - *VT Malicious Reports:* {{ $('Generate Report For Manual Approval').item.json.data.attributes.last_analysis_stats.malicious }}\\n> - *Reputation Score:* {{ $('Generate Report For Manual Approval').item.json.data.attributes.reputation }}/100\\n> - *Additional Notes:* {{ $json.message.content.replace(/\\n/g, '\\\\n').replace(/###/g, ' ').replace(/-\\s+\\*\\*(.*?)\\*\\*/g, '\u2022 *$1*').replace(/\"/g, '\\\\\"').replace(/\\*\\*/g, '*') }}\\n\\nPlease ensure these risks are mitigated before proceeding.\"\n\t\t\t},\n\t\t\t\"accessory\": {\n\t\t\t\t\"type\": \"image\",\n\t\t\t\t\"image_url\": \"https://avatars.slack-edge.com/2024-08-29/7652078599283_52acb3a88da26e76bab6_132.png\",\n\t\t\t\t\"alt_text\": \"Team Avatar\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"actions\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \":arrow_forward: Submit for Approval\"\n\t\t\t\t\t},\n\t\t\t\t\t\"value\": \"submit_for_approval\",\n\t\t\t\t\t\"style\": \"primary\",\n\t\t\t\t\t\"action_id\": \"submit_for_approval\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \"View CSR Details\"\n\t\t\t\t\t},\n\t\t\t\t\t\"value\": \"view_csr_details\",\n\t\t\t\t\t\"url\": \"https://google.com\",\n\t\t\t\t\t\"action_id\": \"view_csr_details\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"type\": \"context\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"Submitted on {{ $now.toFormat('MMMM dd, yyyy') }}. The request requires manual approval. If you have any questions, contact the security team.\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}", "channelId": {"__rl": true, "mode": "id", "value": "C07MB8PGZ36"}, "messageType": "block", "otherOptions": {}}, "credentials": {"slackApi": {"id": "hkcQkp6qhtiMzBEX", "name": "certbot"}}, "typeVersion": 2.2}, {"id": "480c7f12-fc3a-44d1-885f-d6618a1e0dc8", "name": "Route Message", "type": "n8n-nodes-base.switch", "position": [620, 1100], "parameters": {"rules": {"values": [{"outputKey": "Request Modal", "conditions": {"options": {"version": 1, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"operator": {"type": "string", "operation": "equals"}, "leftValue": "={{ $json.response.callback_id }}", "rightValue": "request-certificate"}]}, "renameOutput": true}, {"outputKey": "Submit Data", "conditions": {"options": {"version": 1, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "65daa75f-2e17-4ba0-8fd8-2ac2159399e3", "operator": {"name": "filter.operator.equals", "type": "string", "operation": "equals"}, "leftValue": "={{ $json.response.type }}", "rightValue": "view_submission"}]}, "renameOutput": true}, {"outputKey": "Block Actions", "conditions": {"options": {"version": 1, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "87f6f93e-28c9-49bc-8e1e-d073d86347b4", "operator": {"name": "filter.operator.equals", "type": "string", "operation": "equals"}, "leftValue": "={{ $json.response.type }}", "rightValue": "block_actions"}]}, "renameOutput": true}]}, "options": {"fallbackOutput": "none"}}, "typeVersion": 3}, {"id": "a42115ce-f0d7-443b-947d-cb8d54c2df22", "name": "Venafi TLS Protect Cloud1", "type": "n8n-nodes-base.venafiTlsProtectCloud", "position": [1500, 2700], "parameters": {"options": {}, "commonName": "={{ $json.response.message.blocks[2].text.text.match(/\\*Domain:\\*\\s*<http[^|]+\\|([^\\n]+)>/)[1] }}", "generateCsr": true, "applicationId": "f3c15c80-7151-11ef-9a22-abeac49f7094", "additionalFields": {"organizationalUnits": ["={{ $json.response.message.blocks[2].text.text.match(/\\*Team:\\*\\s*([^\\n]*)/)[1] }}"]}, "certificateIssuingTemplateId": "d28d82b1-714b-11ef-9026-7bb80b32867a"}, "credentials": {"venafiTlsProtectCloudApi": {"id": "WU38IpfutNNkJWuo", "name": "Venafi TLS Protect Cloud account"}}, "typeVersion": 1}, {"id": "69765a07-32ee-478a-a2f7-4de459fd69d9", "name": "Send Auto Generated Confirmation1", "type": "n8n-nodes-base.slack", "position": [1800, 2700], "parameters": {"text": "test", "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\": \"*:lock: CSR Auto-Issued Successfully!*\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\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\": \"*Team:* {{ $('Parse Webhook').item.json.response.message.blocks[2].text.text.match(/\\*Team:\\*\\s*([^\\n]*)/)[1] }}\\n*Requested by:* \\n*Email:* {{ $('Parse Webhook').item.json.response.message.blocks[2].text.text.match(/\\*Requestor\\sEmail:\\*\\s*<mailto:([^|]+)\\|/)[1] }}\\n*Date Issued:* {{ $json.creationDate }}\"\n\t\t\t},\n\t\t\t\"accessory\": {\n\t\t\t\t\"type\": \"image\",\n\t\t\t\t\"image_url\": \"{{ $('Parse Webhook').item.json.response.message.blocks[2].accessory.image_url }}\",\n\t\t\t\t\"alt_text\": \"Team Avatar\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"context\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*CSR Details:*\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"fields\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*Common Name:* {{ $('Parse Webhook').item.json.response.message.blocks[2].text.text.match(/\\*Domain:\\*\\s*<http[^|]+\\|([^\\n]+)>/)[1] }}\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*Organization:* n8n.io\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*Issued By:* Venafi CA\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"*Validity Period:* {{ DateTime.fromISO($json.creationDate).toFormat('MMMM dd, yyyy') }} to {{ DateTime.fromISO($json.creationDate).plus({ years: 1 }).toFormat('MMMM dd, yyyy') }}\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"actions\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \"View CSR Details\"\n\t\t\t\t\t},\n\t\t\t\t\t\"url\": \"https://eval-32690260.venafi.cloud/issuance/certificate-requests?id={{ $json.id }}\",\n\t\t\t\t\t\"style\": \"primary\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \"Revoke CSR\"\n\t\t\t\t\t},\n\t\t\t\t\t\"style\": \"danger\",\n\t\t\t\t\t\"value\": \"revoke_csr\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}", "channelId": {"__rl": true, "mode": "id", "value": "C07MB8PGZ36"}, "messageType": "block", "otherOptions": {}}, "credentials": {"slackApi": {"id": "hkcQkp6qhtiMzBEX", "name": "certbot"}}, "typeVersion": 2.2}, {"id": "82b70dab-2c29-4ecd-8a26-8d7c9e8c007f", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [1165.4582041476783, 2400], "parameters": {"color": 7, "width": 822.2470680931556, "height": 485.55399396506067, "content": "![VirusTotal](https://img.securityinfowatch.com/files/base/cygnus/siw/image/2022/10/Venafi_logo.63459e2b03b7b.png?auto=format%2Ccompress&w=250&width=250)\n## Manual CSR Generation via Venafi\nContextual data from the Slack user's webhook is used to gather the needed contextual data, such as the name of the Slack team/group the user is in and their email and name if needed. Please note this section is still a proof of context and may not work exactly as expected.  \n\nFor automatic CSR Generation to work, ensure you have a Vsatelite deployed and active. "}, "typeVersion": 1}, {"id": "1ae279b2-fc2d-4686-a640-2592cc98318e", "name": "Manual Issue Certificate", "type": "n8n-nodes-base.noOp", "position": [1240, 2700], "parameters": {}, "typeVersion": 1}, {"id": "ce9c2a38-ef95-467d-846b-35f3aa6b2c84", "name": "Webhook", "type": "n8n-nodes-base.webhook", "position": [200, 1100], "webhookId": "4f86c00d-ceb4-4890-84c5-850f8e5dec05", "parameters": {"path": "venafiendpoint", "options": {}, "httpMethod": "POST", "responseMode": "responseNode"}, "typeVersion": 2}, {"id": "1caa5c53-7b65-4578-a7ca-0bf62d05cfb0", "name": "Respond to webhook success", "type": "n8n-nodes-base.respondToWebhook", "position": [760, 1280], "parameters": {"options": {}, "respondWith": "noData"}, "typeVersion": 1.1}], "pinData": {}, "connections": {"OpenAI": {"main": [[{"node": "Send Message Request for Manual Approval", "type": "main", "index": 0}]]}, "Webhook": {"main": [[{"node": "Parse Webhook", "type": "main", "index": 0}]]}, "Parse Webhook": {"main": [[{"node": "Route Message", "type": "main", "index": 0}]]}, "Route Message": {"main": [[{"node": "Respond to Slack Webhook - Vulnerability", "type": "main", "index": 0}], [{"node": "Close Modal Popup", "type": "main", "index": 0}], [{"node": "Respond to webhook success", "type": "main", "index": 0}]]}, "Extract Fields": {"main": [[{"node": "VirusTotal HTTP Request", "type": "main", "index": 0}]]}, "Execute Workflow": {"main": [[{"node": "Merge User and Team Data", "type": "main", "index": 1}]]}, "Close Modal Popup": {"main": [[{"node": "Extract Fields", "type": "main", "index": 0}, {"node": "Get Slack User ID", "type": "main", "index": 0}, {"node": "Get Slack Team ID", "type": "main", "index": 0}]]}, "Get Slack Team ID": {"main": [[{"node": "Execute Workflow", "type": "main", "index": 0}]]}, "Get Slack User ID": {"main": [[{"node": "Translate Slack User ID to Email", "type": "main", "index": 0}]]}, "Auto Issue Certificate": {"main": [[{"node": "Venafi TLS Protect Cloud", "type": "main", "index": 0}]]}, "VirusTotal HTTP Request": {"main": [[{"node": "Summarize output to save on tokens", "type": "main", "index": 0}]]}, "Manual Issue Certificate": {"main": [[{"node": "Venafi TLS Protect Cloud1", "type": "main", "index": 0}]]}, "Merge User and Team Data": {"main": [[{"node": "Merge Requestor and VT Data", "type": "main", "index": 1}]]}, "Venafi TLS Protect Cloud": {"main": [[{"node": "Send Auto Generated Confirmation", "type": "main", "index": 0}]]}, "Venafi TLS Protect Cloud1": {"main": [[{"node": "Send Auto Generated Confirmation1", "type": "main", "index": 0}]]}, "Respond to webhook success": {"main": [[{"node": "Manual Issue Certificate", "type": "main", "index": 0}]]}, "Merge Requestor and VT Data": {"main": [[{"node": "Auto Issue Certificate Based on 0 Malicious Reports", "type": "main", "index": 0}]]}, "Translate Slack User ID to Email": {"main": [[{"node": "Merge User and Team Data", "type": "main", "index": 0}]]}, "Summarize output to save on tokens": {"main": [[{"node": "Merge Requestor and VT Data", "type": "main", "index": 0}]]}, "Generate Report For Manual Approval": {"main": [[{"node": "OpenAI", "type": "main", "index": 0}]]}, "Respond to Slack Webhook - Vulnerability": {"main": [[{"node": "Venafi Request Certificate", "type": "main", "index": 0}]]}, "Auto Issue Certificate Based on 0 Malicious Reports": {"main": [[{"node": "Auto Issue Certificate", "type": "main", "index": 0}], [{"node": "Generate Report For Manual Approval", "type": "main", "index": 0}]]}}}