認可
Keystoneと認可
Keystoneは認可を行いません。しかし、認可のために必要な情報を各サービスに提供します。認可は以下の4者のやり取りによって行われます。
- クライアント
- サービス
- Keystone
- データベース
クライアントは認証のときに受け取ったエンドポイントに従い、各サービスにリクエストを送ります。このリクエストには、認証の際に受け取ったTokenを本人確認のために添えて送ります。
リクエストを受け取ったサービスは、リクエストを処理する前に、本当にそのリクエストを受け付けてよいのかを確認します。
まずサービスは、リクエストの際に受け取ったTokenをKeystoneに送って、そのTokenが示すユーザーを問い合わせます。Keystoneは、データベースからTokenに該当するユーザーを探し出し、そのユーザーの情報をサービスに返答します。このユーザーの情報には、リクエストを受け付けたテナントにおけるユーザーのロールが含まれています。
ユーザー情報を得たサービスは、ロールに従ってユーザーを認可するか否かを決定します。認可するか否かの設定情報は各サービスが持っています。サービスは、ユーザーのロールと設定情報を比較して、認可するか否かを決定します。
ユーザーを認可した場合、そのサービスはユーザーがリクエストした操作を行います。
認可は各サービスが行うことでサービスの変更に対応できる
もし、MSAに従って認可の処理を1つのサービス(例えばKeystone)に担わせたらどなるでしょう。認可を行うそのサービスは、他のサービスに合わせて頻繁に更新しなければなりません。
Keystoneは認可を担当せず、認可に必要な情報を各サービスに共有する役目だけを果たします。認可するか否かを決定するのは各サービスです。これによって、各サービスとKeystoneのバージョンアップは独立して行うことができます。
Keystoneが認可について扱う情報
認可のためにKeystoneが各サービスに送信する情報は、認証の際に送る情報と同じものです。
OpenStackでは認可するか否かを判断するために「policy.json」というファイルを保持しています。内容は次のようなものです。
{
"admin_required": "role:admin or is_admin:1",
"service_role": "role:service",
"service_or_admin": "rule:admin_required or rule:service_role",
"owner" : "user_id:%(user_id)s",
"identity:list_regions": "",
"identity:delete_region": "rule:admin_required",
"identity:ec2_get_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)"
}
2~5行目は、認可の情報へのエイリアスです。意味は次のとおりです。
2行目:admin_requiredは、adminのロールを持っているかmetadataのis_adminの値が1であれば合致します。
3行目:service_roleはserviceのロールを持っていれば合致します。
4行目:service_or_adminはエイリアスを組み合わせたエイリアスです。admin_requiredないしはservice_rokeに合致するならばこれも合致します。
5行目:ownerはユーザーIDを利用する情報です。user_idの値が%(user_id)の値と同じならば合致します。「インスタンスを作成したユーザーであるならば」といった使い方ができます。
7~9行目が、実際の認可の情報です。認可機能を実装する際の参考にしてみてください。
7行目:identity:list_regionsは値が空です。これは「あらゆるユーザーにその操作を許容している」という意味です。
8行目:identity:delete_regionは値にadmin_requiredが入っています。これは、admin_requiredの条件を満たすユーザーでなければ認可されないことを意味します。
9行目:identity:ec2_get_credentialは複雑な条件です。「admin_requiredに合致するユーザーであるか、該当するリソース (この場合はユーザー) の持ち主でなければ実行できない」ことを意味します。
まとめ
サービスが頻繁に増えたり変化したりするという状況に対して、単純な情報であるエンドポイントはKeystoneに情報を集約し、その情報をリクエストに応じて共有するという手段で解決しています。また、複雑なロジックを要する認可については、Keystoneに認可に利用する権限情報のみを集約し、その情報を共有された各サービスが認可を行うことで解決しています。
この解決方法は、OpenStackがMSAで作られているからこそ実現できています。その意味で、Keystoneは機能の面でもアーキテクチャの面でもOpenStackの中核といえるのです。
