こんにちは!any 株式会社のエンジニア @t-komure です。
この記事は、any Product Team Advent Calendar2025 10日目の記事になります。
この記事では、Azure Blob Storageに対して安全にファイルをアップロードするための署名URL(ユーザー委任SAS)をPythonコードから発行する方法にフォーカスして紹介します。
外部公開されたキーを使わずにAzure App ServiceのマネージドIDを利用して署名URLを発行する構成は、セキュリティ・運用性の両面で非常に優れています。
署名URLを発行する方法はいくつかありますが、セキュリティと運用のしやすさの観点からユーザー委任SASを利用します。
なお、署名URL(委任SAS)や認証方法の知識は以下の記事がとても参考になります!
システム構成(概要)
今回利用した主なサービスは次のとおりです
- クライアント(Frontアプリケーション)
- バックエンドAPIから発行された署名URLを取得
- 署名URLへ直接 PUT してファイルアップロード
- Azure App Service
- Pythonアプリケーションをホスト
- システム割り当てマネージドIDを有効化
- Blob Storage認証の主体として利用
- Azure Blob Storage
- ファイルのアップロード先
- ユーザー委任SASを利用
- パブリックアクセスは無効(セキュア)
Azure側の事前設定
署名URLを発行するにはAzure側でいくつか最低限の設定が必要です。
特に以下の設定がポイントとなります。
- App Serviceのシステム割り当てマネージドIDの有効化
- Storage側の権限付与
App Service - システム割り当てマネージドIDの有効化
マネージドIDを使うことでAzure SDKが勝手に認証してくれます。
マネージドID以外の認証ではApp Serviceの認証情報を環境変数に設定するか、Blob Storageのキーを利用する必要があります。
設定手順
1. Azure Portal
2. App Service → 左メニューの「ID」
3. システム割り当てを「有効」にする
4. 保存すると自動的にサービスプリンシパルが作成される
Blob Storage 側に必要なロールを付与する
署名URLの発行、および、発行した署名URLを使いアップロードやBlobを参照するには、App ServiceのマネージドIDにBlob Storageへアクセスできるようロールを割り当てます。
必要なロールは以下の2つです。
- Storage Blob Delegator
- ユーザー委任キー(署名URLの一部)を取得するためのロール
- Storage Blob Data Contributor
- Blobの作成および参照を許可するための基本ロール
- 署名URLでのアップロードおよび参照が可能となる
設定手順
1. Azure Portal
2. 対象の Storage Account
3. アクセス制御 (IAM)
4. ロールの割り当て
5. ロール選択
• Storage Blob Data Contributor
• Storage Blob Delegator
6. プリンシパルとして App Service の Managed Identity を選択
先ほど有効化したマネージドIDに以下の2ロールが付与されていればOKです🙆♂️
Azureらしい翻訳のクセが出ていますね😇
Azure側で必要となる最低限の設定は完了です。
Pythonコードで署名URL(User Delegation SAS)を発行する実装
ここからはPythonコードで署名URLを発行する実装を紹介します。
ポイントは以下の通りです
- マネージドIDを使ってAzure AD認証する(実際はクラスをインスタンス化するだけ)
- ユーザー委任キーを取得する
- 署名の開始/期限を適切に設定する(クロックスキュー対策)
- 最小権限(書き込み/参照)で署名URLを発行
必要なパッケージはazure-identityおよびazure-storage-blobです。
uv add azure-identity azure-storage-blob
または
pip install azure-identity azure-storage-blob
マネージドIDを使って署名URLを発行する実装
App ServiceのマネージドIDを有効化していれば、ManagedIdentityCredential()を使ってストレージへアクセスできます。
from azure.identity import ManagedIdentityCredential
from azure.storage.blob import (
BlobSasPermissions,
BlobServiceClient,
)
now = datetime.utcnow()
client = BlobServiceClient(
account_url=f"https://{ストレージ アカウント名}.blob.core.windows.net",
credential=ManagedIdentityCredential(),
)
# ユーザー委任キーの取得
delegation_key = client.get_user_delegation_key(
key_start_time=now - timedelta(minutes=5),
key_expiry_time=now + timedelta(hours=1),
)
# BlobSasPermissionsでストレージに対する権限を指定する。
# `write`および`create`はアップロード権限の付与となる。`read=True`を指定することで参照権限となる。
token = generate_blob_sas(
account_name={ストレージ アカウント名},
container_name={コンテナ名},
blob_name={ファイル名},
user_delegation_key=delegation_key,
permission=BlobSasPermissions(write=True, create=True),
start=now - timedelta(minutes=5),
expiry=now + timedelta(minutes=10),
)
upload_url = (
f"https://{ストレージ アカウント名}.blob.core.windows.net/"
f"{コンテナ名}/{ファイル名}?{token}"
)
ポイント解説
✅ ManagedIdentityCredentialを明示的に使用
本記事ではApp ServiceのマネージドIDを利用するためManagedIdentityCredential()を使っています。
※ DefaultAzureCredential()もApp Service上では自動使用しますが混乱を避けるためこちらを利用します。
✅ User Delegation Keyのstart/expiry
key_start_time = now - timedelta(minutes=5)
時刻のずれを考慮して開始を5〜15分前などにすると安定します。
✅ sas_expiry = now + timedelta(minutes=15)
sas_expiry = now + timedelta(minutes=15)
``` python
署名URLが漏れた場合のリスクを最小化するため、
5〜15分程度の短命URLを推奨します。
##### ✅ SAS の Permission は最小限に
アップロード時は参照や削除を許可しません🙅♂️
``` python
BlobSasPermissions(write=True, create=True)
生成される署名URL
以下のようなURLが発行されます。
https://example.blob.core.windows.net/container/sample.pdf?se=2025-12-03T01%3A23%3A14Z&sp=r&sv=2025-11-05&sr=b&skoid=3217db61-b9c5-4600-b9d0-c3aa21e1789a&sktid=75733da6-a524-4b51-8999-9ba220698027&skt=2025-12-03T01%3A08%3A14Z&ske=2025-12-03T01%3A23%3A14Z&sks=b&skv=2025-11-05&sig=aS8pjRXd5nVnK/cE66rJ8ZTUmc7RTgJVOWQMXdQpu%2BM%3D
まとめ
App ServiceでのマネージドID有効化〜Blobストレージアカウントの作成・権限割り当て、コードからの署名URL発行はとても簡単にできました。
- マネージドIDで秘密情報なしに署名URLを発行できる
- ユーザー委任SASはAzure AD認証が必須 → マネージドIDとの相性が良い
- 署名URLの開始時刻は "5分前" にしてclock skewを回避
- 署名URLの有効期限は短めにしてセキュアに
any株式会社ではナレッジ経営クラウドQastのエンジニアを絶賛募集中です。
是非採用ページをご覧ください!

