GitHub を使っているのは、もうエンジニアだけではない。マーケがサイトのコードを置き、コーポレートが業務自動化のスクリプトを置き、最近は Claude Code の作業場所にもなっている。
その結果、部署ごとに Organization が乱立する。ある IPO 準備中のスタートアップで、この状態を1つの Org にまとめた。作業前に一番気にしていたのは「リポジトリを移管すると secret が消えて、再登録が必要になる」という話だった。実測したら逆だった。secret は値ごと引き継がれた。そして、それこそが監査上の論点だった。
この記事でわかること
- ▶ Team プランと Enterprise プランを、どう使い分けたか
- ▶ 設定の緩い Org を受け皿にするとき、締める順序
- ▶ リポジトリ Transfer で何が残り、何が落ちるか(実測)
- ▶ 移管後に本当にやるべき「権限の棚卸し」
▼背景:部署ごとに GitHub がバラバラだった
統合前の状態はこうだった。
| 部署 | GitHub の状態 |
|---|---|
| プロダクト | Enterprise プランの Org |
| コーポレート | Team プランの Org(メンバー2名) |
| マーケ | Free プランの Org |
| CX・セールス | 個人の無料アカウント、または実態不明 |
IPO 準備の監査を考えると、この状態は困る。誰がどのリポジトリにアクセスできるのか、退職者のアクセスが残っていないか、会社として説明できない。目的は、アクセスを team 経由に統一して、オフボーディングの漏れをなくすことだ。
スコープは最初に絞った。「リポジトリを持ってくる」+「命名規則」まで。リポジトリの中身の見直しは別の段階にする。ここを広げると、1か月では終わらない。
▼プランの判断:全部を Enterprise に寄せない
最初に考えたのは「プロダクトの Enterprise に全部入れる」案だ。だが、同じ Org の中でプランは混在できない。全員を Enterprise にするとコストが跳ねる。
結論はこうした。
- ▶ プロダクトは Enterprise のまま分離して維持
- ▶ マーケ・コーポレート・セールスは、全社用の Team プランの Org に集約
Team プランの弱点は2つある。1つは SAML SSO と SCIM が使えないこと(Enterprise 限定)。IdP から自動でアカウントを止められない。そこで、退職時に GitHub API でメンバーを外す処理を、IdP の退職フローに組み込むことで補う。もう1つは階層を持てないことだ。これは後述の命名規則で代替した。
シートの数え方に注意
Team プランでは、読み取り専用でも team に所属した時点で1シート消費する。「見るだけの人」も数に入れて見積もる。今回は今後の増員も見込んで、十数シートで購入した。
▼受け皿の Org を「先に締めてから」移管する
受け皿にしたコーポレートの Org は、設定が緩かった。このままリポジトリを集めると、緩い設定のまま全社のコードが集まることになる。そこで、移管の前に締める。順序が大事だ。
STEP1 2FA を必須にする(事前に全員の 2FA 設定状況と保留中の招待を確認。締め出しゼロを確かめてから)
STEP2 Base permissions を none にする(Org に入っただけでは何も見えない状態)
STEP3 メンバーのリポジトリ作成を不可、private fork も不可にする
STEP4 team を作る(名簿用の全員 team +部署 team)
STEP5 サードパーティアクセスを制限する
STEP6 メンバーを招待して、リポジトリを Transfer する
STEP1 の 2FA は特に順序を間違えやすい。「招待 → 全員が設定済みか確認 → 強制」の順だ。設定していない人がいる状態で強制すると、その人は Org から外れる。2FA が既定では必須ではないこと、SSO の強制は Enterprise だけであることも、関係者に先に説明しておいた。
▼Transfer で何が残り、何が落ちるか(実測)
移管の前に、検証用のリポジトリで Transfer の挙動を確かめた。2026年8月の実測だ。
| 項目 | 結果 |
|---|---|
| コミット履歴・PR 番号・マージ履歴 | 保持 |
| 旧 URL からのリダイレクト | 有効 |
| repository secret(値) | 引き継がれる(「再登録が必要」という通説は誤り) |
| Actions のワークフロー | 残る。secret の参照も成功 |
| 個別に付与した collaborator | 移管先の Org のメンバーなら直接付与が残る。メンバーでない人は落ちる |
本番の移管でも、移管後に secret の一致とワークフローの実行成功を確認した。業務は止まらなかった。
▼だから、移管後の権限棚卸しが本体になる
secret が引き継がれるのは、作業としては楽だ。だが監査の目で見ると話が変わる。旧 Org で誰かが登録した資格情報が、旧権限のまま新しい Org に残るということだからだ。
「移管したら再登録が必要」と思っていれば、その再登録のついでに資格情報を見直す機会があった。引き継がれるなら、その機会は自分で作るしかない。今回は移管後に次を確認した。
- ▶ 全リポジトリで、個別 collaborator の付与がゼロになっているか(アクセスは team 経由に統一)
- ▶ どのリポジトリに、どの secret があり、誰が管理しているか(secret の台帳を作る)
- ▶ 承認済みのサードパーティアプリの記録
棚卸しスクリプトのハマりどころ
- ▶ Organization Owner は
affiliation=directの一覧に出ない。逆に言えば、一覧に出てくるものは本物の個別付与だ - ▶
gh apiのエラーレスポンスにjq 'length'をかけると、エラー JSON のキー数(3)が返ってくる。「3人に付与されている」と誤集計しないよう、生のレスポンスを検証する - ▶ ワークフローの YAML で
${VAR:+yes}と書くと、GitHub が${{ }}と誤認して “Invalid workflow file” になる。if [ -n "$VAR" ]で回避する - ▶ Free プランの Org では、private リポジトリから Organization secret を参照できない(Team 以上が必要)
▼階層がない Team プランは、命名規則で整理する
コーポレートからは「Claude Code 用のリポジトリと、通常のバージョン管理用を分けたい」という要望があった。だが Team プランでは、Org の直下にリポジトリが並ぶだけで、フォルダのような階層は作れない。
そこで、部署の頭文字の命名規則(mkt-・corp-・sales-)+ team ごとの権限で代替した。部署の team は、自分の部署のリポジトリだけ見られる・触れる状態にする。
注意点が1つ。外部サービスと連携しているリポジトリは、名前を変えると連携が切れる可能性がある。今回は、外部連携があるリポジトリは corp- の名前でコーポレートの team に置き、リネームは連携を構築したベンダーに依頼してから確認した。
▼API で拾えないもの:個人アカウントに残る会社のコード
最後に残るのが、社員の個人アカウント上に会社のコードが置かれていないかだ。これは Org の外にあるので、API では列挙できない。ヒアリングするしかない。
IPO の監査では、知的財産の帰属が論点になりうる。「会社のコードは会社の Org にある」と言える状態にするには、ツールの設定だけでなく、人に聞く工程が要る。
▼まとめ
- ▶ 全部を Enterprise に寄せない。Team に集約し、SCIM がない分は退職フローで API を叩いて補う
- ▶ 受け皿の Org は、移管の前に締める。2FA は「招待 → 確認 → 強制」
- ▶ Transfer で secret は値ごと引き継がれる。だから移管後の権限棚卸しが監査上の本体
- ▶ 階層は命名規則+team で代替。外部連携のあるリポジトリのリネームは慎重に
- ▶ 個人アカウントに残るコードは API で拾えない。ヒアリングが要る
📅 30分無料相談、受け付けています
「GitHub が部署ごとにバラバラで、IPO の監査で説明できる状態になっていない」——そういった段階からお気軽にどうぞ。権限設計から移管、退職フローへの組み込みまで対応しています。
📅 30分無料相談を予約する →