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

# GH\_HAS\_ACCESS

## Summary

|                              |                                                                          |
| ---------------------------- | ------------------------------------------------------------------------ |
| **Forestall ACL Alias**      | GH\_HAS\_ACCESS                                                          |
| **Edge Type**                | Relationship                                                             |
| **Affected Object Types**    | GitHub Repositories                                                      |
| **Exploitation Certainty**   | N/A (structural)                                                         |
| **GitHub Role / Permission** | Any team repository permission (pull / triage / push / maintain / admin) |

## Description

`GH_HAS_ACCESS` is a **structural relationship** recording that a team has been granted access to a repository, together with the permission level the team holds. The level is stored on the edge as the `Permission` property: `pull`, `triage`, `push`, `maintain`, or `admin`.

This edge captures **all** team-to-repository access regardless of level — it answers "which teams can reach this repository, and how much access do they have?". It is the foundation that other, privileged edges are derived from:

* A team with `admin` also gets the `GH_ADMIN` attack-path edge.
* A team with `push`/`maintain` on an unprotected default branch also gets the `GH_PUSH_TO_DEFAULT` attack-path edge.

Because team membership flows to users via `GH_IN_TEAM`, this edge is how a user ultimately inherits repository access through their teams. As a structural relationship it is not itself a traversable attack path — it describes the access graph that the attack-path edges are computed over.

## Identification

### GitHub Web Interface

1. Open the repository → **Settings → Collaborators and teams**.
2. The **Teams** section lists every team with access and its role (Read / Triage / Write / Maintain / Admin).

### GitHub CLI

List teams with access to a repository and their permission:

```bash
gh api "repos/{org}/{repo}/teams" --paginate \
  --jq '.[] | {slug: .slug, permission: .permission}'
```

List the repositories a team can access:

```bash
gh api "orgs/{org}/teams/{team_slug}/repos" --paginate \
  --jq '.[] | {repo: .full_name, permission: .role_name}'
```

## Exploitation

Not applicable — this is a structural relationship, not a traversable attack path. The security-relevant capabilities derived from team access are exploited through the privileged edges built on top of it (`GH_ADMIN`, `GH_PUSH_TO_DEFAULT`).

## Mitigation

1. **Grant teams the least sufficient permission.** Prefer `read`/`triage` over `write`, and reserve `admin` for the few teams that genuinely administer the repository.
2. **Review team access periodically.** Remove teams that no longer need a repository, and downgrade over-permissioned grants. Pay particular attention to teams with `admin` or `maintain` on repositories holding secrets or cloud federation.
3. **Use nested teams deliberately.** Child teams inherit parent access; keep the hierarchy shallow and intentional so access is easy to reason about.

## Detection

| Event                               | Description                                       |
| ----------------------------------- | ------------------------------------------------- |
| `team.add_repository`               | A team was granted access to a repository         |
| `team.remove_repository`            | A team's access to a repository was removed       |
| `team.update_repository_permission` | A team's permission level on a repository changed |

Alert on grants of `admin`/`maintain` to teams on sensitive repositories, and on permission escalations performed outside an approved change process.

## References

* <https://docs.github.com/en/rest/teams/teams#list-team-repositories>
* <https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization>
