Lake FormationでLFタグ方式・リソース方式を使用しつつ、行列データアクセス制御をしてみた
はじめに
こんにちは、データ事業本部の渡部です。
今回はAWS Lake FormationのLFタグ方式とリソース方式を使用して、データのアクセス制御をしていきます。
タグの付け方はじめ、かなり頭を悩ませました。
本ブログは以下な人には特に参考になるんじゃないかと思います。
- Lake Formationでのアクセス制御の方針を検討している
- LFタグの運用を検討している
- Lake Formationでのハマりポイントを探している
LFタグ方式とリソース方式について
Lake Formationにはアクセス制御の方式として、「LFタグ方式」と「名前付きリソース方式」の2種類があります。
両者の特徴について、AWSのBlackBeltが詳しいので画像引用します。
LFタグ方式は、ざっくり以下の手順でアクセス制御をします。
- タグの作成
- リソース(DBやテーブル)にタグを付与
- プリンシパル(IAM UserやRole、IAM Identity CenterのUserやGroupなど)に任意のタグが付いたリソースに対する、操作権限または操作権限の付与権限を設定
対してリソース方式は、ざっくり以下の手順でアクセス制御をします。
- プリンシパルに、任意のDBやテーブルに対する、操作権限または操作権限の付与権限を設定
手順としては、リソース方式の方が少なく簡単そうに見えるのですが、
例えばテーブルごとにアクセス制御をするとなると、プリンシパルの数分設定する必要があるため、その掛け合わせで設定が必要になってきます。いわゆる密な設定です。
対してLFタグについては疎な設定となっているため、プリンシパルやデータアセットが増えてもプリンシパルとアセットの数の和の設定のみでよいです。
そのため LFタグ方式が推奨 です。
ただしLFタグ方式は列のアクセス制御までの対応で、行レベル・セルレベルでの制御をしたい場合は、リソース方式で対応する必要があります。
そこで私は「行列アクセス制御はどうやるのがベストなんだ?」という疑問を持ちました。
ということで、試してみようと思います。
前提
アクセス制御に使用するデータアセットとデータは以下のとおりです(データは抜粋)。
すでにデータはS3に配置し、DB・テーブルともにGlue Data Catalogに登録済みです。DataLake LocationにもS3パスを登録しています。
アクセス制御は以下のとおりに設定して、グレー部分をSELECTできないようにします。
カラムに対してPIIのものはデータアナリストに見せず、レコードに対してはid_000035
のものだけ出力させるようにします。
今回データアクセスの主体として使用するデータアナリストRoleに対しての許可ポリシーはAWSドキュメントの推奨のとおり設定しています。+Athenaのクエリ結果をS3に出力する許可ポリシーも追加で設定しています。
頭を悩ませながら格闘した記録
まずはデータアナリストRoleでテーブルにアクセスして、データが取得できないことを確認します。
アクセスしたいテーブルが属するデータベース「watanabe_test_db」にDescribe権限がなく、データベースは「defualt」のみしか選べないことから、クエリがエラーとなりました。
LFタグ方式
まずはLFタグでデータアクセス制御をしていきます。
LFタグを作成します。部署ごとにアクセス制御をするため、department
KeyとそのValueを設定しました。
department = {sales,research,manufacturing}
なお今回は使用しないのですが、LF-Tag permissions
とLF-Tag Key-value pair permissions
も設定しておきました。
本ブログとは関係ないので、トグルの中に収めます。
設定内容
LF-Tag permissions
はLFタグの変更・削除権限とその権限付与権限、LF-Tag Key-value pair permissions
はLFタグの参照・リソースへの割当て・LFタグを使用した権限設定の権限、およびそれらの権限付与権限を設定可能です。
今回は権限付与権限以外の権限をデータエンジニアRoleに割り当てました。
次にPII(個人識別用情報)のLFタグも作成しました。
PII = {true,false}
続いてリソースへのタグ付けです。
DBwatanabe_test_db
にdepartment = sales
のタグ付けをします。
LFタグは下位存在に継承されるため、DBにLFタグを付与したことで、テーブルにもdepartment = sales
のタグ付けがされました。(カラムにもタグが継承されます)
続いてプリンシパルへの権限設定をします。
IAM Roleデータアナリストに対して、department = sales
のタグに対する操作を設定します。
DBに対してはDescribe
、Tableに対してはSelect
権限を付与しました。
ちなみにDescribe
はそのDBの存在を見れるようになる、のような理解をすれば良いです。
Athenaでアクセスができるか確認してみます。
アクセス制御前には表示されていなかった画像左側のDBwatanabe_test_db
が表示されて、クエリ実行も成功しました。
さてテーブルのSELECTができることは確認したので、次は列アクセス制御を確認してみます。
PII = true
のLFタグを表示させないカラムに設定します。
残りの列に対して、PII = false
のLFタグを設定します。
さてこの段階でAthenaでクエリを実行してみました。
全カラムが表示されましたね。(あとで気づいたんですがSELECTでカラムを絞ってた方がわかりやすかったです。*
でやってしまったため、みにくいのですがご容赦ください)
現在のリソース・プリンシパルのアクセス制御設定を振り返ってみると、こんな感じです。
なぜAthenaでクエリが成功したのかというと、リソースにLFタグが複数付与されていたとしても、タグのAND条件で評価されるのではなく、OR条件でアクセス制御が評価される からです。
列にはすべてdepartment = sales
のLFタグ付けがなされており、department = sales
のSELECT権限をデータアナリストは保持しているため、SELECTができたというわけです。
それでは本題に戻りpii = false
のものだけアクセスできるように、プリンシパルへのアクセス制御を行います。
ここで私は頭を悩ませました。
Data Permissionに新規でpii = false
に対するアクセス制御を設定したとしても、列全てにアクセスが可能となってしまいます。
これはプリンシパルに対してのアクセス制御でも、Data Permissionを複数設定してもORで評価されてしまう ためです。
どうすればよいか考えた結果、以下のとおりタグ付けをするのがよさそうという結論に落ち着きました。
カラムで使用したタグを上位のDB/テーブルにアタッチし、
プリンシパルに対してはdepartment = sales and pii = false
のタグの組み合わせ(AND)に対してDESCRIBE
とSELECT
権限をつけます。
ここからは私の思考の備忘です。
備忘ハジマリ
以下のように、カラムからdepartment = sales
のタグを外すことでもpii = false
のもののみアクセスできるようにはなるので、よさそうとも思いました。
しかし、データを複数の事業部が触るようになったとき、特定の事業部の特定の人のみに
piiを見せる、というような複数タグの評価をさせるときに上記のタグ付けでは対応ができなくなってしまいます。
以下例ではデータアナリスト(sales)が、pii=true
のデータを閲覧できてしまいます。
備忘オワリ
という経緯もあり、⭐️星マークがついているタグづけを採用しました。
Lake Formationのコンソールで設定をしていきます。
IAMプリンシパルに対してのアクセス制御Data Permisson
は既存のものを編集することは不可能でした。
そのため新規でプリンシパルへのアクセス制御設定を作成して、既存のアクセス制御設定を削除するという流れになるのですが、
今後のアクセス権変更もあるかもしれないので、新規作成ではLF-Tag expression
を使用してアクセス制御をしました。LFタグ式と呼びます。
LFタグ式は後での変更が可能なので、後でData Permission
を変更することが可能です。
複数人に同じようなLFタグ制御をする場合にも、プリンシパルへのアクセス制御がLFタグ式を通すことで1回で済むようになりますね。再利用性・制御の一貫性・変更容易性が確保できます。
アナリストRoleにLFタグ式depertment = sales AND pii =false
に対してDESCRIBE,SELECT
を設定して、作成済みだった既存の制御を削除しました。
アナリストRoleでAthenaを実行すると、PII=true
のカラムが表示されなくなりました。
LFタグ方式によるカラムアクセス制御の完了です。
リソース方式
続いてリソース方式の制御をします。
タグ方式で設定したカラム制御はそのままに、customer_id='id_000035'
の行のみ表示されるようにしたいです。
Data Permissionでリソース方式で設定します。
リソース方式での行列アクセス制御設定は「Data Filter」で設定します。
こちらはLFタグ式と同じように使い回しが可能で、後から変更可能です。
カラムレベル制御はせず、行レベル制御customer_id='id_000035'
を設定しました。
これで設定完了です。
さっそくアナリストRoleでAthenaを実行しました。
しかし・・・全行見えたまま、かつ行フィルターで設定した行が 全カラム 見えるようになってしまいました。
なんとなく予想はできていましたが、LFタグ方式とリソース方式での許可もORで評価される ということですね。
図示すると、こんな状況です。
リソース方式でカラムのアクセス制限をしていないから、LFタグ方式とリソース方式で許可したSELECT権限のカラム・行がすべて見えるようになってしまいました。
そのため、リソース方式を使用する場合において、タグ方式でカラム制御をしているならば、リソース方式でも同様のカラム制御をする必要 があります。
リソース方式でカラム制御をしたあとにAthenaを実行すると、行列アクセス制限ができた形でデータ出力されました。
カラムレベルのアクセス制御が二重管理となって気持ち悪さはありますが、同じテーブルに対して行レベルのアクセス制御までしないプリンシパルが存在しうることを考えると、LFタグのアクセス制御効果を外すというのは筋が悪そうです。
ただ一応LFタグをリソースから外す方法も試したので、備忘として残します。
「どうしてもDB内の特定テーブルだけはリソース方式でアクセス制御をする必要がある」といったような特殊なケースに使用できるかなと思います。
備忘ハジマリ
リソース方式のみのアクセス制御となるように設定変更します。
ここでのハマりポイントとしては、継承されたタグは外すことはできないということです。
じゃあどうやってLFタグでのアクセス制御の効果を外すか。
「タグ継承元のDBからタグを外してタグ方式で制御するテーブルに一つずつタグをつけ、リソース方式で対応するテーブルのみはタグをつけない」とする案もあるのですが、そうなるとDBのDESCRIBE権限の付け方で他リソースと運用が変わることやテーブルの数だけタグをつけることになるので、それも避けたいです。
私が考えたのは、LFタグの値を変更することで対応するやり方です。
LF-Tag key-valuepii={true,false,data_filter}
というように、data_filter
の値を追加して、リソース方式で制御する全カラムに対して、pii=data_filter
のタグをアタッチします。(KeyとValueの意味合いが紐づかないのが難点です。Classification
のようなKey名であればまだよかったでしょうか)
これならば、DBの他テーブルの継承に影響することなく、リソース方式での制御とすることが可能です。
コンソールで設定していきます。
LFタグを編集しました。
全カラムに対してLFタグの値を変更しました。
またリソース方式でのカラムレベル制御もするため、Data Filterで除外するカラムを選択しました。
こうして設定を変更して、データアナリストRoleでAthenaを実行すると・・・
無事想定どおり、行列アクセス制限ができた形でデータ出力されました。
備忘オワリ
さいごに
今回の検証で、列アクセス制御のみの場合はLFタグ方式を使用して、追加で行レベルアクセス制御を重ねがけしたい場合は、LFタグ方式はそのままに行列どちらもアクセス制御させるリソース方式を使用する という方針がよさそうであることがわかりました。
とにかくおさえておくことは、LFタグ方式とリソース方式でのアクセス制御はORで評価されるということ です。
なかなかLake Formationでのアクセス制御はORやANDの評価が入り乱れて、理解するのが難しく、アクセス制御の運用で頭を悩ませます。
おそらくタグの付け方ひとつとっても、LFタグ方式とリソース方式の使い方は様々なやり方があるとは思います。
今回ご紹介したアクセス制御方法を叩き台として、それぞれのデータアクセス制御運用について考えてもらえれば幸いです。