> For the complete documentation index, see [llms.txt](https://docs.forestall.io/forestall/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/forestall/edges/github/gh_owner.md).

# GH\_OWNER

## Summary

|                              |                           |
| ---------------------------- | ------------------------- |
| **Forestall ACL Alias**      | GH\_OWNER                 |
| **Edge Type**                | Attack Path               |
| **Affected Object Types**    | GitHub Organizations      |
| **Exploitation Certainty**   | Certain                   |
| **GitHub Role / Permission** | Organization `owner` role |

## Description

`GH_OWNER` represents that a user holds the **owner** role on a GitHub organization. The owner role is the highest level of privilege in a GitHub organization — equivalent to AWS's `AdministratorAccess` (`AWS_ADMIN`) or Active Directory's Domain Admin.

An organization owner has unrestricted control over every resource and setting in the organization:

* Full administrative access to **all repositories**, including private ones, regardless of explicit repository grants.
* Ability to add or remove members, grant or revoke the owner role, and manage all teams.
* Control over organization-wide security policy — two-factor authentication enforcement, default repository permissions, and member privileges.
* Access to all organization secrets and the ability to configure webhooks, GitHub Apps, and SSO/SAML settings.

Because an owner can already reach every asset in the organization, this edge is a **terminal attack path** — once an attacker controls an owner account, no further traversal is required to compromise the organization.

This edge is computed from the organization role returned by the GitHub API: a user whose membership role is `admin` (surfaced as `owner` in the organization UI) is connected to the organization via `GH_OWNER`.

## Identification

### GitHub Web Interface

1. Navigate to your GitHub Organization page.
2. Open the **People** tab.
3. Use the **Role** filter and select **Owner** to list all organization owners.

### GitHub CLI

List the owners (admins) of an organization:

```bash
gh api "orgs/{org}/members?role=admin" --paginate --jq '.[].login'
```

Check a specific user's role in the organization:

```bash
gh api "orgs/{org}/memberships/{username}" --jq '.role'
```

### GitHub API

Enumerate all members and their roles:

```bash
gh api "orgs/{org}/members?role=admin" --paginate \
  --jq '.[] | {login: .login, id: .id}'
```

## Exploitation

There is no multi-step exploit required — the owner role **is** full control. An attacker who compromises an owner account (through a stolen password, a missing 2FA factor, a leaked Personal Access Token, or session theft) immediately gains organization-wide administrative access.

Typical actions following owner compromise:

1. **Access every repository.** Clone all private source code, including repositories the account was never explicitly added to.

   ```bash
   gh repo list {org} --limit 1000
   gh repo clone {org}/{repo}
   ```
2. **Establish persistence.** Promote an attacker-controlled account to owner, or invite a new member and grant the owner role.

   ```bash
   gh api --method PUT "orgs/{org}/memberships/{attacker}" -f role=admin
   ```
3. **Weaken security controls.** Disable the 2FA requirement, lower the default repository permission, or remove branch protection to enable further attacks.
4. **Exfiltrate secrets and pivot.** Read organization and repository secrets, then use CI/CD or OIDC federation to pivot into connected cloud environments.

## Mitigation

1. **Minimize the number of owners.** Keep the owner role to the smallest possible set. Every owner is a full-organization compromise risk.
   * Navigate to **Organization → People**, filter by **Owner**, and downgrade anyone who does not require organization-wide administration to **Member**.
2. **Require two-factor authentication for owners.** Owner accounts without 2FA are the single highest-value target. Enforce 2FA org-wide (see `FS6011`).
3. **Use teams and repository roles for day-to-day access** instead of granting the owner role. Most administrative tasks can be delegated through custom organization roles or team maintainer rights.
4. **Review owners regularly.** Treat the owner list as a Tier-0 asset and audit it on a fixed cadence, removing accounts that no longer need the role.
5. **Protect owner credentials.** Require hardware security keys for owners and rotate any Personal Access Tokens with `admin:org` scope.

## Detection

Monitor the GitHub audit log for changes to organization ownership:

| Event                | Description                                           |
| -------------------- | ----------------------------------------------------- |
| `org.update_member`  | A member's role was changed (e.g., promoted to owner) |
| `org.add_member`     | A member was added to the organization                |
| `org.invite_member`  | A user was invited to the organization                |
| `business.add_admin` | An enterprise/organization administrator was added    |

Alert on any promotion to the owner role, especially when performed outside of an approved change process. Cross-reference with the actor: an unexpected actor promoting an account to owner is a strong indicator of compromise.

## References

* <https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization>
* <https://docs.github.com/en/rest/orgs/members#list-organization-members>
* <https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization>
