AUTOMATION NOTE — 077

Google Workspace退職者のOAuth連携リスクを低減する!GASとReports APIによる監査と解除

Google Workspaceでは、退職者のアカウント削除は一般的に実施されますが、そのアカウントが過去に許可した外部のOAuthアプリ連携が見落とされがちです。これにより、意図しないデータ漏洩リスクが残存する可能性があります。

この記事を読んだほうが良い人

  • 退職者のGoogle Workspaceアカウント削除は行っているが、OAuthアプリ連携の確認まで手が回っていない情シス担当者
  • 従業員が利用している外部サービスとの連携状況を把握したいと考えている管理者
  • Google Workspaceのセキュリティ監査を強化したい企業の担当者
  • Google Apps Script (GAS) を活用してGoogle Workspaceの運用を自動化したいと考えている方

なぜ退職者のOAuth連携が見落とされがちなのか?潜在リスクを理解する

多くの企業で退職者対応フローには、アカウントの停止、データ移行、Google Driveのオーナー権限移譲などが含まれます。しかし、ユーザーが個人で許可した外部サービスとのOAuthアプリ連携は、アカウント削除だけでは自動的に解除されないケースがあります。

OAuth連携は、ユーザーがGoogleアカウントの情報を外部サービスと共有することを許可する仕組みです。例えば、特定のプロジェクト管理ツールや分析ツールにGoogle Driveへのアクセス権を与えたり、Googleカレンダーの情報を連携させたりすることがこれにあたります。退職後もこれらの連携が残存していると、外部サービス側で何らかのセキュリティインシデントが発生した場合、退職済みユーザーの権限を介して企業データが漏洩するリスクを抱えることになります。

このリスクは、特に以下のような場合に高まります。

  • 退職者が利用していた外部サービスが多数ある場合
  • 従業員が許可なくシャドーITとして外部サービスを利用していた場合
  • 外部サービスのセキュリティポリシーが不明確な場合

企業の情報資産を守るためには、アカウント削除と同時に、関連するOAuthアプリ連携も適切に評価し、不要なものは解除することが不可欠です。

Admin SDK Reports APIでOAuthアプリの許可状況を把握する

Google Workspaceの管理者は、Admin SDK Reports APIを利用して、ユーザーがどのようなOAuthアプリ連携を許可しているかの監査ログを取得できます。このAPIは、管理コンソールからは見えにくい詳細な連携情報をプログラムで取得するのに役立ちます。

Reports APIとは?OAuth連携監査における活用

Admin SDK Reports APIは、Google Workspace環境におけるユーザーアクティビティ、管理者アクティビティ、ログインアクティビティなど、さまざまな監査ログを提供します。OAuthアプリ連携に関する情報は、token アプリケーションカテゴリの authorize_data_access イベントとして記録されます。

このAPIを使うことで、以下の情報を取得し、監査リストの基礎情報とすることができます。

  • どのユーザーが
  • どの外部アプリケーションに対して
  • どのようなスコープ(権限)で
  • いつアクセスを許可したか

注意点: - Reports APIで取得できるログのデータ保持期間は、通常6ヶ月間です(一部のログは1年間保持されます)。そのため、長期的な監査が必要な場合は、定期的にデータを取得し、外部に保存する必要があります。 - Reports APIでは、Google自身のアプリ(例: Google Drive、Google ドキュメント)や、一部の古いOAuth連携など、すべてのOAuthアプリ連携が把握できるわけではありません。主要なサードパーティ製アプリの連携状況を把握するのに有効です。

GASでReports APIからデータを取得する具体的な手順

ここでは、Google Apps Script (GAS) を利用してAdmin SDK Reports APIからOAuthアプリ連携のログを取得し、Googleスプレッドシートに出力する手順を解説します。

1. Google Apps Scriptプロジェクトのセットアップ

  1. 新しいGoogleスプレッドシートを作成し、名前を付けます(例: OAuthアプリ連携監査レポート)。
  2. スプレッドシートから「拡張機能」>「Apps Script」を選択し、新しいGASプロジェクトを開きます。
  3. Google Apps Script (GAS) プロジェクトの名前を付けます(例: GWS OAuth Audit Script)。

2. Admin SDK Reports APIを有効にする

GASプロジェクトの左側メニューにある「サービス」アイコン(+ボタン)をクリックし、「Admin SDK API」を選択して追加します。これにより、GASからAdmin SDK Reports APIを呼び出せるようになります。

3. 必要な認証スコープを設定する

GASプロジェクトの appsscript.json マニフェストファイルに、以下の認証スコープを追加します。

{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/admin.reports.audit.readonly",
    "https://www.googleapis.com/auth/spreadsheets"
  ]
}

https://www.googleapis.com/auth/admin.reports.audit.readonly はReports APIの読み取り権限、https://www.googleapis.com/auth/spreadsheets はスプレッドシートへの書き込み権限です。

4. GASコードの実装とカスタマイズ

以下のGASコードをエディタに貼り付けます。YOUR_SPREADSHEET_ID は、先ほど作成したスプレッドシートのIDに置き換えてください。スプレッドシートIDは、URLの d//edit の間に表示される文字列です。

function getOAuthAppActivities() {
  const SPREADSHEET_ID = 'YOUR_SPREADSHEET_ID'; // ★ここをあなたのスプレッドシートIDに置き換えてください
  const SHEET_NAME = 'OAuthAppActivities'; // 出力シート名

  const ss = SpreadsheetApp.openById(SPREADSHEET_ID);
  let sheet = ss.getSheetByName(SHEET_NAME);
  if (!sheet) {
    sheet = ss.insertSheet(SHEET_NAME);
    // ヘッダー行を設定
    sheet.appendRow(['ユーザーメール', 'イベント名', 'アプリケーション名', 'クライアントID', 'スコープ', 'トークンタイプ', 'アクセスタイプ', 'OAuth連携許可イベント日時']);
  } else {
    // 既存データをクリアして新しいヘッダーを追加
    sheet.clearContents();
    sheet.appendRow(['ユーザーメール', 'イベント名', 'アプリケーション名', 'クライアントID', 'スコープ', 'トークンタイプ', 'アクセスタイプ', 'OAuth連携許可イベント日時']);
  }

  const today = new Date();
  // 過去1年間のデータを取得する例。必要に応じて期間を調整してください。
  const oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());
  const startTime = oneYearAgo.toISOString();
  const endTime = today.toISOString();

  let pageToken = null;
  let allActivities = [];

  Logger.log(`OAuthアプリ連携ログの取得を開始します。期間: ${startTime} から ${endTime}`);

  do {
    try {
      const response = AdminReports.Activities.list('all', 'token', {
        eventName: 'authorize_data_access',
        maxResults: 1000, // 1回のリクエストで取得する最大件数
        startTime: startTime,
        endTime: endTime,
        pageToken: pageToken
      });

      const activities = response.items;
      if (activities && activities.length > 0) {
        allActivities = allActivities.concat(activities);
      }
      pageToken = response.nextPageToken;
    } catch (e) {
      Logger.log(`API呼び出し中にエラーが発生しました: ${e.message}`);
      break;
    }
  } while (pageToken);

  if (allActivities.length === 0) {
    Logger.log('指定期間内にOAuthアプリ連携の活動は見つかりませんでした。');
    sheet.appendRow(['指定期間内にOAuthアプリ連携の活動は見つかりませんでした。']);
    return;
  }

  const data = allActivities.map(activity => {
    // eventParametersはevents配列の各要素の中にある
    const parameters = activity.events && activity.events[0] && activity.events[0].parameters;
    const userEmail = activity.actor && activity.actor.email;
    const eventName = activity.events && activity.events[0] && activity.events[0].name;

    let appName = '';
    let clientId = '';
    let scope = '';
    let tokenType = '';
    let accessType = '';

    if (parameters) {
      parameters.forEach(param => {
        switch (param.name) {
          case 'application_name':
            appName = param.value;
            break;
          case 'client_id':
            clientId = param.value;
            break;
          case 'scope':
            scope = param.value;
            break;
          case 'token_type':
            tokenType = param.value;
            break;
          case 'access_type':
            accessType = param.value;
            break;
        }
      });
    }

    // activity.id.time は OAuth連携が許可されたイベントの発生日時
    return [userEmail, eventName, appName, clientId, scope, tokenType, accessType, activity.id && activity.id.time];
  });

  // データをスプレッドシートに書き込む
  // ヘッダー行の下からデータを挿入するため、getLastRow() + 1 を使用
  sheet.getRange(sheet.getLastRow() + 1, 1, data.length, data[0].length).setValues(data);
  Logger.log(`OAuthアプリ連携の活動ログ ${data.length} 件をスプレッドシートに書き込みました。`);
}

5. GASスクリプトの実行

GASエディタで getOAuthAppActivities 関数を選択し、再生ボタン(▶)をクリックして実行します。初回実行時には、Googleアカウントの認証が求められます。許可すると、指定したスプレッドシートにOAuthアプリ連携のログが出力されます。

このコードは、過去1年間のOAuthアプリ連携のログを最大件数1000件ずつ取得し、ページネーションを用いてすべてのデータを取得します。取得したデータは指定のスプレッドシートに出力され、ユーザーメール、アプリケーション名、付与されたスコープなどの情報が一覧で確認できます。

注意点: - Google Apps Scriptのスクリプト実行には、最大6分間の時間制限があります。大量のデータを処理する場合、この制限に達する可能性があります。その場合は、処理を分割したり、より効率的なデータ取得方法を検討したりする必要があります。

検出したOAuth連携を評価し、適切な対処を行う

スプレッドシートに出力されたデータを基に、退職済みユーザーが許可したOAuthアプリ連携を評価し、適切な対処を行います。

情シス担当者は、単に連携を解除するだけでなく、以下の点を考慮して判断を下すことが重要です。

  • リスクレベルの判断基準: すべてのOAuth連携が同等のリスクを持つわけではありません。アクセススコープが広範なもの(例: Google Driveの全ファイルへのアクセス)や、機密情報を扱う外部サービスとの連携は、より高いリスクと評価すべきです。
  • シャドーITに対する組織ポリシー: 従業員が許可なく利用している外部サービス(シャドーIT)が検出された場合、単に連携を解除するだけでなく、その背景を調査し、再発防止のための組織ポリシー策定や従業員への啓発が必要です。
  • 連携解除の影響: 業務上必要な連携であった可能性も考慮し、安易な全解除は避けるべきです。退職者の後任者への引き継ぎ状況や、過去の業務内容を把握した上で、本当に不要な連携のみを解除することが望ましいです。

取得データからリスクを評価するポイント

出力されたログを参考に、以下の観点でリストを評価します。

  • ユーザーメール: 退職者かどうかの確認
  • アプリケーション名: どのようなサービスか、企業で利用を許可されているものか
  • スコープ(権限): どのような情報にアクセスが許可されているか(例: https://www.googleapis.com/auth/drive はGoogle Driveへのアクセス権)
  • OAuth連携許可イベント日時: OAuth連携が許可されたイベントの発生日時。連携が非常に古い場合、現在も利用されているかは不明ですが、リスク評価の一助となります。

退職者の行に絞り込み、不要な連携やリスクが高いと判断される連携を特定します。

管理コンソールでのOAuth連携解除手順

不要と判断されたOAuthアプリ連携は、Google Workspace管理コンソールから削除できます。

1. 特定ユーザーの連携を個別に解除する

特定の退職者が許可した連携を個別に解除する場合の手順です。 1. Google Workspace管理コンソールに管理者アカウントでログインします。 2. 左側のメニューから「ディレクトリ」>「ユーザー」を選択します。 3. 対象の退職済みユーザーを検索し、クリックします。 4. ユーザーの詳細画面で「セキュリティ」タブを選択します。 5. 「接続済みのアプリ」セクションで、不要なアプリの右側にある「アクセス権を削除」をクリックします。

2. アプリケーション単位でアクセスを制御する

特定の外部アプリ自体を組織全体でブロックしたり、特定のユーザーグループにのみ許可したりする場合の手順です。 1. Google Workspace管理コンソールに管理者アカウントでログインします。 2. 左側のメニューから「セキュリティ」>「アクセスとデータ管理」>「APIのコントロール」を選択します。 3. 「アプリのアクセスを管理」をクリックします。 4. ここで、特定のアプリを検索し、組織全体でアクセスをブロックしたり、信頼済みとして登録したりできます。退職者が許可した特定のアプリがシャドーITであった場合などに有効です。

これらの手順で、不要なOAuthアプリ連携を安全に解除し、潜在的なデータ漏洩リスクを低減できます。

退職者対応フローへの組み込みと継続的な監査体制の構築

OAuthアプリ連携の評価と解除は、退職者対応フローの重要な一部として組み込むべきです。

退職者チェックリストに監査項目を追加する

既存の退職者対応チェックリストに、以下の項目を追加することを推奨します。

  • OAuthアプリ連携の監査と解除: Admin SDK Reports APIでログを取得し、不要なOAuthアプリ連携を特定・解除する。
  • 外部サービスアカウントの確認: 退職者が利用していた外部サービスのアカウントを特定し、停止または移管する。

GASトリガーで定期的な監査レポートを自動生成する

先ほど作成したGoogle Apps Script (GAS) スクリプトは、手動実行だけでなく、定期的に自動実行することも可能です。 1. GASプロジェクトの左側メニューにある「トリガー」アイコン(時計のマーク)をクリックします。 2. 「トリガーを追加」をクリックします。 3. 「実行する関数を選択」で getOAuthAppActivities を選択します。 4. 「イベントのソースを選択」で「時間主導型」を選択します。 5. 「時間ベースのトリガーのタイプを選択」で「月ベースのタイマー」や「週ベースのタイマー」などを選択し、実行頻度を設定します。

これにより、毎月または毎週、自動的にOAuthアプリ連携のログがスプレッドシートに書き出され、常に最新の監査レポートを維持できるようになります。定期的なチェック体制を確立することで、情報漏洩リスクを継続的に監視・管理できます。

まとめ

Google Workspaceにおける退職者アカウントのOAuthアプリ連携は、見過ごされがちな情報漏洩リスクの一つです。Admin SDK Reports APIとGoogle Apps Scriptを活用することで、この見落とされがちな連携状況を可視化し、適切な監査と解除を行うことが可能になります。

本記事で紹介したGASコードと管理コンソールでの操作手順を参考に、以下のステップでセキュリティ対策を強化してください。 1. Google Apps Script (GAS) スクリプトでOAuthアプリ連携のログを定期的に取得し、スプレッドシートにまとめる。 2. 退職者やリスクの高い連携をリストアップし、評価を行う。 3. Google Workspace管理コンソールから不要なOAuthアプリ連携を解除する。 4. 退職者対応フローにOAuthアプリ連携の監査・解除プロセスを組み込み、定期的な自動監査体制を構築する。

これらの取り組みを通じて、企業のGoogle Workspace環境におけるセキュリティレベルを向上させ、情報資産を確実に保護することが可能になります。

コーポレートITのご相談はお気軽に

この記事で書いたような業務改善・自動化の設計から実装まで、DRASENASではコーポレートITの現場に寄り添った支援を行っています。 「まず相談だけ」でも大歓迎です。DRASENAS 公式サイトからお気軽にどうぞ。

CONTACT

御社の IT 部門、ここにあります。

「ITのことはあまりわからない」── そのような状態からで、まったく問題ございません。まずはお気軽にご相談ください。

一社ずつ、一から。