OSS+ Compass

【OpenStackチャレンジ】 第6回 policy.json紹介編

2017.06.21

OpenStackチャレンジ

はじめに

photo22.jpg

Policy.jsonとはOpenStackコンポーネント毎に存在し、各種操作に必要な権限を設定するファイルの事です。

Keystone、Nova、Neutronなどなど…、OpenStackのサービスを司る各コンポーネントは、それぞれがロール(=役割)ベースのアクセスポリシーを所有しています。それを定義するのがpolicy.jsonファイルであり、「どのユーザが、どのオブジェクトにアクセスできるか」を決定しています。

この様にpolicy.jsonは非常に有用かつ重要な役割を担っているのですが、日本語で書かれた分かり易い解説ページがあまり見当たらないのです。という事で、policy.jsonの記述様式について纏めてみました。
本記事執筆にあたり、こちらのドキュメントを参考にさせていただきました。

policy.jsonとは?

policy.jsonファイル自体はJSON(Javascript Object Notation)フォーマットのテキストファイルで、各コンポーネント配下に存在しています(Novaであれば/etc/nova/policy.jsonといった具合です)。各ポリシーは“<target名>”:”<rule名>”フォームにより定義され、”<target名>”は”start an instance”や”attach a volume”といったAPIコールを対象としています。更新されたpolicy.jsonファイルは即座に有効化され、サービス稼働中であっても新しいポリシーが実装されます。

policy.jsonでは”<target名>” 毎に設定範囲を限定します。例えばNovaはインスタンスの一覧表示($nova list)やボリュームリストの表示($nova volume-list)を行いますが、これらは/etc/nova/policy.jsonにおいてcompute:get_all、volume:get_allで設定されます。因みにAPIコールとアクション間のマッピングについては、基本的にドキュメント化されていません。

“<rule名>”では、APIコールの実行ユーザ(以降APIユーザ)とオブジェクトオーナーが同一であるか確認し、その後”<target名>”の実行に向けたAPIコールの許可を出しています。

基本的なルール作成例

では、具体的にいくつかのシンプルなルールを見ていきましょう。

“compute:get_all” : “”
ターゲットはComputeサービスの”list all instances”APIである、”compute:get_all”です。“<rule名>”の空欄は「always」を意味し、誰でもインスタンスをリストできる様設定しています。

“compute:get_all”: “!”
APIによる許可を却下する事も可能です。感嘆符(!マーク)は「never」「nobody」を意味し、事実上“compute:get_all”を使用不可にしています。

“compute:get_all” : “role:admin”
実際は多くのAPIが管理ユーザからのみコールされるのですが、これについては”role:admin”ルールを使用します。ここでは、管理者のみが”compute:get_all”の使用を許可されます。

“stacks:create”: “not role:heat_stack_user”
各ロールに対してAPIを制限する事も可能です。このルールではnotを使用します。例えば、Orchestrationサービスはheat_stack_userというロールを定義しており、このロールを持っているとstack作成が許可されません。因みにandやor、()を活用する事で、より複雑なルールも設定可能です。

“deny_stack_user”: “not role:heat_stack_user”
ルールに対しエイリアス(別名称での登録)を定義する事も可能です。ポリシーエンジンは”deny_stack_user”をAPIではなくエイリアスとして理解します。

“stacks:create”: “rule:deny_stack_user”
上記で定義した”deny_stack_user”を使用して”stack_create”のAPIを制限しています。

“compute:start” : “user_id:%(user_id)s”
インスタンスオーナーのみが当該インスタンスを始動できる様設定しています。:(コロン)マーク左のuser_idには、APIユーザのユーザIDが記入されます。これはオブジェクト(この場合はインスタンス)のユーザID、もう少し正確に言うとデータベース内オブジェクトのuser_idと比較され、各値が同一の際は許可が付与されます。

“admin_required”: “role:admin or is_admin:1”,
“owner” : “user_id:%(user_id)s”,
“admin_or_owner”: “rule:admin_required or rule:owner”,
“identity:change_password”: “rule:admin_or_owner”

管理ユーザは常にAPIコールが許可されています。上記4行は/etc/keystone/policy.jsonが明示的にこのポリシーを作成するプロセスです。

1行目:“user is an admin user”のエイリアスを定義しています。is_adminフラッグはIdentityサービスの初回設定時のみ使用され、ユーザがサービストークン(keystoneコマンドラインクライアントの–os-tokenパラメータ)から付与された管理特権を所持することを意味します。

2行目:APIユーザIDとオブジェクトユーザIDを比較し、”user owns the object”のエイリアスを作成します。

3行目:3つ目のエイリアスとしてadmin_or_ownerを定義し、それ以前の2つのエイリアスとブールオペレータorを結合しています。

4行目:オーナーおよび管理ユーザのみがパスワードを修正できる様、ポリシーを設定しています。

policy.jsonの構造

ここまで具体的なルールサンプルをご紹介しましたが、次にpolicy.jsonの構造についても少し触れたいと思います。

policy.jsonファイルはポリシーとエイリアスにより構成されており、フォームとしては上記“<target名>”:”<rule名>”と”<alias名>”:”<definition名>”フォームが存在します。因みに,(カンマ)や{}(波括弧)は含まれません。

{
“alias 1” : “definition 1”,
“alias 2” : “definition 2”,

“target 1” : “rule 1”,
“target 2” : “rule 2”,
….
}

既に上述したものもありますが、各ルールは以下の様な特性を持っています。

(1)”” (空欄)、[]、@
常にtrueである事を意味し、アクションは必ず許可される。

(2)!
常にfalseである事を意味し、アクションは許可されない。

(3)not, or, and
シンプルなルールに基づいた、ブール式を採る。

(4)special check
<role>:<role名>:API証明が対象のロールを含むかテストします。
<rule>:<rule名>:エイリアスを定義します。
http:<target URL>:リモートサーバへチェックを要求します。サーバがTrueと返答した際にAPIを許可します。

ディベロッパーはその他のspecial checkについても定義する事が可能です。

(5)2つの値について
以下手法により比較されます。
“value1 : value2”

想定される各値としては以下の通りです。
・定数: 文字列, 数値, 正(true), 誤(false)
・APIの特性(project_idあるいはdomain_id)
・ターゲットオブジェクトの特性
・is_adminフラッグ

ターゲットオブジェクトの特性は、データベース内オブジェクトから発生したフィールドとなります。”compute:start”APIを例にすると、オブジェクトは開始されるインスタンスであるといえます。インスタンスを開始するポリシーは、インスタンスを所有するプロジェクトである%(project_id)s特性を使用可能です。最後のsは一連が文字列である事を示しています。

is_adminでは、管理トークンのメカニズム(keystoneコマンドの–os-tokenオプション)を経由して管理特権が与えられます。管理ロールが存在する前段階として、管理トークンはidentityデータベースの初期化を行います。

利便性を目的とするエイリアスでは、ルールを理解することの難解さや、複雑性を避けるために省略名が使用され、以下ポリシーと同様の手法で定義をされます。
alias name : alias definition

一度定義されたエイリアスをポリシールール内で使用するためには、ruleキーワードを使用します。

policy.jsonの旧型ファイルについて

 

javaScriptの配列がブールオペレータを代用する様な、異なるシンタックスにフィーチャーした旧policy.jsonファイルに遭遇する可能性もあります。例えば、上記のEC2証明ルールは以下の様に記述されます。

“identity:ec2_delete_credential”: [ [ “rule:admin_required ],
[ “rule:owner”, “user_id:%(target.credential.user_id)s)” ] ]

ルールは配列内の配列として存在します。最深部の配列がorである一方、最深部の配列内の要素はandとなっています。旧シンタックスが引き続きサポートされている場合も、より直感的な新規シンタックスを使用することが推奨されています。

おわりに

冒頭でも述べた通り、今回扱ったpolicy.jsonは非常に重要な役割を果たす一方、日々OpenStackを使用する上で、具体的な編集方法が中々見つからない(特に日本語で)のが現状です。

そういった問題意識から今回の様なコンテンツを作成しましたが、お役立て頂けましたら幸いです。情報が点在していたり、まだ十分でない点もオープンソースならではと言えますが、このシリーズでも少しつそういった穴を埋めていきたいですね。

今回も最後までお付き合いを頂き、ありがとうございました。

photo-1423256078872-f65d3d4471c2.jpg

最新記事

Category

Old Blogs