「Microsoft Azure documentation update: Harden credential handling in mcp-setup and natural-language-querying skills」は、Azure DocumentDB Agent Kitを使う管理者・開発者にとって、すぐ確認すべきセキュリティ更新です。結論から言うと、今回の変更はデータベース本体の仕様変更ではなく、AIエージェントが接続文字列やサンプルデータ内の機密値をチャットや生成クエリに持ち込まないよう、2つのスキルの指示内容を強化するものです。特に、MCP経由でAzure DocumentDBを扱う環境、GitHub Copilot・Cursor・Claude CodeなどにAgent Skillsを導入している環境では、スキル更新、ローカルの認証情報管理、クエリ生成時のサンプルデータ取り扱いを見直す必要があります。
Microsoft Azureの「Harden credential handling in mcp-setup and natural-language-querying skills」で何が変わったのか
今回の更新対象は、Azure DocumentDB Agent Kit内の documentdb-mcp-setup と documentdb-natural-language-querying の2つです。公式PRでは、この2つのスキルが skills.sh により Snyk の「Insecure credential handling」ルールで High Risk と判定されていたこと、原因が「接続文字列をチャットで求める指示」と「サンプルドキュメント内の実データ値をLLM生成クエリや説明に入れ得る指示」にあったことが説明されています。(GitHub)
重要なのは、これはAzure DocumentDB MCPサーバーの実行機能そのものが変わる更新ではない点です。公式PRでも、問題は「documented MCP tool surface」の外でコードを実行するものではなく、あくまでスキルの指示内容に関するものだと説明されています。(GitHub)
| 対象スキル | 変更前のリスク | 今回の主な対策 |
|---|---|---|
documentdb-mcp-setup | エージェントがMongoDB互換の接続文字列をチャットで尋ねる可能性があった | 接続文字列、パスワード、トークンをチャットで受け取らないルールを追加 |
documentdb-natural-language-querying | サンプルドキュメント内のAPIキー、JWT、パスワード、PIIなどが生成クエリや説明に混入する可能性があった | サンプル値のコピー禁止、秘匿フィールドの除外、出力前の再チェックを追加 |
| MCPサーバー本体 | 今回のPRでは挙動変更の対象外 | 既存のMCPツール面は維持 |
| 他のスキル | 今回の直接修正対象外 | 公式PR上では他スキルはLow Risk扱いで未変更 |
影響を受ける人
今回の更新は、Azure DocumentDBをMCPやAIコーディングエージェントから利用しているチームに関係します。Azure DocumentDB Agent Kitは、Azure DocumentDB向けのAgent SkillsとMCPサーバーを束ねたキットで、Claude Code、Cursor、Codex、Gemini CLI、GitHub Copilot向けのプラグインマニフェストも含むと説明されています。(GitHub)
特に確認すべき対象は次の通りです。
| 立場 | 確認すべきこと |
|---|---|
| Azure管理者 | 接続文字列をチャット、Issue、Pull Request、ログに貼っていないか |
| 開発者 | Agent Kitを最新版に更新し、古いスキル指示が残っていないか |
| セキュリティ担当者 | Secret scanning、Push protection、リポジトリ内のシークレット検出を有効化しているか |
| AIエージェント運用担当 | LLMがサンプルデータ値をクエリ条件や説明に再利用しない設計になっているか |
| 内製スキル作成者 | 自社用に改変したスキルにも同じガードレールを反映しているか |
逆に、Azure DocumentDBのデータベースエンジン、既存コレクション、インデックス、通常のMongoDB互換クエリの仕様がこの更新だけで変わるわけではありません。公式PRでも、DocumentDB MCPサーバー自体の挙動は変更対象外とされています。(GitHub)
mcp-setupの変更点:接続文字列をチャットに貼らせない
documentdb-mcp-setup は、Azure DocumentDB MCPサーバーをエージェントクライアントで使うための設定を案内するスキルです。現在のスキル本文では、DocumentDBの接続文字列を「secret」と扱い、エージェントは接続文字列、パスワード、トークンなどの認証情報をチャットで求めてはいけないと明記されています。(GitHub)
実務上のポイントは、接続文字列の扱いを「エージェントに渡す」から「ユーザーがローカルで直接保存する」に変えることです。
変更前に起きやすかった失敗
たとえば、エージェントが次のように案内してしまうと危険です。
MongoDB互換の接続文字列をこのチャットに貼り付けてください。
この指示では、接続文字列がLLMの会話コンテキスト、チャット履歴、ログ、スクリーンショット、監査対象外の保存領域に残る可能性があります。Azure DocumentDBやMongoDB互換接続文字列にはユーザー名とパスワードが含まれることがあるため、単なる設定値ではなく認証情報として扱う必要があります。
更新後の正しい案内
更新後は、エージェントが接続文字列そのものを受け取るのではなく、形だけを説明し、実値はユーザーがローカル環境に直接保存します。
接続文字列はこのチャットに貼り付けないでください。
ローカルの ~/.documentdb-env を自分で開き、DOCUMENTDB_URI に実際の値を保存してください。
接続文字列の形を示す場合も、実値ではなくプレースホルダーを使います。
export DOCUMENTDB_URI="mongodb+srv://[USER]:[PASSWORD]@[HOST]/?tls=true&authMechanism=SCRAM-SHA-256"
スキル本文では、Azure DocumentDBの接続文字列をローカルの ~/.documentdb-env に保存し、権限を制限したうえでシェルプロファイルから読み込む流れも示されています。(GitHub)
chmod 600 ~/.documentdb-env
確認コマンドも、値そのものを表示しない形にする必要があります。
env | grep "^DOCUMENTDB_URI\|^TRANSPORT\|^HOST\|^PORT" | sed 's/DOCUMENTDB_URI=.*/DOCUMENTDB_URI=[set]/'
このように、設定確認では「設定されているか」だけを見ます。接続文字列の中身を標準出力に出してはいけません。
natural-language-queryingの変更点:サンプルデータの値を生成クエリに使わない
documentdb-natural-language-querying は、自然言語の依頼からAzure DocumentDB/MongoDB向けの読み取りクエリや集計パイプラインを生成するスキルです。スキルの説明では、コレクションスキーマやサンプルドキュメントを使って、読み取り用の find クエリやaggregation pipelineを生成するとされています。(GitHub)
ここで問題になるのは、スキーマ推定のために取得したサンプルドキュメントに、次のような値が含まれているケースです。
| データ例 | リスク |
|---|---|
passwordHash | ハッシュ値が説明文やクエリ例に出る |
apiKey | APIキーがLLMのコンテキストに残る |
jwt | JWTがフィルター条件として再利用される |
connectionString | 別システムへの接続情報が漏れる |
email、phone、ssn | PIIがサンプル出力や説明に混入する |
更新後のスキルでは、サンプルドキュメントから得た値を、生成クエリ、フィルター、$in 配列、正規表現、説明、コメントへそのままコピーしてはいけないと明記されています。値は「型」や「形」を推定するためだけに使い、具体的なリテラルはユーザーが依頼文で指定した値、またはプレースホルダーを使う設計です。(GitHub)
悪い例:サンプル値を勝手にクエリ条件へ入れる
{
"query": {
"filter": "{ email: '[email protected]', status: 'active' }"
}
}
この例では、ユーザーが [email protected] を指定していないのに、サンプルドキュメントから拾った値をクエリに使っています。これは、個人情報や機密値をLLM出力に混ぜる典型的な失敗です。
良い例:ユーザー指定値かプレースホルダーだけを使う
{
"query": {
"filter": "{ email: '<email_from_user>', status: 'active' }",
"limit": "10"
}
}
スキーマ推定では email が文字列であることを把握するだけにとどめ、具体的な値はユーザー入力またはプレースホルダーにします。
サンプル取得時のprojectionにも注意が必要
今回の更新で実務的に重要なのは、単に「エージェント側で赤字化する」だけでなく、可能な限りデータベース側で秘匿フィールドを取得しないようにしている点です。
PRのレビュー過程では、sample_documents に projection を渡してもMCPサーバー側で受け付けないため、秘匿フィールド除外が効かないという指摘がありました。最終的なスキルでは、sample_documents ではなく aggregate を使い、$sample と $project を組み合わせて秘匿フィールドを除外する形に修正されています。(GitHub)
aggregate({
db_name,
collection_name,
pipeline: [
{ $sample: { size: 5 } },
{
$project: {
password: 0,
passwd: 0,
pwd: 0,
secret: 0,
token: 0,
apiKey: 0,
api_key: 0,
accessKey: 0,
privateKey: 0,
client_secret: 0,
refresh_token: 0,
id_token: 0,
jwt: 0,
connectionString: 0,
ssn: 0,
creditCard: 0,
cvv: 0
}
}
]
})
また、find_documents では limit や projection をトップレベルに置くのではなく、options の中に入れる必要があると明記されています。(GitHub)
find_documents({
db_name,
collection_name,
query: {},
options: {
limit: 4,
projection: {
password: 0,
token: 0,
apiKey: 0,
secret: 0
}
}
})
ここは移行時に見落としやすいポイントです。自社でスキルやMCP呼び出しをカスタマイズしている場合、projection を書いているだけで安心せず、対象ツールのスキーマ上どこに渡すべきかを確認してください。誤った位置に指定すると、秘匿フィールドを除外しているつもりでも、実際にはサーバー側で無視される可能性があります。
管理者・開発者が確認すべき設定
Azure DocumentDB Agent KitのREADMEでは、GitHub由来のスキルインストールは自動更新されず、更新時は npx skills add Azure/documentdb-agent-kit を再実行する方法が推奨されています。(GitHub)
まずは、次の順番で確認すると安全です。
| 確認項目 | 判断基準 | 対応 |
|---|---|---|
| スキルが最新版か | 古い mcp-setup や natural-language-querying が残っていないか | Agent Kitを再取得し、ローカルのスキルファイルを更新 |
| 接続文字列の保管場所 | チャット、README、Issue、PR、ログに実値がないか | ローカルの環境変数ファイルや安全なシークレット管理へ移す |
| エージェントの応答 | 接続文字列の貼り付けを求めていないか | 「チャットに貼らない」案内へ修正 |
| サンプル取得 | 秘匿フィールドをDB側で除外しているか | aggregate + $project、または正しい options.projection を使う |
| 生成クエリ | サンプル値がフィルターや説明に混じっていないか | ユーザー指定値かプレースホルダーのみを許可 |
| リポジトリ保護 | シークレットのpushを防げるか | Secret scanningとPush protectionを有効化 |
GitHubを使っている場合は、Secret scanningとPush protectionも併せて確認してください。GitHubの公式ドキュメントでは、Secret scanningはリポジトリの履歴からAPIキー、パスワード、トークンなどのハードコードされた認証情報を検出し、Push protectionはシークレットを含むpushをリポジトリ到達前にブロックする機能と説明されています。(GitHub Docs) (GitHub Docs)
移行時に失敗しやすいポイント
チャットに貼られた接続文字列を「確認だけ」と考えてしまう
接続できない原因を調べるとき、つい「接続文字列を見せてください」と言いたくなります。しかし今回の更新では、その行為自体を避ける設計になっています。
接続できない場合は、接続文字列の実値ではなく、次の項目だけをローカルで確認してもらいます。
| 確認内容 | チャットで共有してよい情報 |
|---|---|
DOCUMENTDB_URI が設定されているか | DOCUMENTDB_URI=[set] のようなマスク済み結果 |
| TLS指定があるか | tls=true を含めたかどうかのYes/No |
| ユーザー名・パスワードが正しいか | 「Azureポータルで再確認した」などの状態 |
| ネットワーク制限 | 許可IP、ファイアウォール、Private Endpointの設定状況 |
| 認証エラー | エラーメッセージから認証失敗か接続失敗かを分類した結果 |
誤って接続文字列を貼ってしまった場合は、その値を処理せず、チャット履歴から削除し、必要に応じて該当資格情報をローテーションするのが安全です。スキル本文でも、エージェントは貼られた認証情報を読み上げたり、ログに出したり、ファイルに書いたりしてはいけないと定めています。(GitHub)
「ユーザーが明示的に見たいデータ」と「エージェントが推定用に拾ったデータ」を混同する
natural-language-querying の更新では、サンプル値の取り扱いが細かく分けられています。スキーマ推定のためにエージェントが取得した値は、生成クエリや説明にコピーしてはいけません。一方で、ユーザーが明示的に「最新の注文10件を見たい」「代表的なユーザードキュメントを表示したい」と依頼した場合は、MCPツールが結果を返すこと自体はブロックしない設計です。(GitHub)
ただし、返された結果に token や jwt のような秘匿値らしきフィールドが含まれる場合は、意図して表示しているか注意喚起する必要があります。これはDLP製品のように全データ流出を完全に止める機能ではなく、LLMが不要に機密値を文脈へ取り込むリスクを減らすためのガードレールです。
フィールド名のブロックリストを雑に使う
今回の更新では、password、secret、apiKey、jwt、connectionString などの明確な秘匿フィールドを除外対象にしています。一方で、auth、session、cookie、pin、dsn のような語は誤検出しやすいため、部分一致ではなく単語単位で扱う方向に調整されています。PRレビューでも、auth が author に、pin が shipping_zip などに誤って一致するリスクが指摘されていました。(GitHub)
自社のデータモデルに合わせて、次のように分類しておくと運用しやすくなります。
| 分類 | 例 | 推奨対応 |
|---|---|---|
| 常に秘匿扱い | password、secret、privateKey、client_secret | サンプル取得時点で除外 |
| 値を見て判断 | session、auth、cookie | フィールド名だけでなく値パターンも確認 |
| 業務上よく使う非秘匿語 | author、session_count、pinned | 誤除外しないようテスト |
| PIIの可能性が高い | email、phone、ssn | 出力目的を確認し、必要最小限にする |
展開前に行うべきテスト
本番チームに展開する前に、次のテストを行うと問題を早く見つけられます。
| テスト | 期待される結果 |
|---|---|
| エージェントに「接続文字列はどこに貼ればよいか」と聞く | チャットへ貼らず、ローカルファイルへ保存する案内になる |
| ダミーの接続文字列を貼ってみる | 値を処理せず、削除とローカル設定を促す |
password や token を含むサンプルドキュメントでクエリ生成する | それらの値が生成クエリや説明に出ない |
author、session_count、pinned を含むコレクションでスキーマ推定する | 誤って全て秘匿フィールド扱いにならない |
| ユーザーが明示的に指定したリテラルで検索する | ユーザー指定値は使われ、サンプル値は使われない |
projection の位置を間違えた呼び出しを検出する | options.projection または aggregate + $project に修正される |
| GitHubにダミーのシークレット風文字列をpushしようとする | Push protectionが有効ならブロックまたは警告される |
GitHubのPush protectionは、コマンドラインからのpush、GitHub UIで作成されたコミット、ファイルアップロード、REST API経由の操作などで検出されたシークレットをブロックできると説明されています。(GitHub Docs)
今回の更新で変わらないこと
今回のドキュメント更新は重要ですが、万能なセキュリティ対策ではありません。次の点は別途対応が必要です。
| 変わらないこと | 必要な対応 |
|---|---|
| 既に漏れた接続文字列は無効化されない | 影響が疑われる資格情報をローテーションする |
| チャット履歴に残った情報は自動削除されない | ユーザー側で削除し、再発防止ルールを整備する |
| MCPサーバー本体の権限は自動で最小化されない | Azure側のRBAC、ネットワーク制限、実行環境の権限を確認する |
| すべての機密データが完全に検出されるわけではない | 自社固有のフィールド名や値パターンを追加する |
| Gitリポジトリへの誤コミットはこのスキルだけでは防げない | Secret scanning、Push protection、pre-commitフックを併用する |
特に、接続文字列を一度でもチャットやGit履歴に貼った場合は、「削除したから安全」と判断しないことが大切です。値が外部に残っている可能性があるため、該当するユーザー、パスワード、キーを再発行し、旧値を無効化する運用まで含めて対応してください。
まず行うべき対応
今回のMicrosoft Azure関連ドキュメント更新を受けて、管理者や開発者が最初に行うべきことは明確です。
まず、Azure DocumentDB Agent Kitを更新し、古い mcp-setup と natural-language-querying の指示が残っていないか確認します。次に、接続文字列をチャットに貼らせる運用を廃止し、ローカルの環境変数ファイルやシークレット管理へ移します。そのうえで、自然言語クエリ生成時にサンプル値がフィルター、説明、正規表現、$in 配列へ混入しないかをテストします。
最後に、GitHubなどのリポジトリ側でSecret scanningとPush protectionを有効化し、スキルだけに頼らない多層防御にしてください。今回の更新は、AIエージェント時代のAzure運用で見落とされがちな「チャット経由の認証情報漏えい」と「サンプルデータ経由の機密値混入」を防ぐための実務的な修正です。使っているチームほど、早めに更新と運用ルールの見直しを進めるべきです。

コメント