ADK×GitHub OAuth認証サンプルを解説してみた

2025/10/21に公開されました。
2025/10/21に更新されました。

ADKとOAuthの基礎から、GitHub認証サンプルの実装・流れを図解&コード付きで解説します。


author: kuribo-

はじめに

「ADKって何?」「OAuthって難しそう…」
そんな方に向けて、GitHub OAuth認証をADKで実装するサンプルをわかりやすく解説します。
認証の流れやコードの役割を図解・実例で丁寧に説明します。

ADKとは?

ADK(Agent Development Kit)は、Googleが提供するAIエージェント開発のためのフレームワークです。
複雑な処理や外部サービス連携を「エージェント」として構築でき、AIモデル(LLM)とツール群を組み合わせて柔軟な自動化・対話システムを作ることができます。

本サンプルでは、以下の主要コンポーネントを利用しています。

  • LlmAgent
    AIモデル(例:Gemini)を使って、自然言語で指示を受けたり、処理を実行するエージェントです。
    「どんな順番でツールを使うか」「どんな情報を取得するか」などを自動で判断します。

  • Planner
    エージェントがどのようにタスクを進めるかを計画する役割です。
    BuiltInPlannerやReActPlannerなどがあり、思考の流れやツールの使い方を制御します。

この仕組みにより、認証→API操作など複数ステップの処理をAIが自律的に実行できるようになります。

OAuthとは?

Webサービスでよく使われる「OAuth認証」の仕組みをざっくり解説します。

パスワードを直接渡さずに認証できる理由

従来の認証では、サービスごとにIDとパスワードを入力し、サービス側がそれを管理していました。
しかし、OAuthでは「認証情報(パスワード)」をサービス側に直接渡すことなく、
第三者(例:GitHub、Googleなど)の認証基盤を利用して安全に認証・認可します。

ユーザーは「このサービスに自分のGitHub情報へのアクセスを許可する」といった形で権限を付与し、
サービス側は「アクセストークン」という一時的な鍵を使ってAPI操作します。
これにより、パスワード漏洩リスクを減らし、権限の細かい制御も可能になります。

主なOAuthの種類(認可コードグラントなど)

OAuth2.0にはいくつかの認証フローがあります。代表的なものは以下です。

  • 認可コードグラント
    一般的なWebアプリで使われる方式。ユーザーが認証画面で許可→認可コード→アクセストークン取得という流れ。
  • インプリシットグラント
    主にSPA(シングルページアプリ)向け。アクセストークンを直接取得するが、現在は非推奨。
  • クライアントクレデンシャルグラント
    サーバー間通信向け。ユーザーの関与なしにアクセストークンを取得。
  • リソースオーナーパスワードクレデンシャルグラント
    ユーザーのID・パスワードを直接サービスに渡す方式。セキュリティ上推奨されない。

本記事ではADKで「認可コードグラント」方式の実装をどう行うのか?を調査した結果をまとめています。

今回の認可コードグラントの流れ

OAuth2.0の「認可コードグラント」方式をステップ形式で説明します。

  1. クライアントが認証URLを生成し、ユーザーをGitHub認証画面へ誘導
  2. ユーザーが認証・許可すると、GitHubが認可コードを返す
  3. 認可コードを使ってアクセストークンを取得
  4. アクセストークンでAPI操作(リポジトリ一覧取得など)

GitHubの設定や、agent.pyとflask_callback.pyの連携・処理順も時系列で解説します。

Github OAuthアプリの設定方法

GitHub OAuth認証を使うには、事前にGitHubで「OAuthアプリ」を作成し、
Client IDClient Secretを取得する必要があります。

1. GitHubでOAuthアプリを作成

  1. GitHubのSettingsにアクセス
  2. 左メニューから「OAuth Apps」を選択し、「New OAuth App」をクリック
    OAuthApps
  3. 以下の項目を入力
  4. 「Register application」をクリック
    CreateOAuthApp

登録後、Client IDが発行され、Client Secretは手動で発行する必要があります。

2. .envファイルへの設定例

プロジェクト直下に.envファイルを作成し、以下のように記述します。

GITHUB_CLIENT_ID=取得したClient ID
GITHUB_CLIENT_SECRET=取得したClient Secret

3. 注意点

  • callback URLはこの後説明するflask_callback.pyのredirect_uriと一致させてください
  • Client Secretは絶対に公開しないように注意しましょう

これで、ADKサンプルの認証処理が正しく動作するようになります。

callback用サーバの必要性と役割

OAuth認証の「認可コードグラント」方式では、
GitHubから「認可コード」を受け取り、さらにアクセストークンまで取得するWebサーバー(コールバック先)が必要です。
この役割を担うのがflask_callback.pyです。

役割

  • GitHub認証画面でユーザーが許可操作をすると、GitHubは「認可コード」を指定したcallback URLに返します
  • flask_callback.pyはFlaskでWebサーバーを立て、/callbackエンドポイントで認可コードを受け取ります
  • 受け取った認可コードとstateを使い、GitHubのAPIにPOSTしてアクセストークンを取得します
  • 取得したアクセストークンを画面に表示します

ADKエージェントとの連携

  • agent.pyで生成した認証URLのredirect_uriはflask_callback.pyの/callbackに設定します
  • flask_callback.pyでアクセストークンを取得した後、そのトークンを使ってAPI操作(リポジトリ一覧取得など)を行います

ポイント

  • ローカル開発時はhttp://127.0.0.1:8081/callbackをcallback URLに設定
  • 認可コードは一時的なものなので、すぐにアクセストークン取得に使う必要があります
  • flask_callback.pyが認可コード→アクセストークン取得まで自動で処理します

この仕組みにより、GitHub認証→認可コード受け取り→アクセストークン取得という一連の流れがflask_callback.pyで完結します。

サンプルコード解説

ここでは、pythonのソースコード2ファイル(agent.py, flask_callback.py)とrequirements.txtを掲載します。
実際の動作や実装の流れを確認したい方は、ぜひ参考にしてください。

agent.py

import os
import logging
import requests
import secrets
import urllib.parse

from google.adk.agents.llm_agent import LlmAgent
from google.genai.types import ThinkingConfig
from google.adk.planners import BuiltInPlanner

from dotenv import load_dotenv
load_dotenv()

# ロガーの基本的な設定
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 環境変数からGitHub OAuth Appの認証情報を取得
GITHUB_CLIENT_ID = os.environ.get("GITHUB_CLIENT_ID")
GITHUB_CLIENT_SECRET = os.environ.get("GITHUB_CLIENT_SECRET")

def login() -> dict:
    """
    ADKツール: GitHub認可URLを生成し、stateも自動発行
    Returns:
        dict: 認可URLとstate
    """
    state = secrets.token_urlsafe(16)
    params = {
        "client_id": GITHUB_CLIENT_ID,
        "redirect_uri": "http://127.0.0.1:8081/callback",
        "scope": "repo",
        "state": state
    }
    auth_url = "https://github.com/login/oauth/authorize?" + urllib.parse.urlencode(params)
    return {
        "status": "success",
        "auth_url": auth_url,
        "state": state
    }

def get_repos(access_token: str) -> dict:
    """
    ADKツール: GitHub APIでユーザーのリポジトリ一覧を取得
    Args:
        access_token (str): GitHubアクセストークン
    Returns:
        dict: ユーザー名とリポジトリ一覧
    """
    headers = {"Authorization": f"token {access_token}"}
    user_res = requests.get("https://api.github.com/user", headers=headers)
    if user_res.status_code != 200:
        return {"status": "error", "error_message": "ユーザー情報取得失敗"}
    user_json = user_res.json()
    repos_res = requests.get("https://api.github.com/user/repos", headers=headers)
    if repos_res.status_code != 200:
        return {"status": "error", "error_message": "リポジトリ一覧取得失敗"}
    repos_json = repos_res.json()
    repo_list = [repo["full_name"] for repo in repos_json]
    return {
        "status": "success",
        "user": user_json.get("login", "GitHub User"),
        "repos": repo_list
    }

thinking_config = ThinkingConfig(
    include_thoughts=True,
    thinking_budget=256
)
logger.debug("ThinkingConfig:", thinking_config)

planner = BuiltInPlanner(
    thinking_config=thinking_config
)
print("BuiltInPlanner created.")

root_agent = LlmAgent(
    model="gemini-2.5-flash",
    name="github_repo_agent",
    instruction="GitHubのOAuth認証を行い、認証されたユーザーのリポジトリ一覧を取得して表示します。"
                "ツールの利用順は login → get_repos です。"
                "stateはクライアント側(loginツール)で発行し、GitHubから返されるのはcodeのみです。"
                "callbackはFlaskサーバー側で処理します。",
    planner=planner,
    tools=[login, get_repos]
)

flask_callback.py

このファイルは「ADKとは独立した、シンプルなWebサーバー」です。
GitHubからの情報(認可コードやアクセストークン)を受け取るためだけに動作し、
ADK(agent.py)と直接通信するのではなく、ユーザー(ブラウザ)を介して認証プロセスを中継する役割を担っています。
認証フローの中で「GitHub→flask_callback.py→ユーザー→ADK」という流れになる点がポイントです。

from flask import Flask, request
import os
import requests
from dotenv import load_dotenv

load_dotenv()

app = Flask(__name__)

GITHUB_CLIENT_ID = os.environ.get("GITHUB_CLIENT_ID")
GITHUB_CLIENT_SECRET = os.environ.get("GITHUB_CLIENT_SECRET")

@app.route("/callback")
def callback():
    code = request.args.get("code")
    state = request.args.get("state")
    if not code or not state:
        return "<h2>認証エラー</h2><p>不正なリクエストです。</p>", 400
    # アクセストークン取得
    token_url = "https://github.com/login/oauth/access_token"
    res = requests.post(token_url, data={
        "client_id": GITHUB_CLIENT_ID,
        "client_secret": GITHUB_CLIENT_SECRET,
        "code": code,
        "redirect_uri": "http://127.0.0.1:8081/callback",
        "state": state
    }, headers={"Accept": "application/json"})
    token_json = res.json()
    access_token = token_json.get("access_token")
    if not access_token:
        return "<h2>認証失敗</h2><p>アクセストークンの取得に失敗しました。</p>", 400
    return f"<h2>アクセストークン</h2><pre>{access_token}</pre>"

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8081)

この2ファイルを組み合わせることで、ADK×GitHub OAuth認証の一連の流れを実装できます。

セキュリティ注記:stateパラメータの検証について

OAuth 2.0のstateパラメータはCSRF攻撃対策のため必須です。
今回はサンプルのため実装を省いています。
本サンプルのようにプロセスが分かれている場合は、state値をDBやファイルで保存し、認可コードの受け取り時に検証してください。
同じプロセスであればDBではなくセッションで保存して検証するのが一般的です。

requirements.txt例

requirements.txtの中身例は以下です。

google-adk
requests
python-dotenv
flask

実行方法・動作確認

1. フォルダ構成例

プロジェクトのディレクトリ構成は以下のようになります。

src/
├── agent.py
├── flask_callback.py
├── requirements.txt
├── .env

2. 必要な環境変数・ライブラリ

  • .envファイルにGitHub OAuthのGITHUB_CLIENT_IDGITHUB_CLIENT_SECRETを設定
  • 必要なPythonライブラリをインストール
pip install -r src/requirements.txt

3. サーバーの起動

2つのPythonファイル(agent.py, flask_callback.py)をそれぞれ起動します。

# Flaskサーバー(認可コード受け取り用)
python src/flask_callback.py

# ADKエージェント(認証・API操作)
adk web

4. 認証フローの確認

  1. agent.pyを実行すると、ADKの画面が表示されます
  2. ADK画面でGitHubのリポジトリを表示するように指示をすると認証URLが発行されます
    例:
    GitHubのリポジトリ一覧を取得したいです。認証を開始してください。
  3. ブラウザで認証URLにアクセスし、GitHub認証画面で許可操作
  4. 許可後、http://127.0.0.1:8081/callbackにリダイレクトされ、アクセストークンが表示されます
  5. 表示されたアクセストークンをADK画面に貼り付けて、リポジトリ一覧を取得するように指示します
    例:
    さっきのアクセストークンを使って、私のリポジトリ一覧を取得してください。

フローとして図解するとこんな感じです。
OAuthFlow

5. つまづきポイント・注意点

  • .envの値が間違っていると認証に失敗します
  • callback URLが一致していないとGitHub認証後にエラーになります
  • ポート(8081)が他のプロセスで使われている場合は変更が必要です

これで、ADK×GitHub OAuth認証サンプルの動作確認ができます。

まとめ

本記事では、ADKとOAuthの基礎から、GitHub OAuth認証サンプルの実装・動作までを解説しました。

  • OAuth認証の仕組み や「パスワードを直接渡さずに認証できる理由」
  • 認可コードグラント方式 の流れと、実際のコードの役割
  • ADK(Agent Development Kit) によるAIエージェント構築のポイント
  • GitHub OAuthアプリの設定方法や、flask_callback.pyの役割
  • サンプルコードと実行手順

これらを通じて、認証フローの全体像や実装の流れが理解できたでしょうか。
これでOAuthの流れを理解できれば、以下のこともできるようになるでしょう。

  • 他のOAuthプロバイダー(Google, Twitterなど)への応用
  • ADKで複雑なAPI連携や自動化エージェントの開発
  • フロントエンドとの連携やWebアプリへの組み込み

実際に実装してみると「認証は難しい」と感じていたのですが、意外とそこまで難しくないのではと思えるところまでいけました。
引き続きADKでやりたいことを実装できるようにしていきたいです。

※本記事は、ジーアイクラウド株式会社の見解を述べたものであり、必要な調査・検討は行っているものの必ずしもその正確性や真実性を保証するものではありません。

※リンクを利用する際には、必ず出典がGIC dryaki-blogであることを明記してください。
リンクの利用によりトラブルが発生した場合、リンクを設置した方ご自身の責任で対応してください。
ジーアイクラウド株式会社はユーザーによるリンクの利用につき、如何なる責任を負うものではありません。