AutomationFlowsAI & RAG › Detect and Remediate Leaked Secret on Repo with Github, Aws, Jira, Slack, Claude

Detect and Remediate Leaked Secret on Repo with Github, Aws, Jira, Slack, Claude

ByTaiwo Hassan @taiwo on n8n.io

SecretOps is an n8n security automation workflow that monitors Git push events, detects high-risk secrets in commits, and automatically responds in real time.

Event trigger★★★★☆ complexityAI-powered26 nodesOpenRouter ChatGithub TriggerHTTP RequestAgentSlackJiraData Table
AI & RAG Trigger: Event Nodes: 26 Complexity: ★★★★☆ AI nodes: yes Added:
Detect and Remediate Leaked Secret on Repo with Github, Aws, Jira, Slack, Claude — n8n workflow card showing OpenRouter Chat, Github Trigger, HTTP Request integration

This workflow corresponds to n8n.io template #15314 — we link there as the canonical source.

This workflow follows the Agent → Datatable 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
{
  "id": "Oh0grYD41otegfWS",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Detect and remediate leaked secrets from Git repos with GitHub, AWS, Jira, Slack and Claude",
  "tags": [],
  "nodes": [
    {
      "id": "53027864-f6ad-4161-9b98-d0b995e2afc6",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        1792,
        128
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "469819b5-378a-4c78-aeef-3f87d391324f",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "REVOKE_AWS_KEY"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "5c63d985-30d6-4fdc-85b4-c84548329a54",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "PAYMENT_PROCESSOR_KEY_ALERT"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "64e071ff-1a36-43f2-afbe-b71d83322b5b",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "ROTATE_DB_PASSWORD"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "47fd1fce-e90c-4c23-a905-73b646313e62",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1008,
        144
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "1f5b0666-113d-4d0b-bfc5-782dbc07e469",
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        1216,
        336
      ],
      "parameters": {
        "model": "anthropic/claude-sonnet-4.6",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "79b40d70-6ea8-448a-865f-d6f616025bca",
      "name": "Github Trigger On Push",
      "type": "n8n-nodes-base.githubTrigger",
      "position": [
        -256,
        144
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "list",
          "value": "artlab-ng",
          "cachedResultUrl": "https://github.com/artlab-ng",
          "cachedResultName": "artlab-ng"
        },
        "events": [
          "push"
        ],
        "options": {},
        "repository": {
          "__rl": true,
          "mode": "url",
          "value": "https://github.com/artlab-ng/artlab"
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e38577ba-0b3b-43de-9253-00dab46cc6b6",
      "name": "Code - Extract Useful Field-1",
      "type": "n8n-nodes-base.code",
      "position": [
        -48,
        144
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nconst body = $input.item.json.body;\nconst repo = body.repository.full_name;\nconst branch = body.ref.replace('refs/heads/', '');\nconst results = [];\n\nconst commit = body.head_commit;\nconst allFiles = [...(commit.added || []), ...(commit.modified || [])];\n\nallFiles.forEach(file => {\n  results.push({\n    json: {\n      fileName: file,\n      author: commit.author.name,\n      rawUrl: `https://raw.githubusercontent.com/${repo}/${branch}/${file}`,\n    }\n  });\n});\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "e092ad38-e8c6-49e1-af96-46ff4465de91",
      "name": "Fetch - Commit Changes From Github",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        160,
        144
      ],
      "parameters": {
        "url": "={{ $json.rawUrl }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "githubOAuth2Api"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        },
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "1b7329e8-6bf1-4aa7-b257-6959030e5ac2",
      "name": "Code - RegEx Scanner",
      "type": "n8n-nodes-base.code",
      "position": [
        384,
        144
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\n// Ensure we handle multiple files if passed from the previous HTTP node\nconst changes = items.map(i => i.json.data).join(\"\\n\");\n\nconst findings = [];\n\n/* -------- 1. AWS ACCESS KEY -------- */\n\nconst awsRegex = /AKIA[0-9A-Z]{16}/g;\nlet m;\nwhile ((m = awsRegex.exec(changes)) !== null) {\n  findings.push({\n    leaked_value: m[0],\n    detected_type: \"AWS_ACCESS_KEY\",\n  });\n}\n\n/* -------- 2. PAYMENT PROCESSOR KEYS (Paystack, Stripe, etc.) -------- */\n\nconst paymentKeyRegex =\n  /(sk_(live|test)_[0-9a-zA-Z]{24,}|pk_(live|test)_[0-9a-zA-Z]{24,})/g;\n\nwhile ((m = paymentKeyRegex.exec(changes)) !== null) {\n  findings.push({\n    leaked_value: m[0],\n    detected_type: \"PAYMENT_PROCESSOR_KEY\",\n  });\n}\n\n/* -------- 3. DATABASE URL -------- */\n\nconst dbRegex =\n  /(postgres(ql)?|mongodb(\\+srv)?|mysql|redis):\\/\\/[^\\s\"']+/gi;\n\nwhile ((m = dbRegex.exec(changes)) !== null) {\n  findings.push({\n    leaked_value: m[0],\n    detected_type: \"DATABASE_URL\",\n  });\n}\n\nreturn findings.map(f => ({ json: f }));"
      },
      "typeVersion": 2
    },
    {
      "id": "fef5e0e7-c991-4803-9bfa-2b3ca9c7499b",
      "name": "AI - Classifier",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1216,
        144
      ],
      "parameters": {
        "text": "=A GitHub commit triggered the secret leak detector.\n\nDetected secrets:\n{{ JSON.stringify($json.data, null, 2) }}\n\nAnalyze each finding and decide the appropriate security response.\nReturn JSON only.",
        "options": {
          "systemMessage": "You are a Security Incident Response Analyst.\n\nYou receive detected secrets from a Git commit. Detection is already verified.\nYour job is ONLY to decide the correct response action and generate messages for Jira and Slack.\n\nYou must choose ONE action from this fixed list:\n\n- REVOKE_AWS_KEY\n- PAYMENT_PROCESSOR_KEY_ALERT\n- ROTATE_DB_PASSWORD\n- IGNORE_KEY\n\nRules:\n\n1. If detected_type = AWS_ACCESS_KEY\n   \u2192 action = REVOKE_AWS_KEY\n\n2. If detected_type = PAYMENT_PROCESSOR_KEY\n   \u2192 action = PAYMENT_PROCESSOR_KEY_ALERT\n\n3. If detected_type = DATABASE_URL\n   \u2192 action = ROTATE_DB_PASSWORD\n\n4. If the leaked_value is clearly fake, placeholder, or test data\n   \u2192 action = IGNORE_KEY\n\nYou must return STRICT JSON (no markdown, no explanation).\n\nFor EACH detected item, return:\n\n{\n  \"leaked_value\": \"...\",\n  \"hash_leaked_value\": \"...\",\n  \"detected_type\": \"...\",\n  \"action\": \"...\",\n  \"jira_tickets\": \"...\",\n  \"slack_message\": \"...\"\n}\n\nThe jira_tickets field must be a short title + description.\nThe slack_message must be a short urgent security alert.\n\nDo not return arrays. Return one JSON object per input item."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "effbb27f-ab61-4f66-b1d4-0bd64c85400f",
      "name": "Code - Formatter",
      "type": "n8n-nodes-base.code",
      "position": [
        1552,
        144
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\n// 1. Get the raw string from the input\nconst rawOutput = $input.item.json.output;\nconst results = [];\n\nconst jsonBlocks = rawOutput.match(/```json\\s*([\\s\\S]*?)\\s*```/g);\n\nif (jsonBlocks) {\n  jsonBlocks.forEach(block => {\n    try {\n      const cleanString = block.replace(/```json/g, '').replace(/```/g, '').trim();\n      const parsed = JSON.parse(cleanString);\n      \n      results.push({ json: parsed });\n    } catch (e) {}\n  });\n}\n\n// 4. Fallback if no blocks were found or if it's a single raw string\nif (results.length === 0) {\n  try {\n    const fallback = JSON.parse(rawOutput.trim());\n    results.push({ json: fallback });\n  } catch (e) {\n    return [{ json: { error: \"No valid JSON found\", raw: rawOutput } }];\n  }\n}\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "41060c34-961e-442a-9703-fb3999ab4f25",
      "name": "Get - UserName From AWS",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2096,
        -96
      ],
      "parameters": {
        "url": "https://iam.amazonaws.com/",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "form-urlencoded",
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "Action",
              "value": "GetAccessKeyLastUsed"
            },
            {
              "name": "Version",
              "value": "2010-05-08"
            },
            {
              "name": "AccessKeyId",
              "value": "={{ $json.leaked_value }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "aws"
      },
      "credentials": {
        "aws": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "6ca43c15-8afd-4ba5-a065-f3d87941d197",
      "name": "Rename",
      "type": "n8n-nodes-base.set",
      "position": [
        2352,
        -96
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "4345faa5-882d-42f1-a33e-5b08e8e6fc9c",
              "name": "awsUserName",
              "type": "string",
              "value": "={{ $json.GetAccessKeyLastUsedResponse.GetAccessKeyLastUsedResult.UserName }}"
            },
            {
              "id": "4afbf9d6-e145-4116-9d88-1f306d787ce2",
              "name": "leaked_value",
              "type": "string",
              "value": "={{ $('Switch').item.json.leaked_value }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6d717f44-38c5-4709-abe7-2e732bd0d27a",
      "name": "Revoke AccessKey On AWS",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2592,
        -96
      ],
      "parameters": {
        "url": "https://iam.amazonaws.com/",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "form-urlencoded",
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "Action",
              "value": "=UpdateAccessKey"
            },
            {
              "name": "Version",
              "value": "2010-05-08"
            },
            {
              "name": "AccessKeyId",
              "value": "={{ $json.leaked_value }}"
            },
            {
              "name": "UserName",
              "value": "={{ $json.awsUserName }}"
            },
            {
              "name": "Status",
              "value": "Inactive"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "aws"
      },
      "credentials": {
        "aws": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.4,
      "waitBetweenTries": 3000
    },
    {
      "id": "1748c605-1742-457c-bed1-b9fc83f8579c",
      "name": "Send a message notification-1",
      "type": "n8n-nodes-base.slack",
      "position": [
        2832,
        -96
      ],
      "parameters": {
        "text": "={{ $('Switch').item.json.slack_message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0ASNF2DM8R",
          "cachedResultName": "all-automation-lab"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "60a2f75c-b64f-44b7-be67-510099b97db1",
      "name": "Send a message notification-2",
      "type": "n8n-nodes-base.slack",
      "position": [
        2352,
        144
      ],
      "parameters": {
        "text": "={{ $('Switch').item.json.slack_message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0ASNF2DM8R",
          "cachedResultName": "all-automation-lab"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "03276b4d-c825-4e27-a34f-9640b81a203d",
      "name": "Send a message notification-3",
      "type": "n8n-nodes-base.slack",
      "position": [
        2352,
        400
      ],
      "parameters": {
        "text": "={{ $('Switch').item.json.slack_message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0ASNF2DM8R",
          "cachedResultName": "all-automation-lab"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "4a93da7e-243f-4fc3-bf20-b22e5d6eb18f",
      "name": "Create an issue for leaked key",
      "type": "n8n-nodes-base.jira",
      "position": [
        2096,
        144
      ],
      "parameters": {
        "project": {
          "__rl": true,
          "mode": "list",
          "value": "10000",
          "cachedResultName": "Software Team"
        },
        "summary": "={{ $json.jira_tickets }}",
        "issueType": {
          "__rl": true,
          "mode": "list",
          "value": "10003",
          "cachedResultName": "Task"
        },
        "additionalFields": {}
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "629e1c80-3146-4a62-83a3-301b7ff33e8d",
      "name": "Create an issue for exposed database url",
      "type": "n8n-nodes-base.jira",
      "position": [
        2096,
        400
      ],
      "parameters": {
        "project": {
          "__rl": true,
          "mode": "list",
          "value": "10000",
          "cachedResultName": "Software Team"
        },
        "summary": "={{ $json.jira_tickets }}",
        "issueType": {
          "__rl": true,
          "mode": "list",
          "value": "10003",
          "cachedResultName": "Task"
        },
        "additionalFields": {}
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b1a8aed2-2326-4a2c-b78a-d0cb3c7cc275",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -368,
        -112
      ],
      "parameters": {
        "width": 672,
        "height": 544,
        "content": "## Ingestion & Extraction\n\n**Trigger:** GitHub Webhook listens for push events on the repository.\n\n**Extraction:** A custom JS node parses the commit metadata to find added or modified files.\n\n**Fetching:** The HTTP Request node pulls the raw source code of those files directly from GitHub."
      },
      "typeVersion": 1
    },
    {
      "id": "4d9e513f-2302-4592-a032-31ec94f5f94c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        -112
      ],
      "parameters": {
        "color": 5,
        "width": 788,
        "height": 544,
        "content": "## Multi-Layer Scanning\n\n**RegEx Scanner:** Performs a high-speed local scan for:\n\nAWS: AKIA patterns.\n\nFintech: Paystack and Stripe secret/public keys.\n\nDatabases: Postgres, MongoDB, MySQL, and Redis connection strings.\n\n**Hash Leaked Value:** Hash the leaked secret for idempotency persistent storage.\n\n**DataTable:** Check if the secret already been processed.\n\n**Aggregation:** All findings are bundled into a single data object for AI analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "a0b142a2-f9b0-49dc-a416-6a57e7d59d54",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        -192
      ],
      "parameters": {
        "color": 6,
        "width": 512,
        "height": 688,
        "content": "## AI Intelligence\n\n**Role**: Acts as a Security Incident Response Analyst.\n\n**Logic:** Validates if the leak is real or a placeholder (test data).\n\n**Output:** Returns a structured JSON object with a specific Action mapping:\n\n\nREVOKE_AWS_KEY: Triggers the automated AWS kill-switch.\n\nPAYMENT_PROCESSOR_KEY: For Requires manual revocation via the provider dashboard to prevent unauthorized financial transactions or data access.\n\nROTATE_DB_PASSWORD: Specifically for database credential exposure.\n\nIGNORE_KEY: For false positives."
      },
      "typeVersion": 1
    },
    {
      "id": "a762d542-5379-476d-8969-6d30c08fddb3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1760,
        -288
      ],
      "parameters": {
        "color": 4,
        "width": 1488,
        "height": 896,
        "content": "## Automated Response (The Switch)\n\n**Action,Execution Steps**\n**AWS Revocation,Get IAM Username \u2192 UpdateAccessKey (Status: Inactive) \u2192 Slack Alert**\n**Key Alerts,Create Jira Task \u2192 Slack Alert**\n**DB Rotation,Create Jira Task \u2192 Slack Alert**"
      },
      "typeVersion": 1
    },
    {
      "id": "d4ad5fc7-7cae-4c63-9a40-77e7f2d83e52",
      "name": "Code - Hash Leaked Value",
      "type": "n8n-nodes-base.code",
      "position": [
        592,
        144
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n  const secret = item.json.leaked_value;\n  \n  let h1 = 0xdeadbeef;\n  let h2 = 0x41c6ce57;\n\n  for (let i = 0; i < secret.length; i++) {\n    const ch = secret.charCodeAt(i);\n    h1 = Math.imul(h1 ^ ch, 2654435761);\n    h2 = Math.imul(h2 ^ ch, 1597334677);\n  }\n\n  h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822519);\n  h1 = h1 >>> 0;\n  h2 = Math.imul(h2 ^ (h2 >>> 13), 3266489917);\n  h2 = h2 >>> 0;\n\n  const finalHash = (h1.toString(16).padStart(8, '0') + h2.toString(16).substring(0, 2));\n  \n  item.json.hash_leaked_value = \"hash_\" + finalHash;\n}\n\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "af233190-717a-4a0f-9d4b-925bc742ece3",
      "name": "If row does not exist",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        800,
        144
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "hash_key",
              "keyValue": "={{ $json.hash_leaked_value }}"
            }
          ]
        },
        "operation": "rowNotExists",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "n736A4FmqsoWbxtH",
          "cachedResultUrl": "/projects/fXqNaRMFXN8afHCV/datatables/n736A4FmqsoWbxtH",
          "cachedResultName": "processed_secrets"
        }
      },
      "typeVersion": 1.1,
      "alwaysOutputData": false
    },
    {
      "id": "2f353f09-c93e-4649-be27-1d5b2457fe80",
      "name": "Save To DataTable-1",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        3040,
        -96
      ],
      "parameters": {
        "columns": {
          "value": {
            "hash_key": "={{ $('Switch').item.json.leaked_value }}"
          },
          "schema": [
            {
              "id": "hash_key",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "hash_key",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "hash_key"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "n736A4FmqsoWbxtH",
          "cachedResultUrl": "/projects/fXqNaRMFXN8afHCV/datatables/n736A4FmqsoWbxtH",
          "cachedResultName": "processed_secrets"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "0e549f7c-0c8f-4345-b851-be7d67d1bea4",
      "name": "Save To DataTable-2",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2592,
        144
      ],
      "parameters": {
        "columns": {
          "value": {
            "hash_key": "={{ $('Switch').item.json.leaked_value }}"
          },
          "schema": [
            {
              "id": "hash_key",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "hash_key",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "hash_key"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "n736A4FmqsoWbxtH",
          "cachedResultUrl": "/projects/fXqNaRMFXN8afHCV/datatables/n736A4FmqsoWbxtH",
          "cachedResultName": "processed_secrets"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "b487ed40-f8f9-4a87-a10c-50889b9a2122",
      "name": "Save To DataTable-3",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2592,
        400
      ],
      "parameters": {
        "columns": {
          "value": {
            "hash_key": "={{ $('Switch').item.json.leaked_value }}"
          },
          "schema": [
            {
              "id": "hash_key",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "hash_key",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "hash_key"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "n736A4FmqsoWbxtH",
          "cachedResultUrl": "/projects/fXqNaRMFXN8afHCV/datatables/n736A4FmqsoWbxtH",
          "cachedResultName": "processed_secrets"
        }
      },
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "QasDp9g5Btc4p7sY",
    "timeSavedMode": "fixed",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "df1cbaae-0a51-4a2e-9ce6-8b146d56d874",
  "connections": {
    "Rename": {
      "main": [
        [
          {
            "node": "Revoke AccessKey On AWS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Get - UserName From AWS",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create an issue for leaked key",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create an issue for exposed database url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "AI - Classifier",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI - Classifier": {
      "main": [
        [
          {
            "node": "Code - Formatter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Formatter": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - RegEx Scanner": {
      "main": [
        [
          {
            "node": "Code - Hash Leaked Value",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If row does not exist": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI - Classifier",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Github Trigger On Push": {
      "main": [
        [
          {
            "node": "Code - Extract Useful Field-1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get - UserName From AWS": {
      "main": [
        [
          {
            "node": "Rename",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Revoke AccessKey On AWS": {
      "main": [
        [
          {
            "node": "Send a message notification-1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Hash Leaked Value": {
      "main": [
        [
          {
            "node": "If row does not exist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Extract Useful Field-1": {
      "main": [
        [
          {
            "node": "Fetch - Commit Changes From Github",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message notification-1": {
      "main": [
        [
          {
            "node": "Save To DataTable-1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message notification-2": {
      "main": [
        [
          {
            "node": "Save To DataTable-2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message notification-3": {
      "main": [
        [
          {
            "node": "Save To DataTable-3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create an issue for leaked key": {
      "main": [
        [
          {
            "node": "Send a message notification-2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch - Commit Changes From Github": {
      "main": [
        [
          {
            "node": "Code - RegEx Scanner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create an issue for exposed database url": {
      "main": [
        [
          {
            "node": "Send a message notification-3",
            "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

SecretOps is an n8n security automation workflow that monitors Git push events, detects high-risk secrets in commits, and automatically responds in real time.

Source: https://n8n.io/workflows/15314/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

Who is this for? Agencies, consultants, and service providers who conduct discovery calls and need to quickly turn conversations into professional proposals.

Tool Think, Tool Calculator, Agent Tool +18
AI & RAG

YouTube Strategist. Uses formTrigger, splitOut, splitInBatches, agent. Event-driven trigger; 50 nodes.

Form Trigger, Agent, OpenRouter Chat +5
AI & RAG

This advanced multi-phase n8n workflow automates the complete research, analysis, and ideation pipeline for a YouTube strategist. It scrapes competitor channels, analyzes top-performing titles and thu

Form Trigger, Agent, OpenRouter Chat +5
AI & RAG

Receives campaign parameters via form, creates a Smartlead campaign, sources qualified leads through Wiza based on your ICP description, researches each prospect with Perplexity AI, generates personal

HTTP Request, Output Parser Structured, Memory Buffer Window +6
AI & RAG

This is a Telegram AI-to-Human Handover System that seamlessly transitions customer support conversations between an AI agent and human operators: AI-First Response: When users message the Telegram bo

Telegram Trigger, Telegram, Email Send +7