Azure Blob StorageにUser delegation SAS tokenがPreviewとしてリリースされました。
PublicなBlobを除いて通常Blobは共有キーによる認可(承認)かAzure ADアカウントを使用した認証(= RBAC)、およびShared Access Signature(SAS)を用いにアクセス委任による認可がないとアクセスできません。
このうちのSASですが、これまでSASの生成方法はストレージアカウントのキーを使ったサービスSASかアカウントSASの2種類でどちらもストレージアカウントキーを使うタイプでした。
今回のUpdateはこのSASの生成方法に新しくUser Delegation SAS(ユーザー委任SAS)がPreviewとして増えたという内容になります。
仕組み的にはSASを署名する際に使用するキーをストレージアカウントキーではなく、ユーザー委任キーを使用する形になります。SASを生成する前に、ユーザー(やアプリケーション)はGet User Delegation Key(REST API)を使用してキーを取得し、そのキーで署名を行いSASを生成します。この委任キーを取得する際、OAuth2.0でAzure ADから得たアクセストークンを使用します。
その後SASの設定+RABCの設定に従って適切にアクセスがコントロールされます。既存のAzure ADを使ったRBACによるストレージアクセスの拡張といったところでしょうか。
とりあえずの使い方(.NET)
準備としてはStorageアカウントにRBACで適切な権限を付与します。ユーザー委任キーを生成する権限は後述するのですが、結局最終的にアクセスするBlobなどもRBACの権限を見るので、Blob Storageに適切な権限を付与します。(Storage Blob Data Readerなど)
今回サンプルとしてAzure FunctionsにManaged Identitiesを設定し、SAS付きURLを生成するようにしました。だいたいの手順はこちらも参考に。
Functions作成後、Managed IdentitiesをOnにしてBlob StorageにStorage Blob Data Readerのロールを割り当てます。
コード的には以下のようになります。(ほぼサンプル)
サンプルからの注意点としてはBlobSasBuilderでSASを生成する際、Versionをユーザー委任キー(UserDelegationKeyのSignedVersion)と一致させる必要があります。(一致しないとPermissionが不適切だとかのエラーになった)
出来上がったSAS付きURLにアクセスすると普通にアクセスできます。試しにBlob Data Readerロールを外したりすると見えなくなるので権限が適切に引き継がれてる(チェックされてる)感じでかすね。
また診断ログ(Classic)でログを取得するようにしておくと、この時使用したユーザーのObject IDやテナントIDがログに含まれます(Logのフォーマットが2.0の場合のみ)
例(赤字の個所がID):
2.0;2019-09-17T21:08:45.6434116Z;GetBlob;SASSuccess;200;443;443;sas;;ebiteststorage;blob;”https://xxxx.blob.core.windows.net:443/test/test.txt?sv=2019-02-02&st=2019-09-17T21%3A07%3A22Z&se=2019-09-17T21%3A18%3A22Z&sr=b&sp=r&skoid=xxxxxx-xxxxx-4993-853d-1ac972472c76&sktid=xxxxxxx-xxxx-xxxxx-a319-0bd5a60e45f3&skt=2019-09-17T21%3A07%3A22Z&ske=2019-09-24T21%3A08%3A22Z&sks=b&skv=2019-02-02&sig=XXXXX”;”/xxxxxx/test/test.txt”;abdd8fbc-c01e-0031-7b9c-6d9e2d000000;0;xxx.xx.xx.xxxx:56206;2019-02-02;840;0;436;17;0;;;”"0x8D73B8D3B7B36FD"”;Tuesday, 17-Sep-19 16:36:47 GMT;;”Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3891.0 Safari/537.36 Edg/78.0.268.3″;;;”xxxxxx-xxxxx-4993-853d-1ac972472c76“;”xxxxxx-xxxx-xxxx-a319-0bd5a60e45f3″;;;;;;”[{"action":"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read", "roleAssignmentId":"xxxxx-925b-44d9-bf5f-8a6deb7d4bcd", "roleDefinitionId":"xxxxx-6ea1-4ae2-8e65-a410df84e7d1", "principals": [{"id": "xxxxx-3658-4993-853d-1ac972472c76", "type":"ServicePrincipal"}], "denyAssignmentId":""}]”
※今回Managed Identitiesを使用したので上記IDはFunctionsのIDになります。Get User Delegation Keyをユーザーのアクセストークンで取得し、なんとかごまかしてUserDelegationKeyオブジェクトを生成すればそのユーザーのアクセスにできます。(Azure CLIなどはそのようになる)
ちょっと今の.NET SDKだとしんどいですね。今後に期待かな。
SASの詳細
SASの詳細についてはこちらのドキュメントを参照ください。
SASに関するベストプラクティスも書いてるので必読です。要件によりますが今後はユーザー委任SASを使ってできるだけ権限と適用範囲を絞ってストレージアカウントキーは使わない方向性のほうが良いでしょうね。またアクセスポリシーを使ってSASの失効をある程度コントロールできるようにしたり、Log Entry Format 2.0を使った診断ログで利用者のIDも取れるようにするのが良いかと思います。(Audit的な)
ユーザー委任SASは含まれる情報が通常のSASトークンよりちょっと多いのでSDKなどを使わず手で作る場合は以下の情報を参考に生成しましょう。
まとめ
ユーザー委任SASは組織内Blob利用などで適切なアクセスコントロールをするうえで大事な機能だと思うので、ちゃんと理解して正しく扱いたいですね。
おまけ
最近のAzure CLIなどは –auth-mode loginを付けるとaz loginしたユーザーの情報(アクセストークン)を使ってくれます。最新のAzure CLIでaz storage blob generate-sasで上記引数と–az-user を付けるとユーザー委任SASを生成してくれます。(ちゃんと権限が設定されていれば)
ピンバック: Azure Update (2019.09.19) | ブチザッキ