AutomationFlowsSlack & Telegram › Monitor Github Repo Access and Push Events with Github and Slack Alerts

Monitor Github Repo Access and Push Events with Github and Slack Alerts

ByRamS @rams1005 on n8n.io

This workflow monitors GitHub for high-risk activities to ensure that only authorized users can modify the repository. It periodically polls GitHub for events such as PushEvent, MemberEvent, and PublicEvent.

Cron / scheduled trigger★★★★☆ complexity16 nodesData TableHTTP RequestSlack
Slack & Telegram Trigger: Cron / scheduled Nodes: 16 Complexity: ★★★★☆ Added:

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

This workflow follows the Datatable → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

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

Download .json
{
  "id": "GAODuENBveqRdHlq",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Monitor GitHub Repositories for Unauthorized Actions",
  "tags": [],
  "nodes": [
    {
      "id": "fec58465-8d55-497b-8550-b2571ef4cebf",
      "name": "Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        688,
        608
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3e4b9b99-152f-4a49-a358-fb3756068da7",
      "name": "Filter Member Events",
      "type": "n8n-nodes-base.code",
      "position": [
        1136,
        608
      ],
      "parameters": {
        "jsCode": "// This node filters the raw GitHub events for security risks\nconst items = $input.all();\n\nreturn items.filter(item => {\n  // Define what you consider a security event\n  // you may leave out PushEvents e.g. commits, other less critical non-sec changes\n  const criticalEvents = [\n    'MemberEvent', // Someone added/removed from repo\n    'PublicEvent', // Repo made public (VERY IMPORTANT)\n    'TeamAddEvent', // Team access changed\n    'PushEvent' // To See every commit event\n  ];\n  return criticalEvents.includes(item.json.type);\n});"
      },
      "typeVersion": 1
    },
    {
      "id": "4d1f6e99-53c5-4662-b26d-229d018b52b0",
      "name": "Check Whitelist",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1344,
        608
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "github_username",
              "keyValue": "={{ $json.type === 'MemberEvent' ? $json.payload.member.login : $json.actor.login }}"
            }
          ]
        },
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "7mEomjLDrAwIBwFl",
          "cachedResultUrl": "/projects/A5ypxGvZ8T1gIWVL/datatables/7mEomjLDrAwIBwFl",
          "cachedResultName": "it_whitelist"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "27e8f26a-e630-4f77-8bbf-4a8eb1f23e90",
      "name": "Github Events (HTTP)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        928,
        608
      ],
      "parameters": {
        "url": "https://api.github.com/repos/<user_name>/<repository>/events",
        "options": {},
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github+json"
            },
            {
              "name": "X-GitHub-Api-Version",
              "value": "2022-11-28"
            }
          ]
        },
        "nodeCredentialType": "githubApi"
      },
      "credentials": {
        "githubApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "48130fa9-634d-4755-b16e-503394ac44ab",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        1552,
        592
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "3f93352d-3e9b-413f-87e1-a792602d5418",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Filter Member Events').item.json.type }}",
                    "rightValue": "MemberEvent"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "e607b280-bce6-4d14-b65d-f13b522b141a",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Filter Member Events').item.json.type }}",
                    "rightValue": "PublicEvent"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "184f10a0-60cc-43af-9bc0-85e273b6ffcd",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Filter Member Events').item.json.type }}",
                    "rightValue": "PushEvent"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "9d8319f3-948e-4453-94b4-1d0a7067a456",
      "name": "PublicEvent",
      "type": "n8n-nodes-base.if",
      "position": [
        1760,
        608
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d560f6d6-cdbe-4abf-b9bb-bf2096d07d2f",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.role }}",
              "rightValue": "admin"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "ed17c63b-dec3-41df-a533-c7e57e902f51",
      "name": "PushEvent",
      "type": "n8n-nodes-base.if",
      "position": [
        1760,
        768
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "08a9cbfc-6db1-4c47-b21f-a195f4551b94",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.role }}",
              "rightValue": "="
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "31f6a4b0-4a65-46a5-ae7c-6db969fdffc8",
      "name": "MemberEvent",
      "type": "n8n-nodes-base.if",
      "position": [
        1760,
        448
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "40be187c-e40f-4781-a911-0bc6c4cc1357",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Filter Member Events').item.json.type }}",
              "rightValue": "admin"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "e90ae829-d324-4c26-a3ea-f755b87ca245",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        208
      ],
      "parameters": {
        "width": 608,
        "height": 784,
        "content": "\n## Monitor GitHub Repositories for Unauthorized Actions\n\n### How it works:\n\nThis workflow monitors GitHub for high-risk activities to ensure that only authorized users can modify the repository. It periodically polls GitHub for events such as PushEvent, MemberEvent, and PublicEvent.\n\nFor each event, the workflow extracts the username of actor and looks it up in the it_whitelist data table to determine the user\u2019s role. A Switch node then routes the event to the appropriate validation logic.\n\n\u2022 Member & Public events: Only users with the admin role are allowed. Any non-admin action such as adding a repository member or changing a private repository to public triggers an alert.\n\u2022 Push events: The user must exist in the whitelist. If no role is found, the user is treated as unknown and flagged.\n\nAll unauthorized actions are reported to Slack, including the event type, actor name, and repository details.\n\n### Setup Steps:\nCredentials: Connect your GitHub Personal Access Token and Slack Bot Token.\n\nCreate a Data Table named it_whitelist with columns github_username and role. Add your GitHub username with the role admin to prevent self-alerts. Accordingly, add other developers and members in your organization with appropriate roles to white list them.\n\nSwitch Configuration: Use the expression {{ $item.json.type }} in 'Rules' mode to route events.\n\nLogic: \nConfigure the PushEvent IF node to flag users whose role is empty or missing.\nConfigure the Member and Public IF nodes to flag users whose role is not admin."
      },
      "typeVersion": 1
    },
    {
      "id": "b6f4481b-bcc3-45c0-bef6-cca5a5c43ca3",
      "name": "Push Event Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2160,
        752
      ],
      "parameters": {
        "text": "=\ud83d\udea8 Security Alert: Unauthorized {{ $('Filter Member Events').item.json.type }} by {{ $json.actor.login }}!",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0917N0QN2C",
          "cachedResultName": "content-creation-agent"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "396f4a16-2432-4911-9ea4-27d04c94892f",
      "name": "Public Event Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2160,
        592
      ],
      "parameters": {
        "text": "epository {{ $json.repository.name }} was made PUBLIC by {{ $json.actor.login }}! \ud83d\udea8 Immediate review required.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0917N0QN2C",
          "cachedResultName": "content-creation-agent"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "fe332c78-fee3-4802-bcee-0fd3395696e6",
      "name": "Member Event Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2160,
        432
      ],
      "parameters": {
        "text": "Unauthorized MemberEvent! Actor: {{ $json.actor.login }} tried to add {{ $json.payload.member.login }}. \u26a0\ufe0f This action was blocked/flagged because the actor is not an Admin.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0917N0QN2C",
          "cachedResultName": "content-creation-agent"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "489f1636-61db-4375-8f6c-a0c1eaf84bf5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        368
      ],
      "parameters": {
        "color": 7,
        "width": 576,
        "height": 384,
        "content": "## GitHub Events & Identity Check\n\nGitHub Node: Polls the API every 10 minutes to fetch the latest events and activity logs.\n\nFilter: Passes only Member, Public, and Push events while ignoring irrelevant data.\n\nCheck \"Whitelist\" Datatable : Searches the it_whitelist Data Table for the authorized users and user's role (admin/developer)."
      },
      "typeVersion": 1
    },
    {
      "id": "dc7b7e02-a468-4d72-b27b-7eb1ae2b57db",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        208
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 768,
        "content": "## Switch and If Nodes to apply Security rules\n\nSwitch: Evaluates the event type (such as PushEvent) and routes the workflow into three dedicated branches, allowing event-specific security policies to be applied.\n\nFlag the activity as unauthorized using If:\n\u2013 the event is Member or Public and the user\u2019s role is not admin, or\n\u2013 the event is a Push and the user is not found in the whitelist (role is empty or unavailable).\n\nOverall, rules are set such that data is sent to True output to send Alerts only when a security violation is detected."
      },
      "typeVersion": 1
    },
    {
      "id": "e3cac6f2-eeac-4274-9a71-944bee482de5",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1984,
        832
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "27e410da-5e06-4ff3-abff-1bdbd289a574",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        208
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 768,
        "content": "## Slack Node (Alert System)\nNotify: Posts a message containing the event type and the GitHub username of the person who triggered it.\n\nTrigger: Only fires when a violation flows through the True path of a security check node."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "7e87b531-024e-4d39-bed9-91e42b52ec47",
  "connections": {
    "Switch": {
      "main": [
        [
          {
            "node": "MemberEvent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "PublicEvent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "PushEvent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule": {
      "main": [
        [
          {
            "node": "Github Events (HTTP)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PushEvent": {
      "main": [
        [
          {
            "node": "Push Event Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MemberEvent": {
      "main": [
        [
          {
            "node": "Member Event Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PublicEvent": {
      "main": [
        [
          {
            "node": "Public Event Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Whitelist": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Member Events": {
      "main": [
        [
          {
            "node": "Check Whitelist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Github Events (HTTP)": {
      "main": [
        [
          {
            "node": "Filter Member Events",
            "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

This workflow monitors GitHub for high-risk activities to ensure that only authorized users can modify the repository. It periodically polls GitHub for events such as PushEvent, MemberEvent, and PublicEvent.

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

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

This workflow is an automated employee time tracking and reporting system that monitors weekly work hours via TMetric, then delivers personalized summaries directly to each team member on Slack. It co

HTTP Request, Item Lists, Data Table +1
Slack & Telegram

Import Productboard Notes Companies And Features Into Snowflake. Uses stickyNote, httpRequest, splitOut, snowflake. Scheduled trigger; 35 nodes.

HTTP Request, Snowflake, Slack
Slack & Telegram

Import Productboard Notes, Companies and Features into Snowflake. Uses stickyNote, httpRequest, splitOut, snowflake. Scheduled trigger; 35 nodes.

HTTP Request, Snowflake, Slack
Slack & Telegram

This workflow imports Productboard data into Snowflake, automating data extraction, mapping, and updates for features, companies, and notes. It supports scheduled weekly updates, data cleansing, and S

HTTP Request, Snowflake, Slack
Slack & Telegram

This workflow automates the full company enrichment pipeline: Simply import CSV company lists to Slack and save time on enrichment and CRM maintenance. It processes uploaded files, extracts company do

Slack Trigger, Slack, HTTP Request +3