AI & Digital Partners をビジョンに掲げるモンスターラボでは、全社員にDifyアカウントが提供されています。これにより、誰でも自由にワークフローやエージェントを開発し、社内に展開できる環境が整っています。当社では、顧客企業をはじめとする各種規定を遵守しつつ、AI活用を推進できるよう、AIの活用に関する社内ポリシーを制定しています。
しかし、DifyからGoogle Driveと連携しようとすると一つの壁にぶつかります。会社のGoogle Workspaceでは、ドライブの共有範囲が組織内に限定されており、先述のポリシーに則った利用の場合も制限が掛かってしまう場合があります。
本記事では、この制約を回避するためにGoogle Apps Script(GAS)でAPIを作成し、Default Application Credentialsで認証する方法を紹介します。
背景:なぜGAS APIが必要なのか
DifyにはGoogle Drive連携の機能がありますが、組織のセキュリティポリシーによっては直接アクセスできないケースがあります。そこで、GASをAPIのプロキシとして利用することで、Difyから間接的にGoogle Driveやスプレッドシートにアクセスできるようになります。
GASでAPIを作成する
開発環境の準備
GASの開発には clasp が便利です。ローカルでTypeScriptを使った開発ができ、AIコーディングアシスタントとの相性も良いです。
npm install -g @google/clasp
clasp login
clasp create --type webapp
APIエンドポイントの実装
GASでは doGet や doPost 関数を定義することでHTTPリクエストを受け付けられます。
function doGet(e: GoogleAppsScript.Events.DoGet): GoogleAppsScript.Content.TextOutput {
console.log('GET request received');
// ここでGoogle Driveやスプレッドシートの操作を行う
return ContentService.createTextOutput(JSON.stringify({ status: 'success' }))
.setMimeType(ContentService.MimeType.JSON);
}
function doPost(e: GoogleAppsScript.Events.DoPost): GoogleAppsScript.Content.TextOutput {
const payload = JSON.parse(e.postData.contents);
// スプレッドシートへのデータ追記など
return ContentService.createTextOutput(JSON.stringify({ status: 'success' }))
.setMimeType(ContentService.MimeType.JSON);
}
デプロイ
GASエディタから「デプロイ」→「新しいデプロイ」を選択し、ウェブアプリとして公開します。
公開後、以下の形式のURLでAPIを呼び出せます:
https://script.google.com/macros/s/{DEPLOYMENT_ID}/exec
認証の課題
ここで問題が発生します。組織内ユーザーにアクセスを限定している場合、APIを呼び出すにはGoogleアカウントの認証が必要になります。
DifyからこのAPIを呼び出すには、何らかの方法でアクセストークンを取得し、リクエストに含める必要があります。
解決策:Default Application Credentials
今回は Application Default Credentials(ADC) を利用してアクセストークンを取得します。
ADCは、Google Cloud SDKやクライアントライブラリが認証情報を自動的に検出するための仕組みです。ローカル開発環境では gcloud auth application-default login で作成した認証情報が使われます。
必要なスコープ
GASウェブアプリへのアクセスに必要な最小限のスコープは以下の通りです:
| スコープ | 必要性 | 理由 |
|---|---|---|
openid | 必須 | 認証の基本 |
drive | 必須 | GASウェブアプリへのアクセスに必要 |
userinfo.email | 任意 | Session.getActiveUser().getEmail() を使う場合 |
cloud-platform | 任意 | gcloud CLIが要求するだけ。直接取得なら不要 |
認証情報の作成
gcloud auth application-default login \
--scopes="openid,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/drive"
実行すると、認証情報が以下に保存されます:
# macOS / Linux
~/.config/gcloud/application_default_credentials.json
# Windows
%APPDATA%\gcloud\application_default_credentials.json
アクセストークンの取得
保存された認証情報からアクセストークンを取得するには、refresh_tokenを使ってトークンエンドポイントにリクエストします:
curl -X POST https://oauth2.googleapis.com/token \
-d "client_id={CLIENT_ID}" \
-d "client_secret={CLIENT_SECRET}" \
-d "refresh_token={REFRESH_TOKEN}" \
-d "grant_type=refresh_token"
Dify 上でのトークン取得
前述のように、Default Application Credentials として保存された認証情報を用いてアクセストークン取得APIを叩きます。 今回は、DifyのHTTPリクエストブロックを利用しました。
application_default_credentials.jsonに記載されている、 client_id, client_secret, refresh_tokenを利用します。
Difyには、認証情報をシークレットとして安全に管理してください。
HTTPリクエストブロックは、下図のように設定します。
- ヘッダー
Content-Type: application/x-www-form-urlencoded
- ボディ
x-www-form-urlencodedclient_id: シークレットに保存した client_idclient_secret: シークレットに保存した client_secretrefresh_token: シークレットに保存した refresh_tokengrant_type: refresh_token

Difyからの呼び出し
取得したアクセストークンをAuthorizationヘッダに付与してGAS APIを呼び出します。
リクエストするメソッドとURLは先述の通り、GASのDeploymentに応じて https://script.google.com/macros/s/{DEPLOYMENT_ID}/exec を呼び出します。
Authorization: Bearer {ACCESS_TOKEN}

セキュリティ上の考慮事項
この方法を採用する際は、以下の点に注意が必要です:
- 認証情報の漏洩リスク:Default Application Credentialsが漏洩すると、なりすましが可能になります。このリスクを、以下の条件のもとコントロールしています。
- スコープの最小化:必要最小限のスコープのみを指定し、権限を絞っている
- アクセス制限:Difyが社内からのアクセスに限定されている
- シークレット管理:Dify上では認証情報をシークレットとして管理し、ワークフロー定義に直接書かない
まとめ
DifyからGoogle Drive上のファイルにアクセスする手段として、GASを用いたAPIを作成しました。組織のアクセス制限を回避するため、Default Application Credentialsを使ってアクセストークンを取得し、認証を行っています。
この仕組みにより、Difyを活用した社内のAI駆動DXをさらに推進できます。
参考リンク
Author

Kiyotaka Kunihira
バックエンド/テックリード/スクラムマスター/エンジニアリングマネージャー


