APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Azure OpenAI ServiceのAPIキーを無効化する

はじめに

こんにちは、ACS事業部の吉川です。
みなさま、Azure OpenAI Service、お使いになられていますでしょうか。
これまでAzureを使ってこなかった方も、Azure OpenAIの登場によりAzureを使い始めたという声を耳にします。
そんなAzure OpenAIを安全に活用する上での、ちょっとした小ネタをお届けします。

Azure OpenAIのアクセス制御の種類

Azure OpenAIを利用する場合のアクセス制御の種類として、以下の2種類の方法が存在します。

  • APIキーによるアクセス制御
  • Azure RBACによるアクセス制御

それぞれの使い方を簡単に見ていきましょう。

APIキーによるアクセス制御

まずAPIキーによるアクセス制御です。こちらはAzure OpenAIのAPIを呼び出す際に、固有のAPIキーを利用して認証する方法です。
ポータルの キーとエンドポイント から確認できるキーがそれにあたります。

Mcirosoffのドキュメントにあるコード例でも、APIキーを利用したパターンが多く紹介されています。
以下のドキュメントに記載されているコードを引用します。

learn.microsoft.com

import os
import openai
openai.api_type = "azure"
openai.api_version = "2023-05-15" 
openai.api_base = os.getenv("OPENAI_API_BASE")  # Your Azure OpenAI resource's endpoint value.
openai.api_key = os.getenv("OPENAI_API_KEY")

response = openai.ChatCompletion.create(
    engine="gpt-35-turbo", # The deployment name you chose when you deployed the GPT-35-Turbo or GPT-4 model.
    messages=[
        {"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
        {"role": "user", "content": "Who were the founders of Microsoft?"}
    ]
)

print(response)

print(response['choices'][0]['message']['content'])

環境変数 OPENAI_API_BASE にエンドポイントとなるURLを、OPENAI_API_KEY にAPIキーを設定して実行します。
ポータルにはキーが2つ表示されていますが、どちらを使っても構いません。キーをローテーション(再生成)する際にサービスを停止させないため、2つのキーが用意されています。
キー1を再生成する前にはアプリ側でキー2を利用するように変更、キー1の再生成が終わったらアプリ側でキー1を利用するようにしてキー2を再生成、といった形でローテーションしていきます。ローテーションを自動化するような仕組みは提供されておらず、手動で行う必要があります。

Azure RBACによるアクセス制御

Azure RBACによるアクセス制御は、API利用設定をロールベースのアクセス制御で行う方式です。Entra(Azure AD)テナントに存在するユーザー・サービスプリンシパル・マネージドIDといったオブジェクトに対し、役割(ロール)を設定することでそれぞれのオブジェクトごとにアクセス許可を与えていきます。

learn.microsoft.com

learn.microsoft.com

Azure内でアプリケーションをホストする場合に一般的な マネージドID を利用する方法をベースに設定方法を確認してみましょう。今回は仮想マシン(VM)をAzure OpenAIのクライアントとして例示しますが、App ServiceなどのPaaSでも設定方法は殆ど同じです。
ポータルで該当のVMを開き、左メニューから ID をクリックし システム割り当て済み の状態を オン に変更し保存します。これでVMの マネージドID がEntra(Azure AD)テナントに登録されます。

続いてAOAIのリソースを開き、左メニューの アクセス制御(IAM) からロールの割り当ての追加を行います。

割り当てるロールとして Cognitive Services OpenAI User を選び、

割当先のIDとして先ほど有効化したVMのマネージドIDを選択します。このまま割り当てを完了させると、VMのマネージドIDに対しCognitive Services OpenAI Userロールが割り当たります。AWSで言うとEC2にIAMロールをアタッチするようなものですね。

このVM上からマネージドIDを利用してAzure OpenAIを利用してみましょう。先のAPIキーのパターンで例示したPythonコードをAzure RBAC用に改変すると以下のようになります。

import os
import openai
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()
token = credential.get_token("https://cognitiveservices.azure.com/.default")

openai.api_type = "azure_ad"
openai.api_version = "2023-05-15"
openai.api_base = os.getenv("OPENAI_API_BASE")  # Your Azure OpenAI resource's endpoint value.
openai.api_key = token.token

response = openai.ChatCompletion.create(
    engine="gpt-35-turbo", # The deployment name you chose when you deployed the GPT-35-Turbo or GPT-4 model.
    messages=[
        {"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
        {"role": "user", "content": "Who were the founders of Microsoft?"}
    ]
)

print(response)

print(response['choices'][0]['message']['content'])

変更点は以下のとおりです。

  • Azure認証用パッケージである azure-identity を追加
  • azure-identityの DefaultAzureCredential() を利用して認証用トークンを取得、OpenAIのAPIキーとしてセットする
  • openai.api_type の値を "azure_ad" に変更

これだけの変更で、VMのマネージドIDを利用して認証を行い、その権限でAzure OpenAIのAPIを利用できます。

どちらの方式がいい?

2つのアクセス制御方式を紹介しましたが、どちらを利用するのがよいでしょうか。
APIキーの場合、Azure OpenAIリソースに対し共通のAPIキーを用いて認証することとなります。認証レベルで利用元ユーザー・アプリケーションを区別することはできませんし、キーのローテーション時にはすべてのユーザー・アプリケーションが等しく影響を受けます。
一方Azure RBAC方式であれば、ユーザー・アプリケーションごとに個別に権限を設定できます。認証部分はEntra(Azure AD) に任せることができますし、マネージドIDを利用すればパスワード・シークレットの管理も不要となります。
このことから、ごく小規模な利用であればAPIキーでもよいですが、ある程度の規模で利用する場合にはAzure RBACをお勧めします。

APIキーを無効化する

ここからが本記事の本題です。
前項の話でAzure RBACを使おう!と決定した場合、APIキーはどうすればよいでしょうか?Azure OpenAIリソースを作成した際にAPIキーは勝手に作られているものですし、ポータルを見ても削除といった項目はありません。組織内で使わないということにして放置しておいてもでもいいのですが、認証できてしまうAPIキーが存在しているという状態はよくないですね。

こういった状況に備えてか、実はREST APIのオプションの中にAPIキーを無効化するオプションがひっそりと存在しています。以下ドキュメントの AccountProperties の項にある disableLocalAuth がそれです。

learn.microsoft.com

いまのところ、ポータルでもAzure CLIでも操作できず、REST APIのみ準備されたオプションのようです。
AzureのREST APIを実行するにはAzure CLIの az rest を利用すると便利です。

# Azure OpenAIリソースの存在するリソースグループ名とAzure OpenAIリソース名を指定する
RG_NAME=rg-sample
AOAI_NAME=aoai-sample

# APIキーの無効化
az rest -m patch --uri /subscriptions/{subscriptionId}/resourceGroups/${RG_NAME}/providers/Microsoft.CognitiveServices/accounts/${AOAI_NAME}?api-version=2023-05-01 \
  --body "{\"properties\": {\"disableLocalAuth\":\"true\"}}"

これを実行した後にポータルからAPIキーの表示をしようとすると、以下のように表示されなくなります。

もちろんAPIキーを用いた認証もできなくなります。

$ python3 aoai.py
Traceback (most recent call last):
~中略~
openai.error.PermissionError: Key based authentication is disabled for this resource.

おわりに

Azure OpenAIを安全に使うために、APIキーを無効化するというテクニックの紹介でした。
ここまでしなくてもアクセスできるネットワークを限定するだけでも十分セキュアだとは思いますが、どうしてもAPIキーを無効化したい方は参考にしてみてください。

【PR】
私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: 吉川 俊甫
AOAIもぼちぼちやってます。2023/06に Microsoft MVP (Microsoft Azure) を受賞しました。
Shunsuke Yoshikawa - Credly