Azure Storageの接続文字列、アカウントキー、SAS、APIキーを開発中にどこへ保存すべきか迷う場合、結論は明確です。ASP.NET Coreの開発環境ではSecret Managerを使い、本番・検証環境ではAzure Key VaultやMicrosoft Entra ID/マネージドIDへ移行するのが基本です。2026年5月20日に更新されたMicrosoft Learnの「Safe storage of app secrets in development」は、Azure Storage自体の仕様変更というより、開発中のシークレットをソースコードやappsettings.jsonへ置かないための実務的な確認ポイントを整理した内容です。(Microsoft Learn)
Azure Storageを使うASP.NET Coreアプリでは、ローカル開発、CI/CD、Azure App Service、Functions、コンテナー環境でシークレットの置き場所が変わります。この記事では、今回の公式情報で確認すべき変更点、影響範囲、管理者・開発者が見直すべき設定、移行時の注意点を実務目線で整理します。
Azure Storageの「Safe storage of app secrets in development」は何が変わるのか
今回確認すべきポイントは、「Azure Storageに新しい認証機能が追加された」という話ではありません。中心は、ASP.NET Coreアプリの開発中に扱うシークレットを、どのように安全に保存・取得するかです。
Microsoft Learnの該当記事は、開発マシン上のASP.NET Coreアプリで機密情報を管理する方法を説明しており、パスワードなどのシークレットをソースコードや構成ファイルに保存しないこと、本番用シークレットを開発・テストに使わないこと、デプロイ時にシークレットをアプリへ同梱しないことを明記しています。(Microsoft Learn)
Azure Storageの文脈では、特に次の値が対象になります。
| 対象になりやすい値 | 例 | 推奨される扱い |
|---|---|---|
| ストレージアカウント接続文字列 | DefaultEndpointsProtocol=https;AccountName=...;AccountKey=... | 可能なら使わず、Microsoft Entra ID認証へ移行。開発中に必要な場合はSecret Managerなどへ保存 |
| アカウントキー | AccountKey=... | 強い権限を持つため、平文保存や共有を避ける |
| SASトークン | ?sv=...&sig=... | 期限・権限・対象範囲を絞る。Blobでは可能ならユーザー委任SASを検討 |
| 外部APIキー | 画像変換API、通知APIなど | 開発中はSecret Manager、本番はKey Vaultなどで管理 |
| Azurite用の接続設定 | UseDevelopmentStorage=true | ローカル検証専用。本番データや本番キーと混在させない |
重要なのは、Secret Managerは「開発時の置き場所」であって、「本番の秘密情報保管庫」ではない点です。公式情報でも、Secret Managerは保存されたシークレットを暗号化せず、信頼済みストアとして扱うべきではないと説明されています。(Microsoft Learn)
今回の公式更新で押さえるべき実務上の変更点
2026年5月20日の更新は、内容の「刷新・整理」に近い位置づけです。GitHub上の履歴では、同日のコミットが「Light Freshness Edit」として記録され、ASP.NET Coreのセキュリティ関連トピックが更新されています。(GitHub)
管理者や開発者が実務で受け止めるべき変更点は、次の3つです。
Secret Managerの位置づけがより明確になった
Secret Managerは、ASP.NET Coreアプリの開発中にシークレットをプロジェクトツリーの外へ保存するためのツールです。UserSecretsIdに紐づくJSONファイルへ値を保存し、Gitなどのソース管理に含めない運用を前提とします。(Microsoft Learn)
ただし、暗号化された保管庫ではありません。開発者の端末が侵害された場合、シークレットが漏えいする可能性があります。そのため、Azure Storageの本番アカウントキーや長期間有効なSASを、安易に開発用Secret Managerへ入れる運用は避けるべきです。
appsettings.jsonにパスワードやキーを入れない方針が再確認された
公式記事では、appsettings.jsonのようにリポジトリへチェックインされ得る構成ファイルへ、パスワードなどのシークレットを保存しないよう示しています。接続文字列にパスワードを直接含めるのではなく、必要な値だけをシークレットとして保存し、実行時に組み立てる例も示されています。(Microsoft Learn)
Azure Storageの場合、次のような設定は危険です。
{
"AzureStorage": {
"ConnectionString": "DefaultEndpointsProtocol=https;AccountName=prodstore;AccountKey=xxxxx;EndpointSuffix=core.windows.net"
}
}
安全な方向へ寄せるなら、少なくとも開発環境では次のように構成を分離します。
{
"AzureStorage": {
"AccountName": "devstore001",
"BlobContainerName": "uploads"
}
}
接続文字列やキーが必要な場合は、Secret Managerへ保存します。
dotnet user-secrets set "AzureStorage:ConnectionString" "DefaultEndpointsProtocol=https;AccountName=devstore001;AccountKey=..."
ただし、より望ましいのは接続文字列依存を減らし、Microsoft Entra IDとAzure Identityを使う設計へ移行することです。
開発環境と本番環境の分離がより重要になった
公式情報では、本番用シークレットを開発やテストに使わないこと、本番シークレットをアプリと一緒にデプロイしないことが明記されています。(Microsoft Learn)
Azure Storageでは、次のような運用が事故につながります。
| NG運用 | 起きやすい問題 |
|---|---|
| 開発者全員で本番ストレージの接続文字列を共有する | 誤削除、誤アップロード、漏えい時の影響拡大 |
| 本番SASをローカル検証に使い回す | 期限切れ忘れ、権限過多、ログからの漏えい |
appsettings.Development.jsonにアカウントキーを書く | リポジトリ誤コミットで外部流出 |
| テスト用と本番用を同じKey Vaultに入れる | 権限設計が複雑になり、誤参照が起きやすい |
開発用ストレージアカウント、検証用ストレージアカウント、本番用ストレージアカウントは分けるのが基本です。加えて、Key Vaultも環境ごとに分けると、アクセス権限と監査が整理しやすくなります。
対象者:誰が何を確認すべきか
今回の内容は、ASP.NET CoreでAzure Storageを使う開発者だけでなく、クラウド管理者、セキュリティ担当者、CI/CD担当者にも関係します。
| 立場 | 確認すべきこと | 具体的なアクション |
|---|---|---|
| 開発者 | ローカル開発でキーをどこに保存しているか | appsettings*.json、.env、サンプルコード、READMEを確認 |
| Azure管理者 | ストレージアカウントキーの利用状況 | 共有キー認証の必要性、RBAC、マネージドID対応状況を確認 |
| セキュリティ担当者 | 本番シークレットの配布経路 | チャット、メール、Wiki、CI/CD変数の棚卸し |
| DevOps担当者 | パイプラインでのシークレット注入方法 | GitHub Actions、Azure DevOps、App Service設定、Key Vault参照を確認 |
| テックリード | 認証方式の標準化 | 接続文字列方式からMicrosoft Entra ID認証への移行計画を作成 |
特に注意すべきなのは、「開発時だけだから問題ない」という判断です。開発端末、検証環境、CI/CDログから漏えいした資格情報が、本番ストレージにアクセスできる状態であれば、影響範囲は本番障害と同じになります。
Azure Storageで見直すべきシークレット管理の優先順位
Azure Storageのシークレット管理は、単に「Secret Managerを使うかどうか」ではなく、そもそも保存すべきシークレットを減らすことから考えるべきです。
優先順位は「キーを保存しない」から始める
Microsoftは、Blob、Queue、Tableデータへの要求について、可能な場合はMicrosoft Entra IDとマネージドIDを使うことを推奨しています。また、Shared Key認証よりもMicrosoft Entra IDとマネージドIDの方がセキュリティと使いやすさの面で優れていると説明しています。(Microsoft Learn)
実務では、次の順で検討します。
| 優先度 | 認証方式 | 向いている場面 | 注意点 |
|---|---|---|---|
| 高 | Microsoft Entra ID + マネージドID | Azure App Service、Functions、VM、コンテナーアプリなど | RBACロール付与が必要 |
| 高 | Microsoft Entra ID + 開発者アカウント | ローカル開発 | 開発者に必要最小限のBlob Dataロールを付与 |
| 中 | ユーザー委任SAS | Blobへの一時的な委任アクセス | Blob中心。期限と権限の設計が必要 |
| 低 | 接続文字列/アカウントキー | レガシーコード、移行途中、非対応サービス | 漏えい時の影響が大きい |
| ローカル限定 | Azurite | ローカルでの動作確認 | 本番相当のセキュリティ検証には不向き |
接続文字列は便利ですが、Azure Storageの接続文字列には実行時アクセスに必要な認可情報が含まれることがあります。公式情報でも、アカウントキーや接続文字列を平文で保存することはセキュリティリスクであり、推奨されないと説明されています。(Microsoft Learn)
開発環境でSecret Managerを使う手順
ASP.NET CoreアプリでAzure Storageの接続文字列や一時的な開発用キーを扱う場合、Secret Managerは手軽な第一歩です。
Secret Managerを有効化する
プロジェクトのルートで次のコマンドを実行します。
dotnet user-secrets init
このコマンドにより、プロジェクトファイルへUserSecretsIdが追加されます。公式情報では、UserSecretsIdの値は既定でGUIDになり、プロジェクトごとに一意であることが説明されています。(Microsoft Learn)
Azure Storage用の値を保存する
接続文字列を保存する場合は、次のように階層キーを使います。
dotnet user-secrets set "AzureStorage:ConnectionString" "DefaultEndpointsProtocol=https;AccountName=devstore001;AccountKey=..."
Blobコンテナー名など、機密ではない値はappsettings.Development.jsonに置いても構いません。
{
"AzureStorage": {
"BlobContainerName": "uploads-dev"
}
}
接続文字列だけをSecret Managerへ逃がすことで、リポジトリへ誤ってキーを含めるリスクを下げられます。
アプリから読み取る
ASP.NET Coreでは、構成APIから値を取得します。
var builder = WebApplication.CreateBuilder(args);
var storageConnectionString =
builder.Configuration["AzureStorage:ConnectionString"];
var containerName =
builder.Configuration["AzureStorage:BlobContainerName"];
Secret Managerの値は、Development環境で構成ソースとして読み込まれます。ASP.NET Core Webアプリでは、WebApplication.CreateBuilderなどの既定構成により、Development環境でユーザーシークレットが扱われます。(Microsoft Learn)
保存済みシークレットを確認・削除する
保存した値は次のコマンドで確認できます。
dotnet user-secrets list
不要になった値は削除します。
dotnet user-secrets remove "AzureStorage:ConnectionString"
全削除する場合は次のコマンドです。
dotnet user-secrets clear
開発者が退職・異動した場合や、検証用ストレージアカウントを作り直した場合は、Secret Manager内の古いキーも消す運用にしておくと安全です。
本番環境ではAzure Key Vaultへ移行する
Secret Managerは開発用です。本番・検証・ステージング環境では、Azure Key VaultやマネージドIDを使って、アプリが必要な値を実行時に取得する構成へ移行します。
Azure Key Vault configuration providerは、Key Vaultのシークレットからアプリ構成値を読み込むための仕組みです。公式情報では、ASP.NET CoreアプリでKey Vaultのシークレットを構成値として読み込む方法、必要なパッケージとしてAzure.Extensions.AspNetCore.Configuration.SecretsとAzure.Identityを追加することが説明されています。(Microsoft Learn)
本番移行時の基本方針
| 項目 | 開発環境 | 本番・検証環境 |
|---|---|---|
| シークレット保存先 | Secret Manager | Azure Key Vault |
| 認証 | 開発者アカウント、開発用サービスプリンシパルなど | マネージドID推奨 |
| Azure Storageアクセス | 可能ならMicrosoft Entra ID | Microsoft Entra ID + RBACを優先 |
| 接続文字列 | 移行中のみ最小限 | 可能な限り廃止またはKey Vault管理 |
| ローテーション | 手動になりがち | Key Vault、運用手順、監査ログで管理 |
Key Vault側では、階層構造を表すキー名に注意が必要です。ASP.NET Core構成では:を階層区切りに使いますが、Key Vaultのシークレット名ではコロンを使えないため、公式情報では--を区切りとして使い、読み込み時にコロンへ置き換える方法が説明されています。(Microsoft Learn)
例として、開発環境で次のキーを使っている場合、
dotnet user-secrets set "AzureStorage:BlobContainerName" "uploads"
Key Vaultでは次のような名前で保存します。
az keyvault secret set \
--vault-name my-kv-prod \
--name "AzureStorage--BlobContainerName" \
--value "uploads"
管理者が確認すべきAzure Storage側の設定
Azure Storage側では、「アプリのシークレットをどこに置くか」だけでなく、「そのシークレットがどれほど強い権限を持つか」を確認する必要があります。
Shared Key認証を使い続ける必要があるか
Azure Storageでは、既定でMicrosoft Entra資格情報またはアカウントアクセスキーによるShared Key認証で要求を認可できます。公式情報では、Microsoft Entra IDがShared Keyよりも優れたセキュリティと使いやすさを提供するとされ、Shared Key認証を無効化できることも説明されています。(Microsoft Learn)
ただし、Shared Keyを無効化すると、アカウントSASやサービスSAS、古いツール、Azure Files関連の一部運用に影響する場合があります。公式情報でも、Shared Keyを無効化する前に互換性やAzure Filesワークロードへの影響を確認する必要があると説明されています。(Microsoft Learn)
確認すべき項目は次のとおりです。
| 確認項目 | 見るべきポイント |
|---|---|
| アプリコード | AccountKey=、UseDevelopmentStorage=true、SAS文字列を検索 |
| Azureポータル | ストレージアカウントのアクセスキー利用状況、診断ログ |
| CI/CD | パイプライン変数に接続文字列が保存されていないか |
| Storage ExplorerやAzCopy | Microsoft Entra ID認証へ切り替えられるか |
| Azure Files | SMB/RESTの認証方式に影響がないか |
| 外部連携 | 取引先や外部システムがSASやアカウントキーに依存していないか |
RBACを最小権限にする
Microsoft Entra IDでAzure Storageへアクセスする場合、対象のユーザー、アプリ、マネージドIDにAzure RBACロールを割り当てます。Blobデータへのアクセスでは、管理系ロールだけではデータアクセスができない場合があり、Storage Blob Data ReaderやStorage Blob Data Contributorなどのデータアクセス用ロールを検討します。(Microsoft Learn)
開発者全員に広い権限を付けるのではなく、次のように分けます。
| 利用者 | 推奨される権限の考え方 |
|---|---|
| 読み取りだけの開発者 | 対象コンテナー単位で読み取り権限 |
| アップロード機能を開発する担当者 | 開発用ストレージに限定して書き込み権限 |
| 本番運用担当 | 必要な期間・範囲に限定して権限付与 |
| アプリ本体 | マネージドIDに必要最小限のデータアクセス権 |
| CI/CD | デプロイに必要な管理権限と、データアクセス権を分離 |
RBACの反映には時間がかかる場合があります。権限を付けた直後にAuthorizationPermissionMismatchなどのエラーが出る場合は、ロールのスコープ、対象ID、伝播待ち、拒否割り当ての有無を確認します。
開発者が失敗しやすいポイント
Azure Storageのシークレット管理では、設定自体よりも運用上の小さなミスが事故につながります。
appsettings.Development.jsonなら安全だと思い込む
appsettings.Development.jsonは開発用ファイルですが、リポジトリに含まれている場合があります。そこへ接続文字列やSASを書くと、レビュー漏れやブランチ共有で漏えいします。
安全な判断基準は単純です。
リポジトリに入る可能性があるファイルには、キー・パスワード・SAS・トークンを書かない。
環境変数を過信する
環境変数は、コードやローカル構成ファイルにシークレットを置かないために使えます。ただし、公式情報では、環境変数は一般に平文で保存され、端末やプロセスが侵害された場合に信頼できない第三者からアクセスされる可能性があると説明されています。(Microsoft Learn)
特に開発端末では、シェル履歴、プロセス一覧、ターミナルログ、IDEの設定同期に注意が必要です。
:と__の違いで設定が読めない
ASP.NET Coreの階層キーではAzureStorage:ConnectionStringのようにコロンを使います。一方、環境変数ではプラットフォームによってコロンが扱えないため、二重アンダースコア__を使います。公式情報でも、__はすべてのプラットフォームでサポートされ、コロンへ置き換えられると説明されています。(Microsoft Learn)
環境変数で設定する場合は、次のようにします。
AzureStorage__ConnectionString="DefaultEndpointsProtocol=https;AccountName=..."
Key Vaultでは__ではなく、通常は--を使います。
AzureStorage--ConnectionString
この違いを混同すると、ローカルでは動くのに本番で値が読めない、という障害が起きます。
Secret Managerをチーム共有の保管庫として使う
Secret Managerは各開発者のユーザープロファイル配下に保存されます。チーム全員で同じ値を共有したい場合でも、Secret Managerのファイルをコピーして配布するのは避けるべきです。
代わりに、次のような方法を検討します。
| 目的 | 推奨される方法 |
|---|---|
| 開発者ごとにローカル値を持たせる | Secret Managerへ各自で設定 |
| 共通の開発用設定を配布する | 機密でない値だけREADMEやサンプルJSONに記載 |
| 開発用シークレットを安全に配る | Key Vault、組織のシークレット管理ツール、権限付き手順書を利用 |
| 本番値を参照させる | 原則として開発者へ直接配布しない |
移行時のチェックリスト
既存のAzure Storage連携アプリを見直す場合、いきなり全面移行するより、漏えいリスクが高い箇所から順に潰す方が現実的です。
| 手順 | 作業 | 判断基準 |
|---|---|---|
| 1 | リポジトリ内を検索 | AccountKey=, BlobEndpoint=, sig=, DefaultEndpointsProtocol=を検索 |
| 2 | 接続文字列の保存先を確認 | appsettings*.json、.env、CI/CD変数、Wiki、READMEを確認 |
| 3 | 開発用と本番用を分離 | 本番ストレージキーが開発端末に存在しない状態を目指す |
| 4 | Secret Managerへ移す | ローカル開発で必要な値だけ保存 |
| 5 | Microsoft Entra ID認証を検証 | Azure SDK + DefaultAzureCredentialで動作確認 |
| 6 | RBACを設定 | アプリのマネージドIDに必要最小限のロールを付与 |
| 7 | Key Vaultへ移行 | 本番・検証シークレットをKey Vaultで管理 |
| 8 | Shared Key依存を棚卸し | 無効化できるストレージアカウントから段階的に対応 |
| 9 | 古いキーをローテーション | 漏えい可能性があるキーは再生成 |
| 10 | ログと監査を確認 | SAS、Shared Key、Microsoft Entra IDの利用状況を監視 |
最初の一歩としては、リポジトリ検索が最も効果的です。接続文字列やキーが見つかった場合は、削除するだけでは不十分です。すでにコミット履歴に残っている可能性があるため、該当するAzure StorageのアカウントキーやSASをローテーションする必要があります。
展開時に注意すべきポイント
Azure Storageのシークレット管理は、ローカル開発で完結しません。App Service、Azure Functions、コンテナー、Azure Kubernetes Service、GitHub Actions、Azure DevOpsなど、実行環境ごとにシークレット注入の方法が変わります。
App ServiceやFunctionsではアプリ設定とKey Vault参照を使い分ける
短期的には、App Serviceのアプリケーション設定に接続文字列や環境変数を置く運用もあります。ただし、本番シークレットを長期的に安全管理するなら、Key Vault参照やマネージドIDを組み合わせる方が望ましいです。
構成の考え方は次のとおりです。
| 値の種類 | 保存先の例 |
|---|---|
| コンテナー名、リージョン、機能フラグ | App Service設定、通常の構成ファイル |
| 接続文字列、APIキー、SAS | Key Vault |
| Azure Storageへのアクセス権 | マネージドID + Azure RBAC |
| ローカル開発用の一時値 | Secret Manager |
DefaultAzureCredentialの動作を理解する
Azure Identityを使う場合、DefaultAzureCredentialはローカル開発とAzure上の実行環境の両方で使いやすい選択肢です。公式情報でも、Azure Identityクライアントライブラリは開発環境とAzure上で同じコードによりアクセストークンを取得でき、DefaultAzureCredentialは複数の資格情報を順に試すと説明されています。(Microsoft Learn)
ただし、本番で意図しない資格情報が使われないよう、実行環境、マネージドID、RBACロール、環境変数を明確に設計してください。公式情報では、Key Vault providerの例において、開発とAzureホスティング環境の資格情報を組み合わせるためにDefaultAzureCredentialを使える一方、本番移行時にはManagedIdentityCredentialなど別の選択肢が適する場合があると説明されています。(Microsoft Learn)
Key Vaultのリロード仕様を確認する
Key Vault configuration providerは、既定ではアプリケーションのライフタイム中にシークレットをキャッシュします。Key Vault側で値を更新・無効化しても、アプリが即座に反映しない場合があります。公式情報では、ReloadIntervalを設定することで定期的な再読み込みを構成できると説明されています。(Microsoft Learn)
ストレージキーをローテーションする運用では、次の点を事前に決めておきます。
| 項目 | 決めること |
|---|---|
| キー更新のタイミング | 業務時間内か、メンテナンス時間帯か |
| アプリ再起動の要否 | 自動反映か、明示的な再起動か |
| 二重キー運用 | Primary/Secondaryキーをどう切り替えるか |
| 障害時の戻し方 | 旧キーをどの期間保持するか |
| 監査 | 誰がいつKey Vaultの値を変更したか |
すぐに実施すべき確認ポイント
Azure Storageを使うASP.NET Coreアプリでは、まず次の5点を確認してください。
1つ目は、appsettings.jsonやappsettings.Development.jsonに接続文字列、アカウントキー、SASが入っていないかです。入っている場合はSecret ManagerやKey Vaultへ移し、漏えい可能性がある値はローテーションします。
2つ目は、開発環境で本番ストレージを参照していないかです。開発用ストレージアカウント、Azurite、検証用データへ切り替えます。
3つ目は、アプリがShared Key認証に依存していないかです。Microsoft Entra IDとマネージドIDでアクセスできる箇所から移行します。
4つ目は、Key VaultとAzure StorageのRBACが最小権限になっているかです。アプリ、開発者、CI/CDに同じ強い権限を持たせないようにします。
5つ目は、設定キーの命名です。Secret Managerでは:、環境変数では__、Key Vaultでは--を使う場面があり、環境ごとの対応表をチーム内で共有しておくと展開ミスを減らせます。
まとめ:開発中の便利さより、漏えい時の影響範囲で設計する
Azure Storageの「Safe storage of app secrets in development」で最も重要なのは、Secret Managerを使うこと自体ではありません。開発中のシークレットをソースコードから分離し、本番シークレットを開発環境へ持ち込まず、最終的にはMicrosoft Entra ID、マネージドID、Azure Key Vaultを中心にした構成へ移行することです。
まずはリポジトリとCI/CD変数を棚卸しし、Azure Storageの接続文字列やアカウントキーが平文で保存されていないか確認してください。次に、ローカル開発ではSecret Manager、本番ではKey VaultとマネージドIDを使う形へ整理します。Shared Key認証に依存している場合は、影響範囲を確認しながらMicrosoft Entra ID認証へ段階的に移行するのが現実的です。

コメント