{
  "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
          }
        ]
      ]
    }
  }
}