外部委託リポジトリのコードセキュリティ:シークレット検知とソースコード流出防止CI/CDガードレール
はじめに
こんにちは、NKKTech Global 技術チームです。
受託開発やクロスボーダー開発において、「外部パートナーを信頼すること」と「セキュリティの防御壁を張ること」は決して矛盾しません。どれほどスキルの高いエンジニアであっても、ローカルで検証用に使った .env やハードコードされたAPIキーを誤って git push してしまうヒューマンエラーは起こり得ます。
特に外部委託プロジェクトでは、以下のような事態が企業の存続を揺るがす重大インシデントに直結します。
- AWSやOpenAIのAPIキーがコミットされ、数時間で数十万〜数百万円規模の不正利用・請求が発生
- データベースの接続文字列(平文パスワード含む)がコミットログに残存
- 開発者個人の管理外端末への不正なリポジトリクローンやフォークによる知的財産の流出
本記事では、「個人の注意深さ」に頼らず、機械的にシークレットを検知・ブロックし、コード流出を防止する多層防御CI/CDガードレールの設計と実装を解説します。
1. シークレット防御の3層アーキテクチャ
シークレット漏洩対策は、単一のツールではなく**「多層防御(Defense in Depth)」**で網を張るのが鉄則です。
2. 【第1層】ローカルでの水際阻止:pre-commit と Gitleaks
開発者がコミットボタンを押した瞬間にローカル端末側で検出・遮断するのが最も安全です。一度リモートにPushされてしまうと、コミットを取り消してもリポジトリの過去履歴(Git DAG)に残存してしまうためです。
設定手順
リポジトリ直下に .pre-commit-config.yaml を配置し、プロジェクト参加時のセットアップコマンド(pre-commit install)を義務付けます。
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.2
hooks:
- id: gitleaks
name: Detect Hardcoded Secrets (Gitleaks)
entry: gitleaks protect --verbose --redact --staged
language: golang
企業独自シークレット用カスタム設定 (.gitleaks.toml)
AWSやGitHubの標準的なトークン形式に加え、自社独自のAPIキーやJWTプレフィックスを検知できるようルールを拡張します。
# .gitleaks.toml
title = "Enterprise Secret Detection Rules"
[[rules]]
id = "nkk-internal-api-token"
description = "社内専用APIトークンの誤コミット検知"
regex = '''(?i)(nkk_sec_[a-zA-Z0-9]{32,64})'''
secretGroup = 1
severity = "CRITICAL"
[allowlist]
description = "テスト用モック文字列の除外"
regexes = [
'''nkk_sec_dummy_test_token_sample''',
'''EXAMPLE_KEY'''
]
3. 【第2層】CI/CDパイプラインによるPRマージ遮断
ローカルフックは開発者が git commit --no-verify を使えば迂回できてしまいます。そのため、リモートのCI/CDパイプラインを絶対的なゲートキーパーとして配置します。
GitHub Actions ワークフロー (.github/workflows/secret-scan.yml)
name: Security Secret Scan Gate
on:
pull_request:
branches: [ main, develop ]
push:
branches: [ main ]
jobs:
gitleaks-scan:
name: Gitleaks Pull Request Scan
runs-on: ubuntu-latest
steps:
- name: Checkout Code with Full History
uses: actions/checkout@v4
with:
# 差分だけでなくPR内のコミット履歴全体をスキャン
fetch-depth: 0
- name: Run Gitleaks Scanner
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_ENABLE_SUMMARY: true
- name: Post Failure Notification
if: failure()
run: |
echo "::error::重大なセキュリティ違反: コミット履歴内に平文の認証情報またはAPIキーが検知されました。"
echo "::error::該当コミットを取り消し、クレデンシャルを直ちに無効化(Revoke)してください。"
exit 1
重要:
fetch-depth: 0を必ず指定してください。浅いクローン(shallow clone)では、PR内で追加された過去のコミットが検証対象から外れてしまい、シークレットを見逃す原因になります。
4. 【第3層】ソースコード流出を防ぐリポジトリガバナンス
シークレット保護に加え、外部委託先からの「コード持ち出し」を防ぐため、GitHub Organization単位で以下の設定を適用します。
① フォーク(Fork)の完全無効化
外部開発者が個人アカウントへリポジトリをフォークすることを許可してはいけません。
-
設定:
Organization Settings>Member privileges>Repository forkingを Disabled に設定。
② IPアクセス制限(IP Allowlisting)
許可された社内VPNや、委託先オフィスの固定グローバルIPアドレスからのみGitHubへのアクセス・クローンを許可します。
- これにより、個人の私物PCや外部のカフェ等からの無断クローンをネットワークレベルで物理的に遮断します。
③ 長期有効クレデンシャルの撲滅(GitHub OIDC)
AWSやGCPと連携する際、AWS_ACCESS_KEY_ID などの静的キーをGitHub Secretsに保存することを全面的に禁止します。
- OIDC (OpenID Connect) を採用し、CI/CD実行時に数分間だけ有効な一時トークン(AssumeRole)を動的発行します。万が一リポジトリが侵害されても、クラウド側への恒久的な侵入経路になりません。
5. 万が一シークレットが混入した際の緊急対応Runbook
ガードレール導入前に誤ってコミットされてしまった場合、直ちに以下の順序で対応します。
-
【最優先】キーの即時失効とローテーション(Revoke & Rotate):
Git履歴の修正よりも先に、該当のAPIキーやパスワードをクラウド側で即座に失効させます。「コミットを打ち消したから安全」ではありません。 -
Git履歴の完全抹消 (
git-filter-repo):
git rmやgit revertでは過去のコミットログに残るため、専用ツールを用いて履歴ツリーから痕跡を消去します。pip install git-filter-repo git-filter-repo --replace-text <(echo "AKIAEXAMPLEKEY==>REDACTED") git push origin --force --all -
監査ログの確認:
漏洩したキーが使われていた期間のCloudTrailやAPIアクセスログを確認し、不正アクセスの有無を特定します。
まとめ:仕組みが「安心できるパートナーシップ」をつくる
外部委託におけるセキュリティ管理の本質は、ベンダーへの締め付けではなく、**「開発者が誤っても重大事故にならないフェイルセーフな安全柵を敷くこと」**です。
- **ローカル(pre-commit)**で開発者のミスを即時フィードバック
- **CI/CD(GitHub Actions)**でマージを機械的にブロック
- **組織ポリシー(IP制限・Fork禁止・OIDC)**で外部流出を遮断
この多層ガードレールを敷くことで、発注側は安心してコア業務を任せることができ、受託側もリスクを恐れずに高いパフォーマンスを発揮できます。
お問い合わせ先
外部委託・オフショア開発におけるセキュリティ監査、セキュアなDevOpsパイプラインの設計、GitHub Enterpriseガバナンスの導入支援に関するご相談は、下記よりお気軽にお問い合わせください。
- Webサイト: https://nkktech.com/
- メール: contact@nkk.com.vn
- LinkedIn: https://www.linkedin.com/company/nkktech
著者:NKKTech Global 技術チーム
私たちは、強固なセキュリティガバナンスとアジャイル開発を融合させ、安全で迅速なグローバルエンジニアリングを提供します。
