Snowflake ロール設計

# はじめに
ファンクショナルロールとアクセルロールを使用した設計例について書きました。
ファンクショナルロールとアクセルロールについては [こちら](https://qiita.com/Hikaru_O/items/bc8ac8b91566485cc949 "Snowflake オブジェクトへのアクセス制御") の記事に記載したので先に読むのをおすすめします。

# やりたいこと
ユーザーごとに見られる/見られないをロールによって制御したい。
例：
・一般社員は基本的に全データを見られるが人事データは見られない
・人事部門社員は一般社員の範囲に加えて人事データも見られる

一般社員の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635659/c64e9de9-a966-f994-99ed-6ce4baeb0350.png)


人事部門社員の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635659/e632e690-0e73-4fa1-d117-2c932b8eaefb.png)


# 設計例
わかりやすくするために参照用と管理用に分けて説明します。
管理用に関しては「やりたいこと」と直接関係はないかもですが基盤の運用をする上であるとよいと思うので記載します。

### 前提
登場するオブジェクト
・データベース*1：DB_ABC
・全体に公開するスキーマ：SC_XXX　
・限定公開データ用のスキーマ：SC_HR
データベース1つに対して、スキーマを2つ（1つは全員が見られるデータが入るSC_XXX、もう一つは人事しか見られない人事データが入るSC_HR）の構成

ロールの命名規則（水色の箱）
・FR_で始まるもの = ファンクショナルロール
・AR_で始まるもの = アクセルロール

## 参照用
見た目は[公式サイトの例](https://docs.snowflake.com/ja/user-guide/security-access-control-considerations#aligning-object-access-with-business-functions "オブジェクトのアクセスとビジネス機能の整合")とおおよそ同じなのですが、
違うのはファンクショナルロール同士の継承があることです。
基本的にファンクショナルロールはユーザーに紐づくのですが、この設計ではファンクショナルロール同士の継承もしてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635659/85273bce-96bd-b765-30c0-e549e2e5c97d.png)


例えば、FR_JINJIはFR_IPPANを継承してます。
理由は、人事部門社員も一般社員と同様に左側のSC_XXXの参照もできるようにしたいからです。
（人事部門領域+一般という「やりたいこと」の図をロールで表現してみました）



ここで、
アクセルロールのAR_SC_XXX_VIEWをFR_JINJIに継承すればいいのでは？
と思う人もいるかもしれませんが、その通りです。

ファンクショナルロールを継承するか、アクセルロールを継承するかは組織の好みになります。
この設計では実世界の役割になるべく寄せようとしたので、「人事部門社員は人事部門社員である前に一般社員である」という考えの下、ファンクショナルロールFR_IPPANをFR_JINJIに継承するようにしています。そして次のような利点もあります。

仮にアクセルロールを継承した場合、今時点では全体公開スキーマが1つでも今後5、10、20と増える度にAR_SC_○○_VIEWをすべてのファンクショナルロール（FR_IPPAN、FR_JINJI、etc.）に継承するのは手間です。

アクセルロールを継承した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635659/823c6d6d-3ea0-4c3b-3d14-ca6c20fd910a.png)



なので、
・FR_IPPANをFR_JINJIに継承
・全体公開スキーマが増えた場合はFR_IPPANに継承する
のようにしておけば、FR_JINJIやその他継承済みのファンクショナルロールにも自動的に新スキーマの権限が継承されますので効率が良いと思います。

ファンクショナルロールを継承した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635659/04671d6d-8d24-a620-cb93-5e03598859e4.png)







## 管理用
データ基盤を導入しはじめの時期は、基盤管理者に管理が一極集中すると思いますが、運用していく中で管理を分けられるような設計をしておくのがおすすめです。
下記は、後に活用が広まりデータベース管理者、スキーマ管理者など、細分化できるようなロール設計になってます。

一般利用と異なるのはALL権限を付与していることです。
設計によってはSELECT,UPDATE,INSERT…と個別の権限を付与するものもありますが、この場合はシンプルにするため管理相当の操作権限としてALL権限を付与します。（[権限一覧](https://docs.snowflake.com/ja/user-guide/security-access-control-privileges"アクセス制御権限")）

また、ETLツールやBIツールなどのアプリケーションの役割を他と明確に分けるため、ユーザーやロールを専用に分けます（一番左）。蓄積や可視化の際に全てのスキーマやテーブルアクセスできるよう、全てのスキーマの管理権限のアクセルロールをアプリ用のファンクショナルロールに継承しています。

スキーマ SC_XXXを例に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635659/ca193417-51f7-ddf7-f3de-6d86326118f2.png)





最後に、ここまで出てきた全てのファンクショナルロールはカスタムロールなので、[Snowflakeの推奨](https://docs.snowflake.com/ja/user-guide/security-access-control-considerations"アクセス制御の考慮事項")のとおり、全てのファンクショナルロールをSYSADMINに継承します。
そうすることで管理が集中する初期段階においても基盤管理者が、細かく分けられたファンクショナルロールを意識することなく全てのスキーマやテーブルにアクセスできます。




# まとめ
・データの見える/見えないをファンクショナルロールとアクセルロールの組み合わせで制御する
・運用イベントにシンプルに対応できる設計を考慮する
・社内での基盤利用度にあわせて柔軟に変化していけるような設計を意識する

FRとARの概念を理解していても、具体例になると急に「これなんでだっけ」とわからなくなってしまうことがよくありました。その度に設計を見直したり人に聞いたりしてようやくこロール設計することの良さを理解できるようになりました。

複雑すぎると運用に限界がありますし、ルールがないのも無法地帯になりかえって複雑になってしまう、など運用を見据えた設計は難しいですね。
重要なところは押さえつつ、なるべくシンプルにするのがとても大事なポイントだなと感じました。
ロールのまとめ方に正解はないなあと実感したのでご参考までに。


# 参考
アクセス制御の概要：
https://docs.snowflake.com/ja/user-guide/security-access-control-overview

オブジェクトのアクセスとビジネス機能の整合：
https://docs.snowflake.com/ja/user-guide/security-access-control-considerations#aligning-object-access-with-business-functions

https://docs.snowflake.com/ja/user-guide/security-access-control-privileges