Detecting GitHound Enumeration via the GitHub API

Detecting GitHound Enumeration via the GitHub API

For many organizations, GitHub Enterprise serves as a central platform for software development, collaboration, and source code management. This makes it an increasingly valuable target for attackers seeking access to source code, sensitive information, credentials, and development infrastructure.

Recent incidents demonstrate an increasing preference among attackers for targeting GitHub environments. In March 2026, the Trivy supply-chain attack involved stolen credentials being used to publish malicious releases and tamper with GitHub Actions. The compromise subsequently extended to Checkmarx’s GitHub environment, where attackers gained unauthorized repository access and distributed malicious code through developer tools and CI/CD. In May 2026, GitHub itself disclosed that an employee device had been compromised through a malicious VS Code extension, resulting in the exfiltration of internal repositories. In May 2026, a reported exposure of sensitive CISA information through a public GitHub repository highlighted how misconfigured access and unintended data disclosure can expose sensitive information. These incidents highlight the growing importance of protecting and monitoring code repositories. Tools such as GitHound, a BloodHound OpenGraph collector for GitHub released by SpecterOps earlier in 2026, can help defenders map a GitHub organization’s environment by identifying relationships between users, teams, repositories, and permissions. This allows them to understand access relationships, identify excessive privileges, and uncover potential attack paths. However, the same capabilities can also be leveraged by adversaries to map an organization’s GitHub environment, discover accessible resources, and identify opportunities for further access.

With this in mind, I took a closer look at GitHub Enterprise audit logs and whether they can be used to detect enumeration through the GitHub API.

GitHound interacts directly with the GitHub API to collect information about an organization’s users, teams, repositories, and permissions. To do so, it requires a GitHub access token with the appropriate permissions to access the resources being queried. The scope of the collected data therefore depends on the token’s privileges.

To authenticate GitHound, create a personal access token (PAT) on GitHub.

  1. Navigate to GitHub’s personal access token settings for your account.
  2. Select Tokens, then click Generate new token.
  3. Provide a descriptive name and set an appropriate expiration date.
  4. Configure the repository access and permissions required for the resources you intend to collect. Use the GitHub documentation to understand the available permissions.
  5. Generate the token and copy it immediately.

GitHub personal access token configuration

Download the tool from the official SpecterOps GitHound repository.

Open a PowerShell session and run the following commands.

powershell

. ./githound.ps1

GitHound module loading)

GitHound module loading

powershell

$session = New-GitHubSession -OrganizationName "<YourOrgName>" -Token "<personal_access_token>"

GitHound session variable creation)

GitHound session variable creation

powershell

Invoke-GitHound -Session $session

Alternatively, collect all available data:

powershell

Invoke-GitHound -Session $session -CollectAll

GitHound execution)

GitHound execution

As GitHound makes API requests to enumerate these resources, its activity will be visible in GitHub audit logs, providing an opportunity for defenders to investigate and detect potentially suspicious patterns of API usage. Before building a detection for GitHub API enumeration, it is important to ensure that the relevant audit events are being collected.

  1. Sign in to GitHub with an enterprise owner account and navigate to Settings.

  2. Open Audit log and select Log streaming. For our tests, we selected streaming to Azure Blob Storage to ingest the logs into Microsoft Sentinel via the GitHub data connector from Microsoft’s Content Hub.

  3. Create a new audit log stream and configure the destination where the logs will be sent.

    GitHub audit log streaming configuration)

  4. In the Settings tab, enable Enable API Request Events so that API activity is captured alongside other audit events.

    GitHub API request events setting)

  5. Save the configuration and verify that events are arriving at the configured destination.

For detailed instructions, refer to GitHub’s official documentation: Streaming the audit log for your enterprise.

GitHound’s API activity is visible in the GitHub audit logs, providing an opportunity to detect enumeration through Microsoft Sentinel.

GitHound enumeration activity)

GitHound enumeration activity

The query focuses on API routes commonly used to retrieve organizational information, including repositories, teams, permissions, and GitHub Actions configuration. It counts the distinct routes and URL paths accessed by an actor and compares these counts against predefined thresholds to identify potential enumeration activity.

While this behavior is consistent with GitHound, the detection identifies an enumeration pattern rather than this specific tool.

kusto

let route_threshold = 10;
let url_path_threshold = 20;
let routes_of_interest = dynamic([
    @'/graphql',
    @'/organizations/:organization_id/organization-roles/:role_id/teams',
    @'/organizations/:organization_id/actions/secrets',
    @'/organizations/:organization_id/custom-repository-roles',
    @'/organizations/:organization_id/repos',
    @'/organizations/:organization_id/secret-scanning/alerts',
    @'/organizations/:organization_id/organization-roles/:role_id/users',
    @'/organizations/:organization_id/actions/permissions/self-hosted-runners',
    @'/organizations/:organization_id/actions/permissions',
    @'/organizations/:organization_id/actions/variables',
    @'/organizations/:organization_id',
    @'/organizations/:organization_id/actions/permissions/workflow',
    @'/organizations/:organization_id/organization-roles',
    @'/organizations/:organization_id/teams'
]);
GitHubAuditLogsV3_CL
| where Action == "api.request"
| project-reorder UrlPath, Route, RequestMethod, QueryString, StatusCode, UserAgent
| where Route in~ (routes_of_interest)
| summarize
    c = count(),
    RequestMethod = make_set(RequestMethod),
    StatusCode = make_set(StatusCode),
    Route = make_set(Route),
    UrlPath = make_set(UrlPath),
    UserAgent = make_set(UserAgent),
    User = make_set(User),
    OperationType = make_set(OperationType),
    Org = make_set(Org),
    OrgId = make_set(OrgId),
    ActorId = make_set(ActorId),
    ActorIsBot = make_set(ActorIsBot),
    ProgrammaticAccessType = make_set(ProgrammaticAccessType),
    TokenScopes = make_set(TokenScopes),
    Type = make_set(Type),
    Action = make_set(Action),
    Business = make_set(Business)
    by Actor, TokenId
| extend RouteCount = array_length(Route)
| extend UrlPathCount = array_length(UrlPath)
| where RouteCount > route_threshold
    or UrlPathCount > url_path_threshold

GitHub API enumeration query results)

GitHub API enumeration query results

GitHub API enumeration can provide attackers with valuable insight into an organization’s repositories, permissions, and development workflows, making API monitoring essential for protecting development environments.

In this blog post, we demonstrated how GitHound’s activity can be observed in GitHub audit logs and how to detect the API enumeration pattern. By enabling API request logging and implementing this or similar detections, defenders can improve visibility across their GitHub Enterprise environment and identify suspicious activity at an early stage.

Related Content