# ghtier > A static, read-only reference for GitHub security. It maps every way access > is granted in GitHub (permissions, roles, classic scopes and tokens, keys and > policies) to one tier scale (Tier 0=Critical .. Tier 3=Low), comparable > everywhere, and links them to real attack paths, incidents and fixes. Roles > and scopes inherit their tier from the permissions they include. It does not > connect to any GitHub account, org, or API. ## Data (static JSON, generated from the same source as the pages) - [/data/index.json](/data/index.json): Manifest of the exports below. - [/data/permissions.json](/data/permissions.json): The base layer. Every GitHub App, fine-grained PAT and GITHUB_TOKEN permission at every level (190), each with a tier, a short reason, an area and plane (control, management, data), where it can be granted, the setups it exists on (Free, Team, Enterprise Cloud, Enterprise Managed Users, Enterprise Server; from GitHub's docs data), and sample REST endpoints. - [/data/roles.json](/data/roles.json): 26 built-in GitHub roles (repository, organization, team, enterprise). Each lists the permissions it includes, where each comes from (GitHub's role tables or docs), and a tier inherited from the strongest permission, with the permission that sets it, plus the setups it exists on with the docs page that says so. Also the 70 permissions GitHub lets you add to a custom repository or organization role, each mapped to permissions. - [/data/scopes.json](/data/scopes.json): 41 classic PAT and OAuth App scopes. Each lists the permissions it reaches with the evidence (REST endpoints from GitHub's docs that need both), a tier inherited from the strongest one, its sub-scopes and the setups it exists on. Also the kinds of token GitHub issues and the highest tier each can carry. - [/data/keys-policies.json](/data/keys-policies.json): 38 keys and credentials, policies, grants, AI agents and systems outside GitHub, each with its tier, reason, attack path, related permissions, the setups it exists on with any condition, and the audit log events to alert on. - [/data/changes.json](/data/changes.json): The same history as /changes, newest first: date, kind (permission, role-action, scope, api-version), change (added, removed, changed), name, detail, and a link to the ghtier page. - [/data/updates.json](/data/updates.json): What was added or changed on ghtier itself, newest first: date, kind (feature, improvement, fix, content, maintenance), one short line, the pages it touched and the PR number. - [/data/findings.json](/data/findings.json): 15 strange findings, places where GitHub access works differently from what most people expect. Each has what people expect, what GitHub does, how to check, how to close it, the permissions, roles, scopes or keys involved, the setups it applies to, and the GitHub docs or changelog source. - [/data/graph.json](/data/graph.json): The whole site as a graph. Nodes are permissions, roles, attack techniques and objectives, entry vectors, incidents, escalations and checklist items (ids like permission:contents:write); edges say which role includes which permission, which permissions enable each technique, which incidents abused them, which escalation each permission starts and what it gains, and which checklist items mitigate each technique. - [/data/permission-model.json](/data/permission-model.json): How the vocabularies fit together. Classic scopes, fine-grained/App permissions, roles, keys and settings; every way access can be granted (25 mechanisms); and a crosswalk of 16 capabilities across classic scope, fine-grained/App permission, GITHUB_TOKEN permission and role. - [/data/landscape.json](/data/landscape.json): The threat landscape, edition 2026-Q4 (reviewed 2026-10-11). Every incident with its OWASP Top 10 CI/CD risks, NIST SP 800-204D sections, plane (control, data, both, platform), first and last seen dates, status and scale; the current trends with the incidents and checklist items behind each; where the frameworks are silent; and the derived flow from way in to objective, the OWASP heatmap by year and the controls that break the most incidents of the last 12 months. Mappings are ghtier's own reading. - [/data/scenarios.json](/data/scenarios.json): Real-world incident write-ups (31 scenarios) tagged by plane, with narrative, permissionsAbused, and sources. - [/data/checklist.json](/data/checklist.json): The hardening checklist, grouped by category. Each item has `meta` (the OWASP Top 10 CI/CD risks it addresses, the lowest GitHub plan it works on and any paid add-on, and when it was last checked against GitHub's docs), `detect` (audit log events to alert on when the control is undone), an effort tier, a one-line "why", fix steps, prerequisites, a docs link, and for 23 of 47 items a read-only `check` (gh api calls + a jq rule) for testing a real org. Plus the optional Secret Protection and Code Security items (formerly GHAS), each tagged with the license it needs. - [/data/assessment.schema.json](/data/assessment.schema.json): The format of an assessment file (results of running those checks), which /checklist can import. - [/data/state-of-github-security.json](/data/state-of-github-security.json): Secret-sprawl, non-human-identity-ratio, and breach-cost stats behind the state-of-security report. - [/data/tooling.json](/data/tooling.json): 18 open-source tools for GitHub, CI and supply-chain security in 9 categories. Each has how it works, what it catches, run/CI snippets, what leaves the machine, limits, an editorial rating (1-5), and GitHub stars, license, latest release and OpenSSF Scorecard score as of 2026-10-10. Also a reference PR security pipeline. ## Pages - [/permission-model](/permission-model): the vocabularies, the grant mechanisms table and the capability crosswalk. - [/tier/permissions](/tier/permissions): every permission with its tier and reason; one page per permission at /tier/permissions/{id}. - [/tier/roles](/tier/roles): every built-in role with its inherited tier; one page per role at /tier/roles/{id}. - [/tier/tokens](/tier/tokens): every classic scope with its tier, and the token types; one page per scope at /tier/tokens/{scope}. - [/tier/keys-policies](/tier/keys-policies): keys, policies, grants and agents; one page each at /tier/keys-policies/{id}. - [/changes](/changes): what GitHub added, removed or changed in its permissions, role tables and scopes, found by ghtier's weekly refresh. Also as an Atom feed: [/changes.xml](/changes.xml). - [/landscape](/landscape): the threat landscape: trends, how attacks flow, OWASP CI/CD risks over time, framework gaps and the controls that break the most current campaigns. Crosswalks at /landscape/frameworks/owasp-cicd and /landscape/frameworks/nist-800-204d, one page per item (e.g. /landscape/frameworks/owasp-cicd/cicd-sec-4). - [/scenarios/all](/scenarios/all): the incident timeline. - [/checklist](/checklist): the interactive hardening checklist. - [/state-of-github-security](/state-of-github-security): the long-form report. - [/best-practices](/best-practices): curated external hardening guidance. - [/tooling](/tooling): open-source security tooling by category, sortable by stars and rating; one page per tool at /tooling/{id}. - [/tier-calculator](/tier-calculator): build a token, App, workflow permissions block, classic scope set, custom repository or organization role, or any permission set and see its tier. You can also paste a workflow permissions block, an App manifest or an X-OAuth-Scopes header to tier it, and pin one selection to compare with another. The selection is in the URL, e.g. /tier-calculator?mode=token&p=contents:write,pull_requests:write or /tier-calculator?mode=custom-repo&base=repo-read&c=r-manage-webhooks. - [/strange-findings](/strange-findings): edge cases where GitHub access works differently from what people expect, each with a GitHub source. Link one with /strange-findings#finding-{id}. - [/updates](/updates): what changed on ghtier itself, newest first, by kind and page. - [/ai](/ai): how agents can use this site and assess a real org. ## Assessing your own organization The checks in checklist.json are meant to be run by you or your agent, with your own `gh` login. ghtier never sees your data. The reference runner is [/skills/ghtier-assess/assess.mjs](/skills/ghtier-assess/assess.mjs) (read it before running it; it has no dependencies and only sends GET requests). It writes ghtier-assessment-.json, which can be imported on /checklist. The matching agent skill is [/skills/ghtier-assess/SKILL.md](/skills/ghtier-assess/SKILL.md). The runner also fills [/skills/ghtier-assess/report](/skills/ghtier-assess/report) (report.html) into a printable ghtier-report-.html. It also lists who holds Tier 0 and Tier 1 in the organization (owners, organization role holders, the base permission, installed GitHub Apps, outside collaborators, self-hosted runners, deploy keys with write access, ruleset bypass actors, organization webhooks, organization secrets visible to all repositories, open runner groups and SSO-authorized credentials), tiered with permissions.json, roles.json, scopes.json and keys-policies.json. [/skills/ghtier-assess/SHA256SUMS](/skills/ghtier-assess/SHA256SUMS) lists the SHA-256 of the runner, the template and those data files; `--pin SHA256SUMS` makes the runner refuse anything else. jq rules run with an empty environment, and check calls must stay inside the organization. Rules for each check: - `calls` are REST paths for `gh api --paginate`; fill `{org}`, and for repo scope `{owner}`, `{repo}`, `{default_branch}`. Merge pages. A 404 becomes null; any other error means the result is "error". - `jq` gets the call results as an array (.[0], .[1], ...) and prints true (pass), false (fail), a number 0-100 (partial), or null (a person has to decide). Repo scope also gets the repo object as `$repo`, runs per non-archived repo, and the item's value is the share of repos that pass. - Items without a check need a person to answer. ## Optional - [llms-full.txt](/llms-full.txt): every permission, role, scope, key and policy, every incident, attack path and the full checklist inlined as plain text, for agents that want everything in one file instead of fetching each JSON export.