gpc-security について
gpc-securityは、GPCユーザー向けのセキュリティスキルで、認証情報の保護、ローテーション、監査ログ、CI/CDの対策を扱います。キー漏えい時の対応、最小権限、機密情報のマスキングについても案内します。
主な機能
- 01認証情報の保存場所の説明
- 02サービスアカウントキーのローテーション手順
- 03JSON Lines監査ログの確認
- 04CI/CDでのシークレット管理の助言
- 05キー漏えい時の対応手順
- 06最小権限と機密情報のマスキング
活用シーン
- 01CI/CDでサービスアカウント認証情報を安全に設定
- 02サービスアカウントキーのローテーション
- 03GPCコマンドの監査記録を確認
- 04キー漏えい時の緊急対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yasserstudio/ gpc-skills --skill gpc-securityインストール後、Claude Code で/gpc-securityを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/evals.jsonreferences/credential-storage.mdkey-rotation.mdruntime-security.mdscripts/detect_gpc.mjs詳細
gpc-security
GPC の認証情報管理、監査ログ、セキュリティのベストプラクティスです。
使用する場面
- サービスアカウントのキーと認証情報を保護する
- 認証情報のローテーションを設定する
- コンプライアンス対応のために監査ログを確認する
- 漏えいしたサービスアカウントキーに対処する
- CI/CD パイプラインで GPC を保護する
- GPC が機密データを保存する場所を把握する
必要な入力
- GPC がインストールされ、認証済みであること —
gpc auth status - サービスアカウントのキーファイル — ローテーション手順で使用します
- CI/CD プラットフォームへのアクセス権 — シークレットを更新するために必要です
手順
0. 認証情報の保存場所
GPC は、プラットフォームに適した安全な場所に認証情報を保存します。
| データ | 場所 | セキュリティ |
|---|---|---|
| OAuth トークン | OS のキーチェーン(macOS/Linux/Windows) | OS による暗号化 |
| トークンキャッシュ | ~/.cache/gpc/tokens/ | ファイル権限(0600) |
| ユーザー設定 | ~/.config/gpc/config.json | ファイル権限 |
| プロジェクト設定 | .gpcrc.json | バージョン管理対象(シークレットを含めないでください!) |
| 監査ログ | ~/.config/gpc/audit.log | JSON Lines、追記専用 |
XDG の上書き設定: XDG_CONFIG_HOME、XDG_CACHE_HOME、XDG_DATA_HOME
Read: 詳細な保存アーキテクチャとセキュリティモデルについては、references/credential-storage.md を参照してください。
1. サービスアカウントキーのセキュリティ
キーを git にコミットしないでください
# .gitignore
*.json.key
*-sa.json
service-account*.json
play-store-key.json
CI では環境変数を使用してください
# GitHub Actions — key stored as secret
env:
GPC_SERVICE_ACCOUNT: ${{ secrets.PLAY_SA_KEY }}
以下にはキーを保存しないでください。
.gpcrc.json(バージョン管理対象)- Dockerfile または docker-compose ファイル
- git にコミットするシェルスクリプト
- CI 設定ファイル(プライベートに見える場合でも)
2. キーのローテーション
サービスアカウントキーは定期的にローテーションしてください(推奨:90 日ごと)。
# 1. Create new key in Google Cloud Console
# IAM & Admin → Service Accounts → Keys → Add Key
# 2. Test new key locally
gpc auth login --service-account /path/to/new-key.json
gpc doctor
# 3. Update CI secrets with new key
# GitHub: Settings → Secrets → PLAY_SA_KEY → Update
# GitLab: Settings → CI/CD → Variables → PLAY_SA_KEY → Update
# 4. Verify CI works with new key
# Trigger a test pipeline
# 5. Delete old key in Google Cloud Console
# IAM & Admin → Service Accounts → Keys → Delete old key
# 6. Clear local token cache
rm -rf ~/.cache/gpc/tokens/
Read: 自動ローテーションのパターンと複数環境での戦略については、references/key-rotation.md を参照してください。
3. 監査ログ
GPC はすべてのコマンドを ~/.config/gpc/audit.log に JSON Lines 形式で記録します。
# View recent audit entries
tail -20 ~/.config/gpc/audit.log | jq .
# Filter by command
cat ~/.config/gpc/audit.log | jq 'select(.command == "releases upload")'
# Filter by app
cat ~/.config/gpc/audit.log | jq 'select(.app == "com.example.app")'
# Filter failures
cat ~/.config/gpc/audit.log | jq 'select(.success == false)'
# Filter by date range
cat ~/.config/gpc/audit.log | jq 'select(.timestamp >= "2025-03-01")'
監査エントリの構造
{
"timestamp": "2025-03-09T14:30:00.000Z",
"command": "releases upload",
"app": "com.example.app",
"args": { "track": "beta", "file": "app-release.aab" },
"user": "[email protected]",
"success": true,
"durationMs": 12340
}
4. シークレットのマスキング
GPC は、すべての出力で機密データを自動的にマスキングします。
- サービスアカウントの JSON 内容はログに記録されません
- 詳細出力にアクセストークンは表示されません
- エラーメッセージに秘密鍵は含まれません
--json出力では認証情報フィールドがマスキングされます- Webhook ペイロードは Slack/Discord/カスタムエンドポイントへの送信前に
redactSensitive()でマスキングされます(v0.9.80+) - 認証エラーメッセージでは、貼り付けられた認証情報のように見える長い入力がマスキングされます(v0.9.80+)
gpc purchases orders review-refundに渡された--pending-refund-tokenは、--notifyの Webhook メッセージおよびプラグインフックデータに含まれません(v1.0.0-rc.1+)- ADC トークンキャッシュでは、認証情報ソースごとにハッシュベースのキーを使用し、複数アカウントの混同を防ぎます(v0.9.80+)
- プロジェクトの
.gpcrc.jsonからプラグインを自己承認することはできません。approvedPluginsはユーザー設定からのみ信頼されます(v0.9.80+)
5. 最小権限の付与
各サービスアカウントに必要な権限だけを付与してください。
アップロード専用サービスアカウント
Play Console の権限:
- アプリ情報の表示
- テストの管理(内部テスト/アルファテスト/ベータテスト用)
- 本番環境へのリリース(必要な場合のみ)
読み取り専用の監視サービスアカウント
Play Console の権限:
- アプリ情報の表示
- 財務データの表示(レポート用)
# Verify what a service account can do
gpc auth status --json | jq '.email'
# Then check that email's permissions in Play Console
6. 漏えいしたキーへの対処
サービスアカウントキーが漏えいした場合:
# 1. IMMEDIATELY delete the compromised key in Google Cloud Console
# IAM & Admin → Service Accounts → Keys → Delete
# 2. Create a new key
# Same page → Add Key → JSON
# 3. Update all locations using the key
gpc auth login --service-account /path/to/new-key.json
# 4. Update CI secrets
# All platforms using the old key
# 5. Clear token cache
rm -rf ~/.cache/gpc/tokens/
# 6. Review audit log for unauthorized actions
cat ~/.config/gpc/audit.log | jq 'select(.timestamp >= "LEAK_DATE")'
# 7. Review Google Cloud audit logs
# Cloud Console → IAM & Admin → Audit Logs
7. CI/CD のセキュリティパターン
GitHub Actions
# npm publish: OIDC via Trusted Publisher (v0.9.77+, no stored NPM_TOKEN)
permissions:
id-token: write # Required for OIDC token exchange with npm
# Google Play service account: encrypted secret
env:
GPC_SERVICE_ACCOUNT: ${{ secrets.PLAY_SA_KEY }}
# Restrict to specific branches
if: github.ref == 'refs/heads/main'
# Use environments for approval gates (staged publishing uses this)
environment: production
シークレットスキャン
# Check if keys are in git history
git log --all --full-history -p -- '*.json' | grep -l '"private_key"'
# If found, rotate immediately and clean git history
検証
gpc auth statusに想定したサービスアカウントのメールアドレスが表示されるgpc doctorですべてのチェックに合格する.gpcrc.jsonにシークレットやキーのパスが含まれていない~/.config/gpc/audit.logに監査ログが書き込まれている- CI のシークレットが暗号化され、ログに表示されない
- ローテーション後に古いキーが削除されている
障害モード/デバッグ
| 症状 | 考えられる原因 | 対処方法 |
|---|---|---|
| キーファイルが git にコミットされている | .gitignore に含まれていない | .gitignore に追加し、直ちにキーをローテーションします |
| ローテーション後もトークンキャッシュが古いまま | 古いトークンがキャッシュされている | ~/.cache/gpc/tokens/ を削除します |
| 監査ログが書き込まれない | 設定ディレクトリへの書き込み権限がない | ~/.config/gpc/ の権限を確認します |
| サービスアカウントのメールアドレスが不明 | キーを確認していない | gpc auth status --json | jq '.email' |
| CI のログに認証情報が表示される | 引数としてキーを渡している | 環境変数を使用し、CLI 引数には決して渡さないでください |
| コマンドを実行するたびにキーチェーンの確認が表示される | macOS キーチェーンへのアクセスが許可されていない | 確認画面で「常に許可」をクリックします |
8. サプライチェーンの保護(v0.9.77+)
GPC は、依存関係および公開に関するサプライチェーン攻撃に対し、15 層の防御を備えています。
| 層 | 内容 |
|---|---|
| 信頼されたパブリッシャー(OIDC) | npm への公開は GitHub OIDC で認証されます。長期有効な NPM_TOKEN はどこにも保存されません |
| 段階的な公開 | CI がパッケージをステージングし、メンテナーが 2FA で承認してから npm で公開します |
| NPM_TOKEN の削除 | GitHub シークレットに保存された npm トークンはありません。OIDC のみが認証経路です |
.npmrc の min-release-age=7 | 公開から 7 日未満のパッケージをブロックします |
pnpm-lock.yaml | バージョンを正確に固定し、予期しないアップグレードを防ぎます |
| Socket.dev CI スキャン | すべての PR で socket ci を実行し、重大なアラートがあればブロックします |
| Socket.dev GitHub App | リスクのある依存関係の変更について、PR にインラインコメントを投稿します |
CI の pnpm audit | 深刻度が高い CVE(本番環境の依存関係)を含む PR をブロックします |
| GitHub Actions の SHA 固定 | 14 個すべてのアクション参照を、変更可能なタグではなくコミットハッシュに固定します |
| SBOM(CycloneDX) | npm のリリースごとに部品表を生成し、アーカイブします |
| CODEOWNERS | セキュリティ上重要なパスには明示的なレビューを必須にします |
| Dependabot | 毎週、更新 PR を作成します(直接の依存関係のみ。アクションはグループ化) |
| Socket CLI ラッパー | ローカルで実行するすべての npm install と npx をスキャンします |
| CodeQL | プッシュのたびに静的解析を実行します |
| GitHub シークレットスキャン | 200 種類以上のシークレットパターンを含むプッシュをブロックします |
GPC の実行時依存関係は google-auth-library、commander、protobufjs、yauzl の 4 つだけです。すべての API 呼び出しでは、Node.js 組み込みの fetch を使用します。
設定:リポジトリルートの socket.yml で Socket.dev のアラートルールを制御します。.npmrc で min-release-age を制御します。.github/CODEOWNERS でレビュー要件を制御します。リリースワークフローでは、OIDC 認証を使って pnpm release-staged を実行します。
9. セキュリティ監査の状況(v0.9.80 + v0.9.82)
v0.9.80 deepsec の再スキャン:v0.9.80 のセキュリティ修正後、コードベース全体を対象に deepsec 監査を実施しました。結果:新たな検出事項は 0 件です。v0.9.74 の監査で追跡されていた検出事項は、すべて解決済みです。
Webhook の編集(v0.9.80):--webhook-url を使って Slack、Discord、およびカスタムエンドポイントに送信される Webhook ペイロードは、送信前に編集されるようになりました。プロセス外に送信される前に、ペイロードから機密フィールドが除去されます。これは、すべての gpc watch の侵害イベントと、その他すべての Webhook 送信経路に適用されます。
google-auth-library の更新(v0.9.82):google-auth-library を 10.7.0 にアップグレードしました。これにより、追跡対象として唯一残っていた本番環境の監査検出事項である、brace-expansion の推移的な脆弱性が解消されました。GPC では、本番環境の監査検出事項がゼロになりました。
9a. GPC GitHub Action のセキュリティ
GPC GitHub Action(yasserstudio/gpc-action)は、Node 24 で実行される TypeScript アクションで、以下のセキュリティ特性を備えています。
- 検証済みバイナリ:GPC GitHub リリースからスタンドアロンの
gpcバイナリをダウンロードし、キャッシュがヒットした場合も含め、実行のたびに SHA-256 を検証します。検証には、リリース内の変更可能なchecksums.txtだけでなく、アクション自体にコミットされたチェックサムを使用します。デフォルトの GPC バージョンは固定されています。アクション v1.1.4 時点では 1.0.0-rc.2 です。gpc-version: latestまたはバージョンが固定されていない場合は、警告を表示したうえでリリースのチェックサムにフォールバックします。 - 認証情報:認証には、
service-account-jsonで渡すサービスアカウント JSON キーを使用します。暗号化されたシークレットとして保存してください。現時点では、OIDC やキーを使わない認証方法はありません。 - 組み込みの事前チェックゲート:アクションはアップロード前に
gpc preflightを実行し、スキャンに失敗した場合は公開をブロックします(preflight: falseを指定するとスキップします)。 - Node 24 ランタイム:現在の GPC CLI の CI マトリックスに一致しています。
使用方法:
- uses: yasserstudio/gpc-action@v1
with:
service-account-json: ${{ secrets.GPC_SERVICE_ACCOUNT }}
package-name: com.example.app
release-files: app/build/outputs/bundle/release/app-release.aab
track: beta
10. 開発者認証
Google による Android 開発者認証の適用は、2026 年 9 月に開始されます(BR、ID、SG、TH)。
gpc verify # Status, deadlines, resources
gpc verify --open # Open verification page in browser
gpc verify --json # Machine-readable output
gpc verify checklist を実行すると、準備状況のチェックリスト全体を確認できます(v0.9.96 時点で 11 項目あり、すべてプロンプトで確認できます)。詳細は gpc-setup を参照してください。gpc doctor には認証チェックが含まれています。gpc status にはフッターのリマインダーが表示されます。gpc preflight にはスキャン後のリマインダーが表示されます。
11. 署名キーの検証(v0.9.75 以降)
ローカルの署名キーが Play の署名証明書と一致することを確認します。
gpc doctor --verify # Show Play cert fingerprint
gpc doctor --verify --keystore release.keystore --store-pass $PW # Compare local vs Play
フィンガープリントが一致しない場合、Play が使用するキーとは異なるキーで配布しています。2026 年 9 月 30 日以降にインストールがブロックされないよう、Play Console に登録してください。
12. セルフホストの Cloud KMS キーを使った Play App Signing(v0.9.96 以降)
gpc app-signing enroll と gpc app-signing rotate は、Google が API 経由で提供する唯一の Play App Signing の方法、つまりセルフホストの Google Cloud KMS キーを使った登録と、そのキーのローテーションに対応しています。
これは通常の方法ではありません。 Google が生成または管理するキーを使った標準的な Play App Signing は、API 経由では設定できません。Play Console で設定してください。コンプライアンス、規制、またはポリシー上の要件により、キーを自社の Cloud KMS インスタンス内で管理する必要がある場合に限り、これらのコマンドを使用してください。
# Enroll an app already published to Open testing or Production
gpc app-signing enroll \
--app com.example.app \
--existing-app \
--kms-key projects/acme/locations/global/keyRings/play/cryptoKeys/signing/cryptoKeyVersions/1
# Enroll an app not yet published (Google requires the certificate here)
gpc app-signing enroll \
--app com.example.app \
--new-app \
--kms-key projects/acme/locations/global/keyRings/play/cryptoKeys/signing/cryptoKeyVersions/1 \
--cert ./signing-cert.pem \
--upload-cert ./upload-cert.pem
# Rotate to a new Cloud KMS key
gpc app-signing rotate \
--app com.example.app \
--kms-key projects/acme/locations/global/keyRings/play/cryptoKeys/signing/cryptoKeyVersions/2 \
--cert ./new-signing-cert.pem \
--lineage ./lineage.bin \
--reason ROUTINE_KEY_UPGRADE
いずれかのコマンドを実行する前に、以下のセキュリティ特性を確認してください。
--certと--upload-certに指定できるのは PEM 証明書のみです。 ファイルフラグに秘密鍵を渡すと使用エラー(終了コード 2)になり、何も送信されません。秘密鍵がマシンの外に出ることはなく、署名キー自体も Cloud KMS に保持され、アップロードされることはありません。- いずれかのサブコマンドを呼び出す前に、キーのバージョンに対する Decrypt および Sign の IAM 権限を Play に付与してください。Google はサーバー側でこれを検証します。権限がない場合、Play API エラー(終了コード 4)で呼び出しが失敗します。
enrollでは--new-appと--existing-appのどちらか一方を指定する必要があります。どちらも指定しない場合、または両方を指定した場合は使用エラーになります。--new-appには--certも必要です。rotateは、セルフホストのキーを使ってすでに登録されているアプリにのみ適用されます(Google 管理のキーのローテーションは Play Console で行います)。また、ローテーションの証明として、apksigner rotateで生成した署名証明書のリネージファイルが必要です。--reasonは必須で、KEY_ROTATION_REASON_UNSPECIFIEDはローカルで拒否されます。受け付ける値:COMPROMISED_KEY、USE_STRONGER_KEY、USE_SAME_KEY_FOR_MULTIPLE_APPS、ROUTINE_KEY_UPGRADE、OTHER。- CI では確認プロンプトは表示されません。 どちらのコマンドも警告を表示し、対話型ターミナルでのみ確認を求めます。CI 環境、非 TTY、
--no-interactive、GPC_NO_INTERACTIVE、またはグローバルな--yesを指定した場合は処理を続行します。人による確認を挟みたい場合は、パイプラインで独自にゲートを設けてください。--dry-runを指定すると、リクエストを送信せずに内容をプレビューできます。
検証
gpc auth statusに想定されるサービスアカウントのメールアドレスが表示されるgpc doctorですべてのチェックに合格する.gpcrc.jsonにシークレットやキーのパスが含まれていない~/.config/gpc/audit.logに監査ログが書き込まれている- CI のシークレットが暗号化され、ログに表示されない
- ローテーション後に古いキーが削除されている
関連スキル
- gpc-setup — 初期認証と設定
- gpc-user-management — チームのアクセスと権限の管理
- gpc-ci-integration — CI/CD パイプラインのセキュアな設定
- gpc-troubleshooting — 認証エラーのデバッグ