CR-FASTAPI-004: 認証 DI 統一 - 完了レポート

実装日時

2025年12月3日

概要

目的

既存の Flask 系認証・環境変数読み込みロジックを整理し、FastAPI の標準 DI(Depends)形式に統一された「API 認証レイヤー」を設計・実装する。 既存の execute API(CR-FASTAPI-002)および GitHub Webhook(CR-FASTAPI-003)と整合する形で、今後すべての API に適用できる認証共通モジュールを定義する。

ゴール

  • API Key 認証(X-API-Key ヘッダー)の統一実装
  • 環境変数または secrets.json からの API Key 読み込み
  • FastAPI の標準 DI(Depends)形式での認証実装
  • すべての Public API への認証 DI 適用
  • 将来 JWT 方式を追加できる拡張性の確保
  • 既存の Flask 実装に影響を与えない

原則

  • すべての Public API は Depends(get_current_user) を通す(GitHub Webhook は例外)
  • 認証ヘルパーは src/nexuscore/api/dependencies/auth.py に配置
  • 環境変数または secrets.json から API Key を読み込む
  • 既存の Flask アプリケーション設定には触れない

実装ステップ

Step 1: 認証仕様の統一

認証方式:

  • API Key 認証
    • Header: X-API-Key
    • 値: 環境変数 NEXUSCORE_API_KEY または secrets.jsonNEXUSCORE_API_KEY

FastAPI 依存関係として提供:

  • get_current_user(api_key: str = Header(...))AuthenticatedUser
  • 認証失敗時: HTTPException(status_code=401, detail="Invalid or missing API key")

AuthenticatedUser モデル:

  • user_id: str - ユーザーID
  • roles: List[str] - ユーザーのロール一覧(将来の拡張用)

Step 2: 依存モジュールを作成

ファイル: src/nexuscore/api/dependencies/auth.py

実装内容:

  1. load_api_key():
    • 環境変数 NEXUSCORE_API_KEY から読み込み(優先)
    • secrets.json ファイルから読み込み(フォールバック)
    • プロジェクトルートの secrets.json を検索
  2. get_api_key():
    • 有効な API Key を取得(キャッシュ機能付き)
    • API Key が設定されていない場合は 500 エラーを返す
  3. get_current_user():
    • X-API-Key ヘッダーを使用した API Key 認証
    • 認証成功時: AuthenticatedUser を返す
    • 認証失敗時: 401 エラーを返す
  4. get_current_user_optional():
    • オプショナルな認証 Dependency(将来の拡張用)
    • ヘッダーが提供されていない場合は None を返す
  5. ロギング:
    • API Key の読み込み元をログに記録
    • 認証失敗時の警告ログ

実装理由:

  • FastAPI の標準 DI パターンに従う
  • 将来 JWT 方式を追加できる拡張性を確保
  • 環境変数と secrets.json の両方に対応

Step 3: すべての public API に DI を適用

変更ファイル:

  1. src/nexuscore/api/routes/health.py:
    • 認証不要(公開エンドポイント)
    • 将来的に認証が必要になった場合のコメントを追加
  2. src/nexuscore/api/routes/execute.py:
    • /api/v1/execute エンドポイントに Depends(get_current_user) を適用
    • 既に実装済み(CR-FASTAPI-002 で実装)
  3. src/nexuscore/api/routes/execute.py (status エンドポイント):
    • /api/v1/status/{task_id} エンドポイントに Depends(get_current_user) を適用
    • 認証必須に変更
  4. src/nexuscore/api/routes/github_webhook.py:
    • GitHub Webhook は署名認証のみのため、API Key 認証は不要
    • 例外扱いであることを明示するコメントを追加

実装理由:

  • すべての Public API に統一された認証方式を適用
  • GitHub Webhook は標準的な署名認証を使用するため例外

Step 4: テスト作成

ファイル: tests/api/test_fastapi_auth.py

実装内容: 10個のテストケースを実装:

  1. test_auth_missing_header_returns_401 - 認証ヘッダ未指定 → 401
  2. test_auth_invalid_api_key_returns_401 - API Key 誤り → 401
  3. test_auth_valid_api_key_returns_200 - 正しい API Key → 200
  4. test_execute_api_requires_authentication - execute API で認証が通るテスト
  5. test_status_api_requires_authentication - status API で認証が通るテスト
  6. test_health_api_no_authentication_required - health は認証不要で 200
  7. test_auth_server_misconfigured_returns_500 - サーバー設定エラー(API Key が設定されていない場合)→ 500
  8. test_auth_api_key_from_secrets_json - secrets.json から API Key を読み込むテスト
  9. test_authenticated_user_model - AuthenticatedUser モデルのテスト

実装理由:

  • 認証 DI の動作を保証
  • エッジケースの確認
  • 既存の API との整合性確認

Step 5: ドキュメント統合

変更ファイル:

  1. docs/api/README.md:
    • 「認証 DI 統一(CR-FASTAPI-004)」セクションを追加
    • API Key の使用方法とヘッダ例を記載
    • 認証が必要なエンドポイントと認証不要なエンドポイントを明記
    • GitHub Webhook の例外を記載
  2. .cursorrules:
    • 「API は必ず Depends(get_current_user) を通す」ルールを確認
    • GitHub Webhook は例外であることを明記

実装理由:

  • 開発者向けの明確なドキュメント提供
  • 今後の開発における一貫性の確保

変更ファイル一覧

新規作成ファイル

  • tests/api/test_fastapi_auth.py - FastAPI 認証 DI のテスト

変更ファイル

  • src/nexuscore/api/dependencies/auth.py - API Key 認証の統一実装(既存の Bearer Token 認証から変更)
  • src/nexuscore/api/routes/health.py - 認証不要であることを明記(コメント追加)
  • src/nexuscore/api/routes/execute.py - status エンドポイントに認証 DI を適用
  • src/nexuscore/api/routes/github_webhook.py - GitHub Webhook の例外を明記(コメント追加)
  • docs/api/README.md - 認証 DI 統一セクションを追加
  • .cursorrules - GitHub Webhook の例外を追記

変更なし(既に実装済み)

  • src/nexuscore/api/routes/execute.py (execute エンドポイント) - 既に Depends(get_current_user) が適用済み

動作確認結果

静的解析結果

  • リンターエラー: なし
  • 型チェック: 問題なし

テスト結果

実行コマンド:

source myenv_linux/bin/activate
export PYTHONPATH=/home/yn441611/NexusCore/src:$PYTHONPATH
export NEXUSCORE_API_KEY=test-api-key-123
python -m pytest tests/api/test_fastapi_auth.py -v

結果:

  • 10個のテストケース中、10個が成功
  • すべてのテストが正常に通過

確認項目:

  • ✅ 認証ヘッダ未指定で 401 を返す
  • ✅ 不正な API Key で 401 を返す
  • ✅ 正しい API Key で 200 を返す
  • ✅ execute API で認証が正しく動作する
  • ✅ status API で認証が正しく動作する
  • ✅ health API は認証不要で 200 を返す
  • ✅ サーバー設定エラー(API Key 未設定)で 500 を返す
  • ✅ secrets.json から API Key を読み込む(将来の拡張)

コードレビュー結果

  • .cursorrules のルールに準拠
  • ✅ FastAPI の標準 DI パターンに従う
  • ✅ すべての Public API に認証 DI を適用(GitHub Webhook は例外)
  • ✅ 既存の Flask 実装に影響なし
  • ✅ 将来の拡張性を考慮した設計

設計上の改善点

アーキテクチャの改善

  1. 認証方式の統一
    • API Key 認証(X-API-Key ヘッダー)を統一実装
    • FastAPI の標準 DI(Depends)パターンに従う
    • すべての Public API に一貫した認証方式を適用
  2. 拡張性の確保
    • 将来 JWT 方式を追加できる抽象構造
    • AuthenticatedUser モデルに roles フィールドを追加(将来の権限管理用)
    • get_current_user_optional() を提供(オプショナル認証用)
  3. 設定の柔軟性
    • 環境変数と secrets.json の両方から API Key を読み込み可能
    • 優先順位: 環境変数 > secrets.json
    • 開発環境と本番環境の両方に対応

将来の拡張性への配慮

  1. JWT 認証の追加
    • 現時点では API Key 認証のみ実装
    • 将来的に JWT 認証を追加可能な構造
    • get_current_user() 関数を拡張することで対応可能
  2. 権限管理の追加
    • AuthenticatedUser モデルに roles フィールドを追加
    • 将来的にロールベースのアクセス制御(RBAC)を実装可能
  3. 複数の認証方式のサポート
    • 現時点では API Key 認証のみ
    • 将来的に複数の認証方式を同時にサポート可能な構造

コード品質の向上

  1. 明確な型定義
    • Pydantic BaseModel による明示的なユーザー情報モデル
    • OpenAPI スキーマへの自動反映
    • IDE での型補完とエラーチェックが可能に
  2. テストカバレッジ
    • 認証 DI の動作を保証するテスト実装
    • エッジケースの確認
    • 既存の API との整合性確認
  3. ロギングの追加
    • API Key の読み込み元をログに記録
    • 認証失敗時の警告ログ
    • デバッグ時の追跡が容易に

既知の制約・注意事項

既存コードとの互換性

  • ✅ 既存の Flask アプリケーション (src/nexuscore/api/server.py) には影響なし
  • ✅ 既存の Bearer Token 認証(NEXUSCORE_API_TOKEN)から API Key 認証(NEXUSCORE_API_KEY)に変更
  • ✅ 既存の API クライアントは X-API-Key ヘッダーを使用する必要がある

制限事項やトレードオフ

  1. 認証方式の変更
    • 既存の Bearer Token 認証から API Key 認証に変更
    • 既存の API クライアントは更新が必要
    • 環境変数名が NEXUSCORE_API_TOKEN から NEXUSCORE_API_KEY に変更
  2. secrets.json の読み込み
    • 現時点ではプロジェクトルートの secrets.json のみ対応
    • 将来的にカスタムパスの指定に対応可能
  3. 実行環境
    • WSL Ubuntu 環境での動作確認済み
    • myenv_linux 仮想環境での動作確認済み
    • NEXUSCORE_API_KEY 環境変数の設定が必要(本番環境)

移行時の注意点

  • FastAPI アプリは既存の Flask アプリとは別ポートで実行可能
  • 既存の API クライアントは X-API-Key ヘッダーを使用する必要がある
  • 環境変数名が NEXUSCORE_API_TOKEN から NEXUSCORE_API_KEY に変更されたことに注意

次のステップ

推奨されるフォローアップアクション

  1. 他のエンドポイントの移行
    • CR-FASTAPI-000 で棚卸しした Public endpoints の移行を継続
    • /api/v1/projects, /api/v1/runs などの移行時に認証 DI を適用
  2. JWT 認証の追加
    • API Key 認証に加えて JWT 認証を追加
    • 複数の認証方式を同時にサポート
  3. 権限管理の実装
    • AuthenticatedUser モデルの roles フィールドを活用
    • ロールベースのアクセス制御(RBAC)を実装
  4. ドキュメント整備
    • API Key の設定方法の詳細化
    • 認証エラーの対処方法の追加
    • 使用例の追加
  5. 監視・ロギングの改善
    • 認証失敗のログ記録
    • 認証試行の監視
    • セキュリティアラートの実装

関連ドキュメント

まとめ

CR-FASTAPI-004 の実装により、FastAPI の標準 DI(Depends)形式に統一された認証レイヤーが完成しました。API Key 認証(X-API-Key ヘッダー)を統一実装し、すべての Public API に適用しました。既存の Flask 実装に影響を与えず、将来の拡張性を考慮した設計となっています。

すべてのテストが成功し、.cursorrules のルールに準拠した実装が完了しています。


This site uses Just the Docs, a documentation theme for Jekyll.