ユーザにできるだけセキュアにAzure Files（ファイル共有）リソースにアクセスさせる

#### この記事の内容
[本記事の概要](#本記事の概要)
　[SAS利用の背景](#sas利用の背景)
　[SASの種類と制御](#sasの種類と制御)
[SASトークンの生成](#sasトークンの生成)
　[ポータル上で生成](#ポータル上で生成)
　[Pythonで生成](#pythonで生成)
[まとめ](#まとめ)

## 本記事の概要
#### SAS利用の背景
Webサービス等を構築する際、ユーザにストレージアカウント上のリソースにアクセスさせたいことがある。そういった場合、ストレージアカウントキーや接続文字列をユーザに渡すというのはセキュリティリスクが非常に高いため推奨されない。

https://learn.microsoft.com/ja-jp/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#protect-your-access-keys

> ストレージ アカウント アクセス キーは、ストレージ アカウントの構成とデータへのフル アクセスを提供します。 アクセス キーは常に慎重に保護してください。 キーを安全に管理およびローテーションするには、Azure Key Vault を使用します。 共有キーへのアクセスにより、ストレージ アカウントの構成とそのデータへのフル アクセス権がユーザーに付与されます。 共有キーへのアクセスは慎重に制限し、監視する必要があります。

したがって、限定的でよりセキュアなアクセスを実現できるShared Access Signatures（SAS、共有アクセス署名）を発行するのが一般的である。

#### SASの種類と制御
SASは以下のようなアクセスコントロールを可能にする。

- 権限付与（読み取り、書き込み、作成、削除など）
- アクセス可能なリソースの制限（特定サービス、ファイルのみ等）
- 有効期限の設定
- 発信元ip指定
- プロトコル指定（httpsのみなど）
<br>
またSASは３種類あり、署名方法や利用できるサービスが異なる。

https://learn.microsoft.com/ja-jp/azure/storage/common/storage-sas-overview#types-of-shared-access-signatures

>* ユーザー委任 SAS
>ユーザー委任 SAS は、Microsoft Entra 資格情報によって保護されるだけではなく、SAS に指定されたアクセス許可によっても保護されます。 ユーザー委任 SAS は、BLOB ストレージにのみ適用されます。

>* サービス SAS
>サービス SAS は、ストレージ アカウント キーで保護されます。 サービス SAS は、次のうち 1 つだけの Azure Storage サービスのリソースへのアクセスを委任します。Blob storage、Queue storage、Table storage、または Azure Files。

>* アカウント SAS
>アカウント SAS は、ストレージアカウント キーで保護されます。 アカウント SAS は、1 つ以上のストレージ サービスのリソースへのアクセスを委任します。 サービスまたはユーザー委任 SAS を介して実行できるすべての操作は、アカウント SAS を介しても実行できます。

今回は、Azure Filesで利用できる方法としてサービスSASを用いる（Azure FilesではサービスSASとアカウントSASが利用できるが、サービスSASがよりセキュアである）。本記事では、Azure Portal上での発行方法とPythonを利用した発行方法を紹介する。（PowerShellでの発行方法は割愛する）

## SASトークンの生成
#### ポータル上で生成
こちらは至って簡単である。

AzurePortalからストレージアカウントにアクセスし、ストレージブラウザからSASトークンを発行したいリソースのミートボールメニューを展開。「SASの生成」を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632520/a86114aa-ff7a-c658-eeb9-698b99d1f671.png)

画面右側に下のような作成メニューが表示されるので、入力後に「SASトークンおよびURLを作成」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632520/24d188c5-2c8f-509c-ff88-756672477e4d.png)

:::note info
SAS URLを用いてユーザは対象のリソースにアクセスできるようになる。
:::



#### Pythonで生成
こちらが本記事のメイン。
ユーザに既存のリソースを読み込ませるだけなら上記方法でも問題ないが、より動的な要件の場合はこちらが必要となる。今回はPythonを用いて __ファイル共有直下の特定ファイルへの読み取りアクセスを１時間だけ許可する__ SASトークンの取得を行う。

```python
from azure.storage.fileshare import ShareServiceClient
from azure.storage.file import (
    FileService,
    FilePermissions,
)

# ファイル共有サービス全体と各ファイル共有用のクライアントを取得
share_service_client = ShareServiceClient("ストレージアカウントのURL", "ストレージアカウントキー")
share_client = share_service_client.get_share_client("ファイル共有名")

# 各ファイル用のクライアントを取得
file_service = FileService(
    account_name=share_client.account_name,
    account_key="ストレージアカウントキー",
)

# SASトークンの生成
sas = file_service.generate_file_shared_access_signature(
    share_name=share_client.share_name,
    directory_name=None,
    file_name="ファイル名",
    permission=FilePermissions.READ,
    expiry=datetime.datetime.utcnow() + datetime.timedelta(hours=1),
)

# SAS URLを作成
sas_url = f"https://{share_client.account_name}.file.core.windows.net/{share_name}/{file_name}?{sas}"
```

:::note warn
ストレージアカウントキーをソース直書きするのは非推奨。
[前述](#sas利用の背景)の通りフルアクセスが可能になるアクセスキーは慎重に保護されるべきで、Key Vault等から取得するべきだろう。
:::

## まとめ
本記事では、SASを利用する背景から実際の作成方法を紹介した。
筆者が方法を模索していた際、Blobでの生成方法が多くAzure Filesでの生成に苦労したのでナレッジとして記述した。