CTC 教育サービス
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes
前回に続いて、2019年に公開された論文「Zanzibar: Google's Consistent, Global Authorization System」に基づいて、Googleのサービス群を支える統合認証システム「Zanzibar」を紹介していきます。今回は、リアルタイムに更新されるACLの整合性を担保する仕組みについて解説します。
前回の記事で説明したように、Zanzibarは「何に対して(object)」「どのような関係・権限を(relation)」「誰が持つのか(user)」という関係を表す、「<object>#<relation>@<user>」という形式のレコード(ACL)を記録します。この際、どのような順序でACLが変更されたかという時間的な前後関係を正しく保持すること、そして、誤って古い情報を返さないこと、この2点を守ることが特に重要になります。論文内では、これらが守られなかった際に起こり得る問題として、次の2つの例が挙げられています。
例1:時間的な前後関係を無視した場合に起こる問題
(1) アリスは、フォルダーからボブのアクセス権を削除する。
(2) アルスは、新しいドキュメントをフォルダーに保存するようにチャーリーに依頼する。このドキュメントはフォルダーのアクセス権を引き継ぐ。
(3) ボブは新しいドキュメントにアクセスできてはいけないが、(1)(2) の記録順序が誤っていた場合、ボブが新しいドキュメントにアクセスできる可能性がある。
例2:誤って古い情報を返した場合に起こる問題
(1) アリスは、ドキュメントからボブのアクセス権を削除する。
(2) アルスは、ドキュメントに新しい内容を書き加えるようチャーリーに依頼する。
(3) ボブはドキュメントの新しい内容を見れてはいけないが、Zanzibarが(1)より古い時点のACL情報を返すと、ボブは新しい内容を見れる可能性がある。
このような問題に対処するために、Zanzibarは、次の2つの手法を適用します。1つは、バックエンドデータベースであるSpannerの機能を用いて、ACLの変更操作に対して「外部一貫性(External Consistency)」を持つタイムスタンプを与えます。簡単にいうと、変更Aが完了した後に変更Bが開始された場合、変更A、変更Bのそれぞれに与えられるタイムスタンプTA、TBは、必ず「TA<TB」を満たすというものです。1台のサーバーで変更A、変更Bの両方を処理するのであれば、当たり前に思える結果ですが、複数のサーバーで並列に処理する場合、どちらの処理が先に完了したかを正しく把握するのはそれほど簡単ではありません。Spannerには、分散型のデータベースでありながら、外部一貫性を持ったタイムスタンプを与えることができるという特徴があります。
そしてもう1つは、ACLの情報を読み出す際は、特定時刻のスナップショットを利用します。時刻T1のスナップショットを利用すれば、読み出される情報は、T1以前の変更をすべて含んでいることが保証されます。クライアントからの検索リクエストに対して、使用するスナップショットの時刻を適切に選択する方法については、この次に説明します。なお、ここでいう「クライアント」は、サービスを提供するサーバー上のアプリケーションのことであり、エンドユーザーの端末上で稼働するコードではありません。この点に注意しながら、この後の説明を読み進めてください。
ACLの情報を読み出す際は、特定時刻のスナップショットを利用すると説明しましたが、単純に考えれば、「常に最新のデータを利用する」という方針が最善のように思われます。しかしながら、Zanzibarは地理的に離れた複数のデータセンターで稼働しており、それぞれの地域でデータベース(Spanner)が稼働しています。これら複数のSpannerは相互にデータレプリケーションを行っており、基本的には同一のデータを保持していますが、他の地域で行われた変更が反映されるまで時間差が生じる可能性があります。そこで、「必要とする範囲での最新の時刻」を選択して、その時刻までのレプリケーションが完了していれば、その時刻のスナップショットを利用してクライアントに情報を返します。レプリケーションが完了していない場合であっても、少なくともその時刻までのレプリケーションが完了するのを待てば応答を返すことができます。
それでは、「必要とする範囲での最新の時刻」はどのように決めるのでしょうか? これには、「content-change check」と呼ばれる特別なリクエストを使用します。図1は、content-change checkによって、先ほどの例2の問題が防止できることを示したものですので、この例を用いて説明します。
図1 content-change checkによって最新のACLを反映する仕組み
はじめに、ボブは、クライアントに対して、あるリソース(ドキュメント)の閲覧を要求します。この時、クライアントは、該当のリソースに対するcontent-change checkリクエストをZanzibarに送信します。すると、このリソースに対するACLが変更された最後の時刻情報を含む「zookie」と呼ばれるトークンが返るので、クライアントはこれをローカルに保存します。その後、zookieと共に該当リソースに対するACLをリクエストすると、Zanzibarは、zookieで指定された時刻よりも新しいスナップショットを用いてリクエストに応答します。次に、アリスは、このリソースのACLを変更して、ボブの閲覧権限を削除します。ただし、この時点のリソースの内容は、ボブはすでに閲覧しているので、リソースの内容が更新されない限りは、アリスによるACLの変更はボブに適用しても意味がありません。つまり、クライアントは、先ほど取得したzookieを再利用して、このリソースのACLを再取得しても構いません。
その後、チャーリーは、このリソースを更新しますが、このタイミングで、クライアントは、content-change checkリクエストを再送信して、zookieを取得しなおします。クライアントは、チャーリーによる更新内容をボブの端末に反映する前に、新しいzookieでボブに対するACLを再取得するので、チャーリーによる更新内容が誤ってボブの端末に反映されることはありません。このように、Zanzibarを利用するクライアントは、適切なタイミングでcontent-change checkリクエストを送信することにより、必要な範囲で最新のACL情報を取得することが可能になります。
今回は、2019年に公開された論文「Zanzibar: Google's Consistent, Global Authorization System」に基づいて、Googleのサービス群を支える統合認証システム「Zanzibar」において、ACLの整合性を担保する仕組みを説明しました。次回は、Zanzibarのシステム構成など、システム全体のアーキテクチャーを解説します。
Disclaimer:この記事は個人的なものです。ここで述べられていることは私の個人的な意見に基づくものであり、私の雇用者には関係はありません。
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes