Googleが数十億ユーザーのアクセス権限をどのようにチェックしているか、そしてSpiceDBとの関係
プロジェクトがadminとuserという単純なロール構造を超えて成長すると、混乱が始まります。マイクロサービスアーキテクチャでは、権限チェックが絡み合ったウェブのように複雑化することが多いです。あるサービスはデータベースにロールを保存し、別のサービスはJWTトークンを検証し、3番目のサービスは多くのJOINを含む重いSQLクエリを実行します。2021年以降、OWASPはアクセス制御の失敗(Broken Access Control)をWebアプリケーションセキュリティに対する最優先の脅威として位置づけています。
Googleは長年にわたってこの問題と向き合ってきました。Google Drive、YouTube、Cloud IAMのために、同社はZanzibarという統一された集中型認可システムを発展させました。2019年、エンジニアたちはそのアーキテクチャに関する論文を発表し、Authzedチームはこれに着想を得て、アクセス制御管理のためのオープンソースデータベースであるSpiceDBを作成しました。
認可を別のデータベースに移行する理由
通常のデータベースはビジネスエンティティの保存には優れていますが、複雑な権限グラフの処理には苦戦します。ドキュメントが別のフォルダ内にあるフォルダに置かれており、ユーザーグループと別の部署が共有している状況を想像してください。標準的なDBMSを使用して、特定の従業員がファイルにアクセスできるかどうか計算すると、非常に面倒で低速になります。
SpiceDBはこのタスクを肩代わりします。データベースにシンプルなクエリを送信します:「ユーザーXはリソースZに対してアクションYを実行できるか?」。応答は高速なバイナリ回答です。
同時に、SpiceDBは認可(アクセス権限)のみを処理し、認証(身元確認)については何も知りません。パスワードの確認、ユーザーのログイン、トークンの発行は、KeycloakやAuth0などのアイデンティティプロバイダーが引き続き処理する必要があります。
スキーマとリレーションシップ言語の仕組み
SpiceDBでの作業は、スキーマの記述から始まります。スキーマはオブジェクトタイプと権限計算のルールを定義します。
スキーマの構文は読みやすく簡潔です:
definition user {}
definition folder {
relation parent: folder
relation viewer: user
permission view = viewer + parent->view
}
definition document {
relation folder: folder
relation viewer: user
permission view = viewer + folder->view
}
この例では、ドキュメントへのアクセスのviewは、viewerに直接リストされているユーザーに自動的に付与されるだけでなく、親フォルダで権限のviewを持つユーザーにも付与されます。ネストチェーンは任意の深さにできます。
実際のデータはリレーションシップとして保存されます。これらはシステムに関する単純な事実です,例如:
folder:finance— IDがfinanceのフォルダタイプのオブジェクトviewer— リレーションuser:mikhail— サブジェクト
このようなリレーションシップを記録することは、ミハイルがファイナンスフォルダのリーダーになったことを意味します。
ReBACと属性:Netflixの経験
古典的なRBAC(Role-Based Access Control)と異なり、SpiceDBはReBAC(Relationship-Based Access Control)を実装しています。アクセスはグラフ内のオブジェクト間のリレーションシップを通じて決定されます。
しかし、ビジネスではユーザーがチームの一員であることを知るだけでは不十分な場合があります。コンテキスト条件を検証する必要があります,例如、人物が企業のIPアドレスからアクセスしているか、要求が営業時間中に実行されたかなど。
このようなシナリオのために、NetflixのエンジニアたちはSpiceDBにcaveatsメカニズムの追加を支援しました。これはReBACとABAC(Attribute-Based Access Control)を組み合わせたものです。コンテキスト関数がリレーションシップに添付され、権限チェックの瞬間に計算されます。
アーキテクチャと負荷時のパフォーマンス
SpiceDBはGoで書かれており、高負荷向けに設計されています。著者たちは、数百万クエリ/秒およびデータベース内の数十億のリレーションシップでp95レイテンシ5msを主張しています。
ストレージ(データストア)として、馴染みのあるDBMSを接続できます:
- PostgreSQL
- CockroachDB
- MySQL(MySQL用のドライバはGitHubの認可チームによって作成されました)
- Google Cloud Spanner
興味深い機能の1つは、個々のクエリレベルでの一貫性管理です。ユーザーがアクセス権限を変更したばかりの結果をすぐに確認したい場合、アプリケーションは完全に一貫性のあるデータを要求するリクエストを送信します。ただし、パブリックカタログをレンダリングしていて、数秒の遅延が問題でない場合は、キャッシュを許可してデータベースへの負荷を軽減します。
SpiceDBは「逆」質問にも回答できます:「このユーザーはどのリソースにアクセスできるか?」や「このドキュメントを表示できるのは誰か?」。これには、内部で逆インデックスを使用します。
Dockerとcurlによるクイックスタート
1つのDockerコマンドで実験用のSpiceDBを起動できます:
docker run --rm -p 50051:50051 -p 8443:8443 \
authzed/spicedb serve \
--http-enabled true \
--grpc-preshared-key "somerandomkeyhere"
起動後、HTTP API経由でスキーマを読み込みます:
curl --location 'http://localhost:8443/v1/schema/write' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer somerandomkeyhere' \
--data '{
"schema": "definition user {} \n definition folder { \n relation viewer: user \n permission view = viewer \n }"
}'
ユーザーanneがフォルダbudgetを表示できるリレーションシップを追加します:
curl --location 'http://localhost:8443/v1/relationships/write' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer somerandomkeyhere' \
--data '{
"updates": [
{
"operation": "OPERATION_TOUCH",
"relationship": {
"resource": { "objectType": "folder", "objectId": "budget" },
"relation": "viewer",
"subject": { "object": { "objectType": "user", "objectId": "anne" } }
}
}
]
}'
次に権限を確認します:
curl --location 'http://localhost:8443/v1/permissions/check' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer somerandomkeyhere' \
--data '{
"resource": { "objectType": "folder", "objectId": "budget" },
"permission": "view",
"subject": { "object": { "objectType": "user", "objectId": "anne" } }
}'
応答としてステータスPERMISSIONSHIP_HAS_PERMISSIONを受け取ります。
RESTおよびgRPC APIに加えて、開発者はコマンドラインユーティリティのzedと、Playground(play.authzed.com)というブラウザベースのサンドボックスを提供しています。これは権限モデルを作成し、テストデータで埋め、コードを書く前に仮説をテストするのに便利です。
このツールの対象ユーザー
SpiceDBはすでにRed Hat、IBM、GitPod、Tubiで本番稼働しています。
すべての権限が管理パネルと少数のロールに限定されている小さなモノリスでこのようなシステムを導入しても意味がありません—不必要的インフラ複雑化です。ただし、次のような場合にこのツールは最適です:
- десятокのマイクロサービスがあり、それぞれが独自の方法で権限チェックを試みている場合。
- 製品ロジックがファイル共有、複雑なフォルダ階層、チームアカウントを必要とする場合。
- セキュリティ監査とアクセス制御管理の単一ポイントが必要な場合。
Kubernetesへのデプロイメントには、Authzedが公式オペレーターを提供しています。プロジェクトは積極的に開発されており、GitHubリポジトリにはすでに約7,000個のスターがあります。
関連プロジェクト