tech AI generated (Claude)

GitHub認証トークンの期限切れ検知とGitHub App移行による自動化パイプライン強化

平文トークン管理の課題を解決し、GitHub App の Installation Access Token を活用した自動更新可能な認証フローの実装方法

#github #api #automation #security #devops

データ分析パイプラインにおける GitHub 認証の課題

データ分析業務では、Issue 管理・PR 自動化・ブログ記事生成など、GitHub REST API を活用した自動化パイプラインが重要な役割を果たします。しかし、OAuth トークンの期限切れによる自動化停止は、業務継続性の大きなリスクとなります。

この記事では、平文トークン管理から GitHub App による自動更新可能な認証フローへの移行手順と、実装時の技術的検討点を再現可能な形で解説します。

GitHub 認証トークンの期限切れが引き起こす自動化パイプラインの停止

セキュリティリスク

# 現状: 平文でのトークン保存
echo "ghp_xxxxxxxxxxxxxxxxxxxx" > secrets/gh-token
  • ローカルファイルシステムに平文で GitHub トークンを保存
  • .gitignore で除外していても、ディスク上に機密情報が残存
  • トークンのローテーションが手動依存

運用負荷

# 手動更新が必要
find /sessions/*/mnt/*/secrets/gh-token -type f -exec cat {} \;
  • トークン期限切れ時の手動更新
  • 自動化パイプラインの予期しない停止
  • 24時間365日の監視が必要

GitHub App 移行による解決策

1. GitHub App の作成

GitHub App を作成し、以下の権限を設定します:

{
  "permissions": {
    "issues": "write",
    "pull_requests": "write",
    "contents": "write",
    "metadata": "read"
  },
  "events": [
    "issues",
    "pull_request"
  ]
}

2. Installation Access Token の取得

GitHub App の Installation Access Token は1時間の有効期限で自動更新されます:

// Installation Access Token の取得
const jwt = require('jsonwebtoken');
const fetch = require('node-fetch');

async function getInstallationAccessToken(appId, privateKey, installationId) {
  // JWT の生成
  const payload = {
    iat: Math.floor(Date.now() / 1000),
    exp: Math.floor(Date.now() / 1000) + (10 * 60), // 10分
    iss: appId
  };
  
  const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });
  
  // Installation Access Token の取得
  const response = await fetch(
    `https://api.github.com/app/installations/${installationId}/access_tokens`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Accept': 'application/vnd.github.v3+json'
      }
    }
  );
  
  const data = await response.json();
  return data.token;
}

3. 自動化パイプラインへの統合

#!/bin/bash
# GitHub App トークンを使った自動化スクリプト

APP_ID="123456"
INSTALLATION_ID="987654"
PRIVATE_KEY_PATH="/secure/github-app-key.pem"

# Installation Access Token の取得
TOKEN=$(node get-installation-token.js "$APP_ID" "$INSTALLATION_ID" "$PRIVATE_KEY_PATH")

# GitHub API の実行
curl -H "Authorization: token $TOKEN" \
     -H "Accept: application/vnd.github.v3+json" \
     https://api.github.com/repos/owner/repo/issues

トークン期限切れの検知と通知

1. 期限切れ検知ロジック

async function checkTokenExpiry(token) {
  try {
    const response = await fetch('https://api.github.com/rate_limit', {
      headers: { 'Authorization': `token ${token}` }
    });
    
    if (response.status === 401) {
      throw new Error('Token expired or invalid');
    }
    
    const rateLimit = await response.json();
    return rateLimit.rate.remaining > 0;
  } catch (error) {
    console.error('Token validation failed:', error.message);
    return false;
  }
}

2. Slack 通知の実装

async function notifyTokenExpiry(slackWebhookUrl, error) {
  const message = {
    text: "GitHub API 認証エラー",
    attachments: [{
      color: "danger",
      fields: [{
        title: "エラー内容",
        value: error.message,
        short: false
      }, {
        title: "対応",
        value: "GitHub App のトークン更新またはクレデンシャル確認が必要",
        short: false
      }]
    }]
  };
  
  await fetch(slackWebhookUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(message)
  });
}

実装時の技術的考慮点

サンドボックス環境での制約

# Cowork(Claude のローカルサブスクリプションに含まれる定期実行基盤)サンドボックスの制約
# - 毎回新規環境(状態引き継ぎなし)
# - FUSE マウント内のファイルは削除不可
# - 外部ネットワークアクセスは可能

秘密鍵の安全な管理

# GCP Secret Manager を使った秘密鍵管理
gcloud secrets create github-app-private-key \
  --data-file=private-key.pem

# 実行時に取得
PRIVATE_KEY=$(gcloud secrets versions access latest \
  --secret=github-app-private-key)

移行手順

1. 現行システムのバックアップ

# 既存のトークン設定をバックアップ
cp secrets/gh-token secrets/gh-token.backup

2. GitHub App の設定

  1. GitHub Settings > Developer settings > GitHub Apps
  2. “New GitHub App” を選択
  3. 必要な権限とイベントを設定
  4. 秘密鍵をダウンロード(.pem ファイル)

3. スケジュールタスクの更新

# .claude/skills/generate-blog/SKILL.md の環境セットアップ更新
sed -i 's/secrets\/gh-token/github-app-auth.js/' SKILL.md

4. 動作確認

# 新しい認証フローのテスト
node test-github-app-auth.js
gh api user --auth-token $(node get-installation-token.js)

期待される効果

セキュリティ向上

  • 平文トークンファイルの削除
  • 1時間の短い有効期限による露出リスク軽減
  • 秘密鍵の暗号化保存

運用負荷軽減

  • トークンローテーションの自動化
  • 期限切れによる自動化停止の回避
  • 24時間監視の不要化

保守性向上

  • 標準的な GitHub App パターンの採用
  • スケーラブルな認証アーキテクチャ
  • エラーハンドリングの統一化

まとめ

平文トークン管理から GitHub App への移行により、データ分析パイプラインの自動化がより安全で持続可能になります。Installation Access Token の自動更新機能を活用することで、運用負荷を大幅に軽減しながら、セキュリティレベルを向上できます。

実装時は、サンドボックス環境の制約を理解し、秘密鍵の管理方法を慎重に設計することが重要です。GCP Secret Manager や AWS Secrets Manager などのマネージドサービスとの組み合わせにより、エンタープライズレベルの認証システムを構築できます。

関連記事