【入門編】 Microsoft Graph APIを用いたCASBのテナント監視におけるHTTPステータスコード429(Too Many Requests) – ゼロトラスト&エンタープライズセキュリティ実践ガイド

インフラやネットワークの世界に飛び込んだばかりの皆さん、日々の学習や実務でお疲れ様です!技術の扉を開いたはいいものの、次から次へと出てくる横文字や専門用語の壁に、思わずクラッとしていませんか?「ゼロトラスト」や「CASB(キャスビー)」なんて言葉、なんだかカッコいいけれど、なんだか難しそう……ですよね。

でも、一歩ずつ紐解いていけば大丈夫です!今回は、クラウドの安全を守るCASBと、Microsoft 365の裏側でこっそり起こる「ちょっとしたすれ違い」について、身近な例えを交えながら優しく解説していきます。現場でそのまま使える実践的なコードも用意したので、ぜひ最後までリラックスして読んでいってくださいね。

—

1. そもそもCASBってなに?オフィスに例えてみよう

私たちが普段何気なく使っているMicrosoft 365などのクラウドサービス。会社の中だけでなく、自宅やカフェからもアクセスする今の時代、「社内だから安全」「社外だから危険」というこれまでの境界線は通用なくなりました。そこで登場するのが、すべてのアクセスを疑ってかかる「ゼロトラスト」の思想であり、そのクラウド版の守衛さんこそが CASB(Secure Access Service Edgeの構成要素の一つ) です。

CASBは、社員の皆さんがクラウド上でどんなファイルを開き、誰と共有し、怪しい動きをしていないかを常に見張っています。この見張りを続けるために、CASBのシステムは定期的にMicrosoftのサーバーへ「何か新しい事件(ログ)は起きていませんか?」と尋ねに行きます。このお使いのやり取りに使われるのが、Microsoft Graph API という共通の連絡通路なんですね。

2. 郵便配達員が直面する「受け取り拒否」の悲劇

さて、ここからが今日の本題です。
CASBという名の優秀な郵便配達員が、Microsoft 365という巨大なマンションの管理事務所(Graph API)へ、せっせと手紙(ログの要求)を届けに行くとします。

通常であれば、「はいどうぞ、こちらが今日の分です」とスムーズに受け渡しができます。しかし、会社全体の規模が大きかったり、リアルタイムに監視したい項目が山のようにあったりすると、CASBの配達員はこんな行動に出てしまいます。

  • 「ねえねえ、さっき手紙を渡したばかりだけど、もう次の新しい手紙はない!?」
  • 「1秒間に10回も、立て続けにノックして最新情報をちょうだい!」

これを見た管理事務所の管理人さんは、どう思うでしょうか?
「ちょっと待ってくれ!こっちは他にもたくさんの住人の対応で手一杯なんだよ!そんなに何度もドンドン叩くんじゃない!」と、怒ってドアをピシャリと閉めてしまいます。

この、「ちょっと君、リクエストが多すぎるよ!落ち着きなさい!」と管理事務所から突き返される現象こそが、HTTPステータスコード 429 (Too Many Requests) なのです。エラーの世界では「レートリミット(回数制限)超過」と呼ばれています。

3. レートリミットを華麗にかわす「バックオフ制御」という大人の対応

429 エラーを食らってしまったCASBの配達員が、「なんで受け取ってくれないんだ!」と意地になって再びドアを激しく叩き続けたらどうなるでしょう? 管理人さんはさらに怒って、いよいよ出入り禁止(一時的なアクセスブロック)にしてしまうかもしれません。これではセキュリティ監視が止まってしまい、本末転倒ですよね。

ここで必要になるのが、「バックオフ制御(Exponential Backoff:指数バックオフ)」 という賢い仕組みです。

人間社会でも、相手が忙しそうにしていたら「じゃあ、次は5秒後に声をかけてみよう」「それでもダメなら、今度は10秒待ってみよう」「次は20秒……」と、少しずつ待つ時間を増やしながら様子を見ますよね。プログラムの世界でも全く同じことをさせます。

バックオフ制御のイメージ

1. エラー (429) を検知する。
2. すぐに再挑戦せず、例えば 2秒 待つ。
3. 再びダメなら、待つ時間を倍の 4秒 に増やす。
4. さらにダメなら、次は 8秒 に増やす……と、少しずつクールダウンの時間を長くしていく。

こうすることで、サーバーへの負荷を優しく逃がしつつ、確実にログを回収できるようになるのです。

4. 実践!Pythonで学ぶ「バックオフ制御」のコード例

「言葉の意味は分かったけれど、実際にどうやってプログラムを書けばいいの?」という初学者の方のために、Pythonを使った具体的なサンプルコードを用意しました。現場のインフラエンジニアがよく書くスクリプトの雰囲気を感じ取ってみてくださいね。

import time
import requests

# Microsoft Graph APIのエンドポイント(例:監査ログ取得用URL)
API_URL = "https://graph.microsoft.com/v1.0/auditLogs/signIns"

# 認証トークン(実際の環境では変数やキーホルダーから安全に読み込みます)
HEADERS = {
    "Authorization": "Bearer 実際のアクセストークンをここに記述します",
    "Content-Type": "application/json"
}

def fetch_logs_with_backoff(url, headers, max_retries=5):
    """
    429エラー(Too Many Requests)を優しくハンドリングし、
    段階的に待機時間を増やしながらAPIからログを取得する関数です。
    """
    wait_time = 2  # 最初は2秒待つ設定にします
    
    for attempt in range(1, max_retries + 1):
        try:
            print(f"[試行 {attempt}/{max_retries}] APIにリクエストを送信中...")
            response = requests.get(url, headers=headers)
            
            # ステータスコードが 200 (成功) なら、無事にデータをゲット!
            if response.status_code == 200:
                print("-> ログの取得に成功しました!")
                return response.json()
            
            # ステータスコードが 429 (レートリミット超過) の場合
            elif response.status_code == 429:
                print(f"-> 429エラー検知: サーバーが混雑しています。{wait_time}秒間クールダウンします...")
                
                # Microsoft Graph APIは、親切に「何秒待てばいいか」を Retry-After ヘッダーで教えてくれることがあります
                retry_after = response.headers.get("Retry-After")
                if retry_after:
                    sleep_seconds = int(retry_after)
                else:
                    sleep_seconds = wait_time
                
                # 指定された時間だけ処理を一時停止(スリープ)させます
                time.sleep(sleep_seconds)
                
                # 次回のために待機時間を倍に増やします(指数バックオフ)
                wait_time *= 2
                
            else:
                # その他の予期せぬエラー(500系サーバーエラーなど)
                print(f"-> 予期せぬエラーが発生しました。ステータスコード: {response.status_code}")
                response.raise_for_status()
                
        except requests.exceptions.RequestException as e:
            print(f"通信エラーが発生しました: {e}")
            break
            
    print("最大試行回数に達したため、ログの取得を諦めました。管理者にアラートを飛ばします。")
    return None

# 関数の実行テスト(※実際の有効なトークンがない場合はエラーになります)
# log_data = fetch_logs_with_backoff(API_URL, HEADERS)

このコードのポイントは、response.status_code == 429 をキャッチしたあとに、time.sleep() を使ってあえて立ち止まっているところです。さらに、Microsoft Graph APIがこっそり教えてくれる Retry-After というお告げ(ヘッダー情報)を読み取って、それに従う優しさも持たせています。

5. まとめ:エラーコードはシステムからの「ラブレター」

いかがでしたでしょうか?
一見すると難しそうな 429 Too Many Requests というエラーも、郵便配達員と管理人の関係に置き換えてみると、なんだかクスッと笑えて親しみが湧いてきませんか?

ゼロトラストやCASBの運用において、エラーコードはシステムが発する「ちょっとペースを落としてよ!」というサイン(対話のきっかけ)です。ただ機械的にプログラムを動かすだけでなく、相手のサーバー事情を思いやる「大人のマナー(バックオフ制御)」を実装してあげることで、安定した強靭なセキュリティ基盤が築けるようになります。

焦らず、一歩ずつ、手を動かしながらインフラの世界を楽しんでいきましょう!それではまた次回の技術解説でお会いしましょう!

コメント

タイトルとURLをコピーしました