GitHub の Org 統合で repository secret は引き継がれた——IPO 準備企業の Org 一本化【実録】

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 で拾えない。ヒアリングが要る
📄 退職者・業務委託のアカウントを漏らさない棚卸しの全体設計はこちらの記事で解説しています。
📄 スタートアップで最初にそろえる IT ツールはこちらの記事でまとめています。

📅 30分無料相談、受け付けています

「GitHub が部署ごとにバラバラで、IPO の監査で説明できる状態になっていない」——そういった段階からお気軽にどうぞ。権限設計から移管、退職フローへの組み込みまで対応しています。

📅 30分無料相談を予約する →