マイクロソフト公式OSS「ghqr」でGitHub設定をベストプラクティス診断してみた
GitHubの運用は大変です。
多くの組織において、だれかが業務の片手間で面倒を見ているのではないでしょうか?日々要求レベルが高まるセキュリティ対応の追従も大変です。
そんな運用チームに朗報です。
マイクロソフトがGitHubの設定のベストプラクティス診断を行う ghqr(GitHub Quick Review) というGo製のCLIツールをOSS公開しました。
Enterprise / Organization / Repository といった粒度で、設定をベストプラクティスに照らして診断し、 Excel / Markdown / JSON の 3 形式でレポートを出力します。 リポジトリの About には 「Evaluate your enterprise and organizations with GitHub best practices」 と記載されています。
実行はコマンド一発です
$ ghqr scan -e ENTERPRISE-NAME# エンタープライズアカウント全体をスキャン$ ghqr scan -o ORG-NAME# 組織全体をスキャン
2要素認証が有効化されていないOrganizationも簡単に検知できます。
CSPMのGitHub版というとイメージしやすいかもしれません(少し盛りすぎです)。
リリースされたばかりで機能はまだ揃いきっていませんが、 CLIやMCP連携を試してみたので、どんなツールなのか、軽く紹介します。
検証環境
- ghqr : v.0.2.1
- 検査対象 : GitHub Organization
対応しているGitHub
GitHub は色々なサービス形態があります。
ghqr は github.com と ghe.com でホストされる以下のような広義のクラウド版に対応してます。
- github.com の Enterprise/Organization/Repository
- ghe.com でホストされるデータレジデンシー版GitHub Enterprise Cloud
次のイシューにあるように、現時点ではGitHub Enterprise Server(GHES=オンプレ版)はサポートしていません。
インストール
アセットからインストール
main ブランチから
mainブランチから直接インストールする場合は、以下のコマンドを実行しましょう
Linux/macOS
bash -c "$(curl -fsSL https://raw.githubusercontent.com/microsoft/ghqr/main/scripts/install.sh)"
Windows
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/microsoft/ghqr/main/scripts/install.ps1'))
既に list-recommendations でチェック項目を眺めました。残りの 2 つを順に見ていきます。
サブコマンドは3つだけ
ghqr CLI のサブコマンドは 3 つだけです。
ghqr list-recommendationsレコメンデーション一覧を出力ghqr scanスキャンを実施ghqr mcpMCPサーバとして起動
ghqr list-recommendations : チェックリスト項目一覧
ghqr は設定がベストプラクティスに沿っているかどうかチェックします。
このチェックリスト一覧は ghqr list-recommendations コマンドで確認できます。
$ ghqr -v
ghqr version v.0.2.1
$ ghqr list-recommendations
ID SCOPE CATEGORY SEVERITY TITLE
────────────────── ────────────── ────────────────────── ────────── ─────────────────────────────────────────────────────
ent-alert-001 enterprise dependencies critical Critical Dependabot alerts open across enterprise
ent-alert-002 enterprise dependencies high High-severity Dependabot alerts open across enterprise
ent-alert-003 enterprise security high Code scanning alerts open across enterprise
ent-alert-004 enterprise security critical Secret scanning alerts open across enterprise
ent-ghas-001 enterprise security high GitHub Advanced Security not enabled at enterprise level
ent-ghas-002 enterprise security high Secret scanning not enabled as enterprise default
ent-ghas-003 enterprise security high Secret scanning push protection not enabled as enterprise default
ent-ghas-004 enterprise dependencies high Dependabot alerts not enabled as enterprise default
ent-ghas-005 enterprise dependencies medium Dependabot security updates not enabled as enterprise default
ent-ghas-006 enterprise dependencies medium Dependency graph not enabled as enterprise default
ent-ghas-007 enterprise security low Secret scanning for non-provider patterns not enabled as enterprise default
ent-log-001 enterprise security critical Suspicious audit log events detected
ent-log-002 enterprise security high Audit log streaming configuration cannot be verified
org-act-001 organization actions high Default GITHUB_TOKEN permission is write
org-act-002 organization actions high GitHub Actions allows all third-party actions
org-act-003 organization actions low Actions restricted to local repositories only
org-alert-001 organization dependencies critical Critical Dependabot alerts open across organization
org-alert-002 organization dependencies high High-severity Dependabot alerts open across organization
org-alert-003 organization dependencies medium Open Dependabot alerts across organization
org-alert-004 organization security high Code scanning alerts open across organization
org-alert-005 organization security critical Secret scanning alerts open across organization
org-cop-001 organization copilot_cost medium Copilot seats assigned to all organization members
org-cop-002 organization copilot_security high Copilot allowed to suggest code matching public repositories
org-cop-003 organization copilot_cost medium High percentage of inactive Copilot seats
org-def-001 organization dependencies high Dependabot alerts not enabled by default for new repositories
org-def-002 organization dependencies medium Dependabot security updates not enabled by default for new repositories
org-def-003 organization dependencies medium Dependency graph not enabled by default for new repositories
org-def-004 organization security high Secret scanning not enabled by default for new repositories
org-def-005 organization security high Secret scanning push protection not enabled by default for new repositories
org-def-006 organization security medium GitHub Advanced Security not enabled by default for new repositories
org-sec-001 organization security high Two-factor authentication not required
org-sec-002 organization security medium Web commit signoff not required
org-sec-003 organization access_control high Default repository permission set to admin
org-sec-004 organization access_control medium Members can create public repositories
org-sec-005 organization access_control medium No security manager team assigned
org-sec-006 organization security info EMU enabled: two-factor authentication is controlled by your identity provider
repo-acc-001 repository access_control high Excessive admin collaborators
repo-acc-002 repository access_control medium Direct collaborators instead of teams
repo-acc-003 repository security high Deploy keys with write access
repo-acc-004 repository security medium Unverified deploy keys
repo-acc-005 repository security medium Deploy keys present — consider GitHub Apps or OIDC
repo-bp-001 repository branch_protection critical No branch protection configured on default branch
repo-bp-002 repository branch_protection critical No approving reviews required before merge
repo-bp-003 repository branch_protection medium Only 1 approving review required
repo-bp-004 repository branch_protection high Stale reviews not dismissed on new commits
repo-bp-005 repository branch_protection medium Code owner review not required
repo-bp-006 repository branch_protection critical Pull request reviews not configured
repo-bp-007 repository branch_protection high Strict status checks not enabled
repo-bp-008 repository branch_protection high No specific status checks required
repo-bp-009 repository branch_protection high No required status checks configured
repo-bp-010 repository branch_protection critical Force pushes allowed on protected branch
repo-bp-011 repository branch_protection high Branch deletion allowed on protected branch
repo-bp-012 repository branch_protection medium Signed commits not required
repo-bp-013 repository branch_protection low Linear history not required
repo-bp-014 repository branch_protection info Branch protected by repository rulesets (not legacy branch protection)
repo-comm-001 repository community info GitHub Discussions not enabled
repo-feat-001 repository features low Issues and Discussions both disabled
repo-feat-002 repository maintenance low Auto-delete branches on merge not enabled
repo-meta-001 repository community medium Repository has no description
repo-meta-002 repository community low Repository has no topics
repo-meta-003 repository maintenance low Repository appears dormant but is not archived
repo-sec-001 repository security high Dependabot alerts not enabled
repo-sec-002 repository security critical Critical Dependabot alerts open
repo-sec-003 repository security high High-severity Dependabot alerts open
repo-sec-004 repository security low No SECURITY.md file found
repo-sec-005 repository access_control medium No CODEOWNERS file found
repo-sec-006 repository security medium Dependabot alerts enabled but no dependabot.yml found
repo-sec-007 repository security high Dependabot not configured
repo-sec-008 repository security high Code scanning (CodeQL) not configured
repo-sec-009 repository security info No custom CodeQL configuration file
70 recommendation(s) shown (total in registry: 70)
Organizationレベルで high を列挙します。
ghqr list-recommendations --scope organization --severity high
ID SCOPE CATEGORY SEVERITY TITLE
────────────────── ────────────── ────────────────────── ────────── ─────────────────────────────────────────────────────
org-act-001 organization actions high Default GITHUB_TOKEN permission is write
org-act-002 organization actions high GitHub Actions allows all third-party actions
org-alert-002 organization dependencies high High-severity Dependabot alerts open across organization
org-alert-004 organization security high Code scanning alerts open across organization
org-cop-002 organization copilot_security high Copilot allowed to suggest code matching public repositories
org-def-001 organization dependencies high Dependabot alerts not enabled by default for new repositories
org-def-004 organization security high Secret scanning not enabled by default for new repositories
org-def-005 organization security high Secret scanning push protection not enabled by default for new repositories
org-sec-001 organization security high Two-factor authentication not required
org-sec-003 organization access_control high Default repository permission set to admin
10 recommendation(s) shown (total in registry: 70)
以下のようなあるあるなコントロールが用意されていますね。
- 2FA が組織レベルで必須化されていない
GITHUB_TOKENのデフォルト権限が write になっている- リポジトリのデフォルト権限が admin になっている
ghqr scan : スキャンを実施
ghqr scan がメインとなるスキャンコマンドです。
引数で対象を指定します。
ghqr scan: 認証ユーザが所属する広いスコープghqr scan -e my-ent: 特定の Enterprise 配下ghqr scan -o my-org: 特定の Organization 配下ghqr scan -r owner/repo: 特定のリポジトリ
Organizationをスキャンしてみる
このようなツールが気になる人は、Organizationを管理している人が多いと思います。
PAT(Personal Access Token)を渡し、スキャン対象のOrganizationを指定するだけでスキャン完了です。
export GH_TOKEN=github_pat_xxxxxxxxxxxx
ghqr scan -o my-org
実行結果です
$ ghqr scan -o my-org
2026-04-30T22:06:59+09:00 INF Scan started stages=9
2026-04-30T22:06:59+09:00 INF Initializing scan...
2026-04-30T22:06:59+09:00 INF Authenticated to GitHub user=example
2026-04-30T22:06:59+09:00 INF Skipping enterprise scan - no enterprises specified (use --enterprise or -e flag)
2026-04-30T22:06:59+09:00 INF Starting organization scan count=1
2026-04-30T22:06:59+09:00 INF Scanning organization organization=my-org
2026-04-30T22:06:59+09:00 INF Starting organization scan organization=my-org
2026-04-30T22:07:02+09:00 INF Organization scan completed organization=my-org
2026-04-30T22:07:02+09:00 INF Organization scan completed successfully organization=my-org
2026-04-30T22:07:02+09:00 INF Organization scan completed
2026-04-30T22:07:02+09:00 INF Fetching organization repository names via GraphQL org=my-org
2026-04-30T22:07:02+09:00 INF Scanning repositories in batches batch_size=5 count=4 org=my-org workers=5
2026-04-30T22:07:04+09:00 INF Enriching repositories with ruleset data via GraphQL (batched) chunks=1 org=my-org repos=3 workers=10
2026-04-30T22:07:05+09:00 INF Enriching repository current=1 repository=my-org/xx1 total=3
2026-04-30T22:07:05+09:00 INF Enriching repository current=2 repository=my-org/xx2 total=3
2026-04-30T22:07:05+09:00 INF Enriching repository current=3 repository=my-org/xx3 total=3
2026-04-30T22:07:05+09:00 INF Org repository scan complete org=my-org scanned=4
2026-04-30T22:07:05+09:00 INF Running best-practice evaluations...
2026-04-30T22:07:05+09:00 INF Evaluations completed
2026-04-30T22:07:05+09:00 INF Rendering reports... results=31
2026-04-30T22:07:05+09:00 INF JSON report written path=ghqr_20260430_220659.json
2026-04-30T22:07:05+09:00 INF Generating Excel report: ghqr_20260430_220659.xlsx
2026-04-30T22:07:05+09:00 INF Excel report written path=ghqr_20260430_220659.xlsx
2026-04-30T22:07:05+09:00 INF Markdown report written path=ghqr_20260430_220659.md
2026-04-30T22:07:05+09:00 INF Scan summary enterprises=0 organizations=1 output=ghqr_20260430_220659 repositories=4
2026-04-30T22:07:05+09:00 INF Scan completed in 6s
2026-04-30T22:07:05+09:00 INF Scan completed
完走すると同じ base name で 3 ファイルが落ちてきます。
$ ls -1
ghqr_20260430_220659.json
ghqr_20260430_220659.md
ghqr_20260430_220659.xlsx
並列処理が入っており、1000を超えるリポジトリがある場合でも、数分でスキャンが完了しました。
JSONレポートの構成
JSON形式はスキャン結果を処理したい場合に便利です。
jq で集計したり、前回との差分をチェックしたり、システム連携するのも容易です。
冒頭を抜粋します。
{
"generated_at": "2026-04-30T13:07:05Z",
"organizations": {
"your-org": {
"copilot": {
"active_this_cycle": 5,
"billing_enabled": true,
"inactive_this_cycle": 0,
"public_code_suggestions": "block",
"seat_management_setting": "assign_selected",
"total_seats": 5
},
"copilot_evaluation": {
"recommendations": [
{
"category": "copilot_cost",
"issue": "Copilot seat utilization: 5 active, 0 inactive out of 5 total",
"learn_more": "https://docs.github.com/en/copilot/managing-copilot/managing-github-copilot-in-your-organization/reviewing-activity-related-to-github-copilot-in-your-organization/reviewing-your-organization-s-copilot-seat-assignments",
"recommendation": "Monitor seat utilization regularly for cost efficiency",
"severity": "info"
}
],
"summary": {
"high_severity": 0,
"info": 1,
"low_severity": 0,
"medium_severity": 0,
"total_issues": 1
}
},
...
ランニングコストもみてくれるのはありがたいですね。シート管理は地味に手間がかかります。
Markdownレポートの構成
Markdownはスキャン結果をテキストで確認したい場合に便利です。
リポジトリ単位でスキャンした結果をイシューに貼り付けるのも有りでしょう。
冒頭を抜粋します
# GitHub Assessment Report — your-org
**Scope:** Organization
**Generated:** April 30, 2026
**Scan Coverage:** 0 enterprises / 1 organizations / 4 repositories
---
## Executive Summary
> The overall security and best practices posture of this environment **requires immediate attention**. A total of **33 findings** were identified across 0 enterprises, 1 organizations, and 4 repositories. Of these, **4 are critical** and **3 are high severity**, requiring prompt remediation. An additional **11 medium-severity** findings should be addressed within 60 days. The most prevalent area of concern is **Community Health & Documentation** with 8 findings. The top improvement opportunity is to enable branch protection and Dependabot alerts across all repositories.
### Posture Scorecard
| Entity | Type | Critical | High | Medium | Low | Info |
|--------|------|----------|------|--------|-----|------|
| your-org | org | 0 | 1 | 3 | 0 | 0 |
| your-org/xx1 | repo | 1 | 1 | 2 | 4 | 0 |
| your-org/xx2 | repo | 1 | 0 | 2 | 3 | 0 |
| your-org/xx3 | repo | 1 | 0 | 2 | 4 | 0 |
| your-org/xx4 | repo | 1 | 1 | 2 | 4 | 0 |
### Overall Risk Distribution
| Severity | Count | % of Total |
|----------|-------|------------|
| 🔴 Critical | 4 | 12% |
| 🟠 High | 3 | 9% |
| 🟡 Medium | 11 | 33% |
| 🟢 Low | 15 | 45% |
| ℹ️ Info | 0 | 0% |
...
Excelレポートの構成
Excelファイルはレポートを俯瞰したい場合に便利です。
例えば、大量のリポジトリに対して Critical が多いリポジトリや Critical なFindingでフィルターするなら、Excelでやるのが素直です。
Excelは以下のシートに分かれています
- Organizations
- Repositories
- Branch Protection
- Findings
Repositoriesシートの冒頭を抜粋します

ghqr mcp : MCPサーバとして起動してClaude Codeから探索的に調べる
ghqr は MCP サーバモードも備えています。
--mode http で起動するとデフォルトで /sse (イベントストリーム) と /message (POST) の 2 エンドポイントを公開します。
export GH_TOKEN=github_pat_xxxxxxxxxxxx
ghqr mcp --mode http --addr :8080
# Starting MCP server in HTTP/SSE mode on :8080
Claude なら以下のようにしてMCPサーバーを追加します。
claude mcp add ghqr --transport sse http://localhost:8080/sse
MCPの設定ファイルを直接編集することも可能です。
{
"mcpServers": {
"ghqr": {
"type": "sse",
"url": "http://localhost:8080/sse",
"headers": {},
"tools": ["*"]
}
}
}
Claude Codeから呼び出してみましょう。
> ghqr でgithub org(your-org) を scan して
...
⏺ スキャン完了しました。
ghqr スキャン結果: your-org
成果物
- /Users/jsmith/ghqr/ghqr_20260430_204115.json
(MCP 経由のスキャンでは JSON のみ生成。.md/.xlsx は CLI 直叩き時のみ出力される模様)
Org レベル所見
セキュリティ
- 2FA 必須化 OFF (org-sec-001 high)
- Web commit signoff 未設定 (org-sec-002 medium)
- メンバーが Public リポジトリを作成可能 (org-sec-004 medium)
- Security Manager チーム未割当 (org-sec-005 medium)
...
横断的な傾向
- 全リポジトリで default branch の Branch Protection 未設定 (critical)
- CODEOWNERS / SECURITY.md がいずれも未配置
- description / topics 未設定が多くガバナンス上の見通しが悪い
詳細は JSON の evaluation.recommendations を参照してください。
> critial と high がある xx1 はどうすれば良い?
⏺ xx1 の問題を整理すると最終 push が 2025-02-04 で約 15 ヶ月放置 (repo-meta-003 dormant も同時検出)。「使うか / 使わないか」で対応が分岐します。
判断フロー
A. もう使わない場合 (推奨候補)
archive すれば read-only になり、Branch Protection も Dependabot も無関係になります。critical/high が一発で消えます。
...
問題のリポジトリをアーカイブ化して再スキャンします。
> リポジトリ xx1 をもう一回スキャンして
⏺ your-org/xx1 の再スキャン結果です。
成果物
- /Users/jsmith/ghqr/ghqr_20260430_204532.json
変化点
リポジトリは archived = true に変更済み (前回 false)。
残った Recommendation
┌──────────┬────────────────┬───────────────────────────────────┐
│ severity │ rule_id │ issue │
├──────────┼────────────────┼───────────────────────────────────┤
│ high │ repo-sec-001 │ Dependabot alerts not enabled │
├──────────┼────────────────┼───────────────────────────────────┤
│ info │ (rule_id なし) │ Repository is archived (情報通知) │
├──────────┼────────────────┼───────────────────────────────────┤
│ medium │ repo-meta-001 │ Repository has no description │
└──────────┴────────────────┴───────────────────────────────────┘
解釈
archive 化で前回検出されていた critical の repo-bp-001 (Branch Protection) は消えました。archive により書き込みが拒否されるため、保護ルールが事実上不要になったという判定です。
ただし repo-sec-001 (Dependabot alerts) と repo-meta-001 (description) は archived とは無関係に残ります。
実害観点
- archived = read-only 状態なので Dependabot を有効化しても新しい依存追加はもう発生せず、既存依存のアラート受信のみ意味を持つ。脆弱性監視を継続したい場合のみ ON にすべき。完全に塩漬け運用なら無視で問題なし。
- description は archive 後も付けられます。一覧での見通しのため gh repo edit your-org/xx1 --description "..." で追加可。
要約: ghqr の警告は実質「info ノイズ」レベルで、archive により実害のあるリスクは消えています。
探索的に調査する場合、MCPインターフェースは便利ですね。
最後に
マイクロソフト公式 OSS の ghqr で、 GitHub の設定をベストプラクティスに照らして一括チェックする方法を紹介しました。
- Enterprise/Organization/Repositoryの粒度で検査可能
- CLI 一発で xlsx / Markdown / JSON のレポートを生成
- コントロール単位で改善アクションまで提示
GitHubの運用は属人化しがちで継続的なセキュリティ対応もおざなりになりがちですが、ghqr を定期的に回すことで設定の棚卸しと是正の敷居が低くなることが期待されます。
そのような未来のためにも、チェック項目の拡大に期待したいですね(OSSなのでPR送り放題です)。









