> 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_has_role.md).

# GH\_HAS\_ROLE

## Summary

|                              |                                     |
| ---------------------------- | ----------------------------------- |
| **Forestall ACL Alias**      | GH\_HAS\_ROLE                       |
| **Edge Type**                | Relationship                        |
| **Affected Object Types**    | GitHub Organization Roles           |
| **Exploitation Certainty**   | N/A (structural)                    |
| **GitHub Role / Permission** | Direct organization-role assignment |

## Description

`GH_HAS_ROLE` is a **structural relationship** recording that a user or team has been directly assigned a GitHub **organization role** (`GHOrgRole`). Organization roles — both GitHub's predefined roles and an org's custom roles — are named bundles of fine-grained permissions.

This edge is the structural access layer for organization roles, mirroring GCP's `GCP_HAS_ROLE`: it connects the principal to the role node, while the role node connects to the organization via `GH_PARENT`. Together they answer "which principals hold which roles, and what does each role grant?".

The security-relevant *capabilities* a role confers are derived into attack-path edges (for example `GH_MANAGE_ROLES` when the role grants "manage custom organization roles"). `GH_HAS_ROLE` itself is the underlying assignment, not a traversable attack path.

## Identification

### GitHub Web Interface

1. Open the organization → **Settings → Organization roles → Role assignments**.
2. Each assignment shows the principal (user or team) and the role they hold.

### GitHub CLI

List the users and teams assigned to a role:

```bash
gh api "orgs/{org}/organization-roles/{role_id}/users" --paginate --jq '.[].login'
gh api "orgs/{org}/organization-roles/{role_id}/teams" --paginate --jq '.[].slug'
```

## Exploitation

Not applicable — this is a structural relationship. The capabilities a role grants are exploited through the derived attack-path edges built on top of it (e.g. `GH_MANAGE_ROLES`).

## Mitigation

1. **Assign roles sparingly and review them.** Audit role assignments regularly, especially for roles that carry organization-administration permissions.
2. **Prefer least-privilege roles.** Assign the narrowest role that satisfies the need; avoid broad predefined roles (e.g. all-repository admin) where a scoped role suffices.
3. **Manage assignments through an approved process** rather than ad-hoc grants.

## Detection

| Event                                                             | Description                   |
| ----------------------------------------------------------------- | ----------------------------- |
| `organization_role.user_add`                                      | A role was assigned to a user |
| `organization_role.team_add`                                      | A role was assigned to a team |
| `organization_role.user_remove` / `organization_role.team_remove` | A role assignment was removed |

Alert on assignments of privileged roles, especially outside an approved change process.

## References

* <https://docs.github.com/en/rest/orgs/organization-roles>
* <https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/about-custom-organization-roles>
