Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Azure OpenAI Service のネットワークアクセスを制限する

こんにちは、igaです。
ポケモンsleepを継続していますが、行ける場所が増えたことで新しいポケモンに出会えるようになりました。


今回は、Azure OpenAIのセキュリティを向上させるため、ネットワークのアクセス制限について確認してみました。

Azure OpenAIの利用制限

Azure OpenAIを利用するためには、通常、APIキーが必要になります。
APIキー自体、ランダムな数字と文字で生成されるもので、これだけでもある程度セキュリティは確保できるものの、もし、APIキーが外部に知られてしまうと、想定していない人や環境から、自社のAzure OpenAIにアクセスされてしまいます。

APIキーが万が一漏洩してしまった場合に、Azure OpenAIを不正に利用されないようにするため、ネットワークのアクセスを制限します。

Azure OpenAIへのネットワークアクセスを制限する

Azure OpenAIに対して、アクセスを制限する方法には、以下の2つがあります。

①特定IPアドレスからのアクセスのみ許可
②Azure内のプライベート通信でのアクセスのみ許可

それぞれを簡略化した図で表すと、次のようになります。

①特定IPアドレスからのアクセスのみ許可

許可した外部ネットワークから、Azure OpenAIを利用することができます。

②Azure内のプライベート通信でのアクセスのみ許可

Azure内仮想ネットワークからのみ、Azure OpenAIがリクエストを受け付けることになります。
この場合、インターネットからリクエストを受け付けるためのアプリケーションが必要になります。
今回の例では、App Serviceを利用してAzure OpenAIにリクエストを送るアプリケーションを構築します。


それぞれのメリット、デメリットは以下のようになります。

設定内容 メリット デメリット
①特定IPアドレスからのアクセスのみ許可 ・追加のコストが不要である IPアドレスが特定できない場合は利用できない(Azure Functionsなどのマネージドサービスからのアクセスなど)
・インターネットからのアクセスを制限できない
②Azure内のプライベート通信でのアクセスのみ許可 ・特定のVNetからのアクセスに限定できる
・インターネットからのアクセスを制限できる
・追加のコストが必要になる(稼働時間、および、通信量に基づく費用が発生する)

①特定IPアドレスからのアクセスのみ許可

Azure Portalから、作成してあるAzure OpenAIを選択します。
サイドメニューから「Networking」を選択すると、「Firewalls and virtual networks」タブで接続元IPアドレスの許可設定を行うことができます。

設定項目と、どこからAzure OpenAIを利用できるのかを整理すると以下のようになります。

設定項目 利用可否
すべてのネットワーク すべての接続元IPアドレスから、Azure OpenAIを利用できる
Selected Networks and Private Endpoints 指定した接続元IPアドレスからのみ、Azure OpenAIを利用できる
無効 インターネットから、Azure OpenAIが利用できない

「Selected Networks and Private Endpoints」を選択すると、以下の画面でインターネットからの接続元IPアドレスと、Azure内仮想ネットワーク(VNet)を指定することができます。
今回は、Azure内仮想ネットワーク(VNet)は指定せず、インターネットからの接続元IPアドレスを指定します。

「クライアントIPアドレス」として、Azure Portalを操作している外部ネットワークの接続元IPアドレスが表示されています。
このチェックをつけることで、Azure OpenAIを利用する接続元IPアドレスが追加されます。
Azure Portalを操作している外部ネットワークとは別の接続元IPアドレスを指定する場合は、「IPアドレスまたはCIDR」のテキストボックスにIPアドレスを入力します。

設定を行ったら、画面上部の「Save」ボタンを押して変更した内容をAzure OpenAIに反映します。

PythonコードからAzure OpenAIを利用する

前回まではPythonのOpenAIライブラリを利用してAzure OpenAIにアクセスしていました。
今回は、Pythonのrequestsライブラリを利用して、Azure OpenAIにREST APIでアクセスします。

import os
import math
import json
import requests

def chat_to_ai():
  api_type = "azure"
  api_base = "https://xxxxxxxx.openai.azure.com"
  api_version = "2023-06-01-preview"
  api_key = os.getenv("OPENAI_API_KEY")
  deployment_id = "ChatTest"

  api_url = f'{api_base}/openai/deployments/{deployment_id}/chat/completions?api-version={api_version}'

  req_headers = {
    "Content-Type": "application/json",
    "api-key": f'{api_key}'
  }

  # 問い合わせ内容
  messages = [
      {
          "role":"system",
          "content":"You are an AI assistant that helps people find information."
      },
      {
          "role": "user",
          "content": "あなたは何ができますか?"
      }
  ]

  req_body = {
    "messages": messages
  }

  response = requests.post(api_url, headers=req_headers, data=json.dumps(req_body))
  if response.status_code == 200:
    # Azure OpenAIから正常応答が返ってきた場合は、レスポンスBodyをJSON形式に変換して返す
    return json.loads(response.text)
  else:
    # Azure OpenAIから正常応答が返ってこない場合は、Azure OpenAIのレスポンスと同じ構造でHTTPステータスコードを返す
    return {
      'choices': [
        {
          'message': {
            'content': f'error status: {response.status_code}'
          }
        }
      ]
    }

if __name__ == '__main__':
  ai_response = chat_to_ai()

  print(ai_response.get('choices', [{}])[0].get('message', {}).get('content', 'NO_CONTENT'))

このプログラムを、Azure OpenAIで接続元IPアドレスとして許可された外部ネットワークのマシンで実行します。
すると、実行結果としてAzure OpenAIからの結果が返ってきます。

私は、情報を検索する手助けをすることができます。
また、質問に答えたり、ニュースや天気予報を提供したり、リマインダーやスケジュール管理を行ったりすることも可能です。
さらに、翻訳や計算、単位変換などもお手伝いできます。
どのような情報をお探しですか?

同じプログラムを、接続元IPアドレスを許可していない外部ネットワークのマシンで実行するとエラーとなります。

error status: 403

②Azure内のプライベート通信でのアクセスのみ許可

Azure Portalから、作成してあるAzure OpenAIを選択します。

サイドメニューから「Networking」を選択すると、「Firewalls and virtual networks」タブで接続元IPアドレスの許可設定を行うことができます。
「無効」を選択すると、Azure OpenAIにアクセスするには「プライベートエンドポイントが必要」というメッセージが表示されます。
今回はアクセス制限を行うため、画面上部の「Save」ボタンを押して変更した内容をAzure OpenAIに反映します。

「Private endpoint connections」タブを選択すると、Azure OpenAIに対するプライベートエンドポイントを作成することができます。
「Private endpoint」を押すと、プライベートエンドポイントを作成するウィザード画面に変わります。

まず、プライベートエンドポイントの情報を入力します。

次に、プライベートエンドポイントの対象となるリソースを選択します。
ここでは、「対象サブリソース」として「account」を指定します。

次に、プライベートエンドポイントを配置するネットワークを選択します。

Azure内のサービスから、プライベートエンドポイントを使用するため、「プライベートDNSゾーンと統合する」で「はい」を選択します。

最後に、これまで入力した項目を確認して、「作成」ボタンを押すとプライベートエンドポイントが作成されます。


PythonコードからAzure OpenAIを利用する

先ほどのPythonコードを実行すると、どこで実行しても以下のようにエラーとなります。
これは、外部ネットワークからAzure OpenAIの利用を制限しているからです。

error status: 403


このままでは、Azure OpenAIが利用できないので、Azure内部でAzure OpenAIに要求を出すプログラムを動かします。

そのため、App Serviceを作成して、App ServiceからAzure OpenAIに要求を出すようにします。
App Serviceを作成するには、公式のクイックスタートを参照してください。
learn.microsoft.com


このアプリケーションに、先ほどのAzure OpenAIに要求を出すプログラムを組み込むことで、App ServiceからAzure OpenAIに要求を出すことができるようになります。
組み込んだアプリケーションで、Azure OpenAIからの結果を表示させると、以下のようにAzure OpenAIから正常応答が返ってくることが分かります。

私は、情報を検索する手助けをすることができます。
また、質問に答えたり、ニュースや天気予報を提供したり、リマインダーやスケジュール管理を行ったりすることも可能です。
さらに、翻訳や計算、単位変換などもお手伝いできます。
どのような情報をお探しですか?

まとめ

Azure OpenAIに対して利用できるネットワークを制限する方法を確認しました。
制限の方法は2通りありますが、どちらを利用するかは利用に関する要件とコストを比較して決定することになります。



Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Kaggle Grandmasterと一緒に働きたエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの採用 - Wantedlywww.wantedly.com