Access Policy Language (APL)¶
概要¶
Access Policy Language (APL) とは、バケットポリシーを設定するための言語です。
下の図と表は、リソースのアクセス制御を行うメインコンポーネントとのやりとりを示しています。
リソースの所有者
- リソース
本サービスの内部にあるものです。バケット, オブジェクトなど。
- バケットポリシー
- 本サービス内では、1バケットにつき1バケットポリシーとなります。本サービスのAPIはバケットポリシーの更新を行います。
複数の利用者からサービスへリクエスト
- Access Policy Language で書かれた評価コード
来たリクエストに対して適用可能なバケットポリシーを評価し、リソースへアクセス可能/不可能を判断します。
- Access Policy Language を使う
下の表は、Access Policy Languageを使用してどのようにアクセス制御がされるかを示しています。
- Access Policy Languageによるアクセス制御のプロセス
バケットリソースに対してバケットポリシーを書きます。
- 本サービスへバケットポリシーをアップロードします。
- 本サービスでは、バケットポリシーを更新できるAPIを提供しています。例えば、利用者はAPIの PUT Bucket policy を使用することで、バケットへバケットポリシーをセットすることができます。
- ユーザがリソースへリクエストします。
- 例)あるユーザがバケットへオブジェクトをアップロードします。
- 本サービスは、そのリクエストへどのバケットポリシーが適用可能かを判断します。
- 例)利用可能なすべてのバケットポリシーを見て、どれが適用可能かを判断します。(判断基準は対象のリソースが何か、リクエストしたユーザが誰か、などの情報から)
- 本サービスはバケットポリシーを評価します。
- 例)バケットポリシーを見て、そのユーザがバケットへオブジェクトをアップロード可能かを判断します。
- サービスは、リクエストを拒否する、または、リクエストの処理を続行します。
- 例)バケットポリシーの評価結果より、Access Denied のエラーを返す、または処理を続行する。
Key の概念¶
Permission¶
Permissionとは、本サービスにおいて特定のリソースに対するアクセスを許可又は禁止する為の考え方です。
- Permissionは基本的に以下の形式を取ります。
AはBに対し、条件Cが成立する場合に操作Dを行う事ができる。
- 具体的には、たとえば以下のような内容となります。
ジェーン(A)はバケット「MyImage」(B)に対し、2012/12/31の午前0時までなら(C)オブジェクトをPUTする(D)事ができます。
この場合は、ジェーンがバケット「MyImage」に対してリクエストを送信する毎に、ジェーンがPermissionを与えられており、且つ送信されたリクエストが条件を満たしているかどうかを確認します。
Statement¶
Statementは宣言の中心的な要素になります。この要素は複数の要素を内包する事ができます(このマニュアルにあるサブ要素の項をご覧ください)。
- Statementは個別の宣言の配列を持ちます。個々の宣言は異なるJSONブロックであり、中括弧「{}」で括られています。
"Statement":[{...},{...},{...}]
Policy¶
Policyは 1つ以上のStatementを持ちますが、 各Statementは独立したものと見なします。
Principal¶
Principalは、バケットポリシーによって許可または不許可を与えられる対象となる利用者を表します。
Principalの指定には、本サービスのアクセスキーIDを使用し、プレフィックスにIIJGIO:を指定します。
アスタリスク「*」を用いる事で、匿名ユーザを含む全ての利用者として指定することもできます。
アクセスキーIDについては、サービスオンラインでご確認いただけます。
Note
(匿名ユーザを含む)全ての利用者を指定する場合には以下のように記述してください。
"Principal": {
"IIJGIO": "*"
},
複数の利用者を指定する場合は、以下のように配列で記述します。
"Principal": {
"IIJGIO": ["SAMPLE00000000000000", "SAMPLE00000000000001"]
},
Action¶
Principalが権限を与えようとしている行動を表します。
“A has permission to do B to C where D applies” の B に相当する。
ここで指定する Action名については、バケットポリシーご覧ください。
Resource¶
Resourceはバケットポリシーの影響の対象となるバケット、オブジェクトを表します。
値には、本システムが規定するフォーマットに従って指定する必要があります。
複数文字のワイルドカード”*”および単一文字のワイルドカード”?”が使用可能です。
Condition と Key¶
- Condition は、何らかの制約またはパーミッションの詳細を表します。
A has permission to do B to C where D applies.
のDに相当します。
- 代表的な Condition は、以下に関係します。
- 日付と時刻例: リクエストは、指定日よりも前に到着していなければならなりません。
- IPアドレス例: リクエストしたクライアントのIPアドレスは、特定のCIDR範囲になければならなりません。
Keyは、アクセス制約の基本的な特性を表します(例: リクエストの日時)。
ConditionとKeyの両方を使用してアクセス制限を表現することができます。
例)2010/05/30より前のアクセスを制限したい場合は、DateLessThanというConditionを使用し、値に2010-05-30T00:00:00Zを指定します。
Requester¶
本サービスへリクエストを出し、特定のリソースにアクセスしたのは誰かを表します。
Requesterは “Will you allow me to do B to C where D applies” というリクエストを出します。
Evaluation¶
本サービスが、受け取ったリクエストの許可/拒否をバケットポリシーに基づいて評価するプロセスです。
Effect¶
評価の際に返される結果です。
指定可能な値は、”Deny”, “Allow”の2つのみです。
- 以下の2つの例は、似ていますが異なります。
- 例1: 「Antarcticaから来たすべてのリクエストを拒否する」というバケットポリシーを設定したい場合==> Antarcticaに割り当てられたIPアドレスが使用されたリクエストに対してEffect=Denyを設定するということ
- 例2: 「Antarctica以外から来たすべてのリクエストを許可する」というバケットポリシーを設定したい場合==> Antarctica以外から来たリクエストに対してEffect=Allowを設定するということ
Default Deny¶
バケットポリシーにAllow,Explicit Denyのどちらも指定されていない場合の、デフォルトの結果値としてバケットポリシーはDenyとなります。
Allow¶
“Effect=Allow”のStatementを持つ結果です。
- 以下のことに注意する必要があります。
- Effect=AllowはDefault Denyを上書きできます。
- Effect=AllowはExplicit Denyを上書きできません。
Explicit Deny¶
“Effect=Deny” の Statement を持つ結果です。
評価ロジック¶
評価処理のゴールは、与えられたリクエストの許可/拒否を決めることです。
- 評価ロジックは、下記のように幾つかのルールからなります。
- デフォルトでは、リソースに対するリクエストは すべて拒否します。
- Allow設定は、デフォルトの Deny設定を上書きします。
- Explicit Deny設定は、Allow設定を上書きします。
- バケットポリシーが複数存在する場合、評価結果は評価の順序に関与しない(どのバケットポリシーから評価しても同じ結果となる)。
- Default Deny からスタートします。
- リクエストに適用可能なコードを実行し、評価します。
- それらのバケットポリシーの中から、リクエストに対してExplicit Denyを指示するものがあるかを確認します。1つでも存在する場合はDenyを返し、評価プロセスを終了します(Explicit Deny)。
- Explicit Denyが存在しない場合、次にAllowを指示するものがあるかを確認します。1つでも存在する場合はAllowを返し、評価プロセスを終了します。
- Allowが存在しない場合はDenyを返します(Default Deny)。
Explicit Deny と Default Deny¶
リクエストに直接適用するバケットポリシーがない場合Default Denyを返します。
Statement内のどのConditionにも該当しない場合Default Denyを返します。
Conditionが存在する場合は、バケットポリシー内のEffectタグの内容に従いAllowまたはDenyを返します。
例)Antarcticaから来たリクエストを拒否することを考えてみると、「Antarctica以外から来たリクエストを許可(Allow)する」というバケットポリシー(ここでは”Policy A1”と呼ぶ)を書くことができます。
もしU.S.からリクエストが来た場合、(Antarcticaから来たリクエストではないため)このConditionが適用されます。従ってリクエストはAllowと評価されます。
もしAntarcticaからリクエストが来た場合は,このConditionは適用されないため、評価結果はDefault Denyとなります。
Explicit Denyを使用して、以下のようにバケットポリシーを書くこともできます(”Policy A2” と呼びます)。
もしAntarcticaからリクエストが来た場合は このConditionが適用されるのでExplicit Denyが返されます。
Default DenyとExplicit Denyの違いは重要でDefault DenyはAllowにより上書きされますがExplicit Denyは上書きされません。
- 以下は「2010/06/01に到着したリクエストを許可(Allow)する」というもう1つのバケットポリシー(”Policy B” と呼ぶ)を考えた例です。
- 「シナリオ1」はPolicy A1とPolicy Bの組み合わせです。
- 「シナリオ2」はPolicy A2とPolicy Bの組み合わせです。
- どちらにも「2010/06/01 にAntarcticaからリクエストを受け取った」というケースを流します。
シナリオ1Policy A1は前述の通りDefault Denyを返します。Policy Bでは、リクエストが 2010/06/01に来ているのでAllowとなります。
Policy Bの結果のAllowがPolicy A1の結果のDefault Denyを上書きするため、リクエストは許可されます。
シナリオ2Policy A2はExplicit Denyを返し、Policy BはAllowを返します。
Policy A2の結果のExplicit DenyがPolicy Bの結果のAllowを上書きするため、リクエストは拒否されます。
APLの書き方¶
バケットポリシーの基本的な構造¶
バケットポリシーは、JSONドキュメントで表現され、下図のような情報を含みます。
- 各バケットポリシーで共通の情報(オプション)
- 1つ以上の個々のStatement
個々のStatementは、アクセス制御の命令セットを保持します。
バケットポリシーが複数のStatementを含む場合、評価時に論理和(OR)が適用されます。
Statementは、幾つかの要素の集合からなります。
バケットポリシーの要素¶
全ての要素はオプションとなっています。
Version¶
Versionは、Access Policy Languageのバージョンを示します。
- 現在は “2008-10-17” という値のみが許可されています。
"Version":"2008-10-17"
Id¶
Idはバケットポリシーの任意の識別子です。
一意性を確実にするため、ID には UUID を使うか、UUID を ID の一部にすることを推奨します。
本サービスでは、Id 要素を要求するよう実装しており、かつ一意な値にしておく必要があります。
Permission¶
Permissionは、特定のリソースに対してアクセスを許可または拒否するものです。
Permissionは基本的に “A is/isn’t allowed to do B to C where D applies” の形式に従います。
- 例)「Jane(A) has permission to receive messages (B) from John’s Amazon SQS queue (C)
- as long as she asks to receive them before midnight on May 30, 2009 (D)」
Statement¶
Statementはアクセス制御の命令セットです。Statement要素には複数のStatementを配列で指定することができます。
Statementが複数存在する場合は、それぞれの評価値の論理和(OR)が最終的な結果となります。
- Statement の記述は以下のようにJSONで表記します。
"Statement":[{...},{...},{...}]
Policy¶
Policyは1つ以上のStatementのコンテナとして位置づけられるドキュメントで、Access Policy Language (APL)によって記述されます。
- 例) Policy が以下の2つのStatementを持っています。
- Jane は John の オブジェクト を読むことができる。
- Bob は John の オブジェクト を読むことができない。
これは、個々のStatementを個別に保持している2つのバケットポリシーと同義です。つまり、分かれていてもまとまっていても同じ意味となります。
Issuer¶
Issuerはリソースに対してパーミッションを許可するPolicyを書いた人です。
Issuerは常にリソースの所有者となります。つまり、所有していないリソースにはバケットポリシーはセットすることができません。
Sid (Statement ID)¶
Policy Statementを提供する際の、任意の識別子です。
Policy Document ID(Id)のサブのIDといった位置づけです。
- 本サービスでは、本要素は必須で、ユニークな値が必要とされます。
"Sid":"1"
Principal¶
バケットポリシーの適用対象で、複数指定することができます。
Principalの値は、本システムのアクセスキーIDを使用します。
全てのユーザに適用できる“*”という値を指定することも可能です。
JSON内では、”IIJGIO:” をアクセスキーIDの接頭辞として使用します。
Action¶
Actionは、Allow/Denyを決めるアクセスの種類です。
本要素には、複数の値を記載することが可能です。
値の表記はフリーフォームですが、本サービスが期待する値とマッチする必要があります。
全てのアクションを示す “*” を値として指定することが可能です。
Resource¶
Resourceは、Statementの影響の対象とするリソース(バケット、もしくはオブジェクト)を指定します。
リソース記述子の書式に従い記述します。
grn:iijgio:dag:::mybucket/myobject
この値には、ワイルドカード文字(複数文字にマッチする”*” と単一文字にマッチする”?”)を含める事ができます。
代表的な設定を以下に示します。
バケットを指定する場合.. code-block:: json
grn:iijgio:dag:::mybucket
末尾に/を書きません。
オブジェクトを指定する場合.. code-block:: json
grn:iijgio:dag:::mybucket/オブジェクトのパス
特定のバケット内の全てのオブジェクトを指定する場合
grn:iijgio:dag:::mybucket/*
ResourceとActionの関連はPut Policy時にチェックされます。
Resourceがバケットを指す場合、バケットに関するActionだけが同一Statmentに記載出来ます。Resourceがオブジェクトを指す場合、オブジェクトに関するActionだけが同一Statmentに記載出来ます。同時に記載する必要がある場合はStatmentを分割して下さい。
- Put Bucket policyでエラーになる例
{ "Version": "2008-10-17", "Id": "aaaa-bbbb-cccc-dddd", "Statement": [ { "Effect":"Deny ", "Sid":"1", "Principal": { "IIJGIO": ["ACCESSKEYID000000001","ACCESSKEYID000000002"] }, "Action": ["dag:ListBucket","dag:PutObject","dag:GetObject"], "Resource": ["grn:iijgio:dag:::bucket","grn:iijgio:dag:::bucket/*"] } ] }- Put Bucket policyでエラーにならない例
{ "Version": "2008-10-17", "Id": "aaaa-bbbb-cccc-dddd", "Statement": [ { "Effect":"Deny ", "Sid":"1", "Principal": { "IIJGIO": ["ACCESSKEYID000000001","ACCESSKEYID000000002"] }, "Action": ["dag:ListBucket"], "Resource": "grn:iijgio:dag:::bucket" }, { "Effect":"Deny ", "Sid":"2", "Principal": { "IIJGIO": ["ACCESSKEYID000000001","ACCESSKEYID000000002"] }, "Action": ["dag:PutObject","dag:GetObject"], "Resource": "grn:iijgio:dag:::bucket/*" } ] }
Condition¶
Conditionブロック
Condition要素は、Policy Statementの中で一番複雑な部分です。
Condition要素は複数の条件を持ち、さらに各条件の中には複数のKey-Valueペアがあるので「Conditionブロック」と呼びます。
特定のKeyを除き、通常Keyは複数のValueを持つことができます。
Conditionブロックを作成する際、各Conditionの名前と少なくとも1つのKey-Valueペアを定義する必要があります。
使用できるKeyは、本システムで提供されているものがあります。
- 以下は、NumericEquals を使用した例です。
- foo の値が A か B のどちらかである必要がある。
- bar の値が C である必要がある。
さらに 「2009/01/01以降のアクセスを拒否する」 という条件を追加したい場合、DateGreaterThan を使用します。
Conditionブロック内のCondition間、およびCondition内のKey間では、論理積(AND)が適用されます。
単一KeyのValue間では、論理和(OR)が適用されます。
使用できるKeyは、本システムで提供されているものを使用します(例: 日時に基づいてアクセス制限したい場合にはiijgio:CurrentTimeを使用します)。
- 例として、以下の3つの Condition をアップロードしたいとします。
- 日時は 2010/08/16 12:00 以降である必要がある。
- 日時は 2010/08/16 15:00 より前である必要がある。
- リクエストの IP は、192.168.176.0/24 または 192.168.143.0/24 の範囲である必要がある。
Condition ブロックは3つの Condition から成り、このすべてを通過したものがリソースへアクセスできます
- この例のバケットポリシーは、以下のように書くことができます。
"Condition" : { "DateGreaterThan" : { "iijgio:CurrentTime" : "2009-04-16T12:00:00Z" }, "DateLessThan" : { "iijgio:CurrentTime" : "2009-04-16T15:00:00Z" }, "IpAddress" : { "iijgio:SourceIp" : ["19.168.176.0/224", "192.168.143.0/24"] } }
利用可能なキー
本システムで予め用意されているキーは、以下の通りです。
キー名は大文字・小文字は区別しません。つまりiijgio:CurrentTimeは “IIJGIO:currenttime” と同義です。
キー | 説明 |
---|---|
iijgio:CurrentTime | 日付/時刻 に関する条件 |
iijgio:SecureTransport | リクエストがSSLを使用されているかを示すboolean値 |
iijgio:SourceIp | リクエスト側のIPアドレス |
iijgio:UserAgent | リクエスト側のクライアントアプリケーションの種類 |
iijgio:EpochTime | エポック時間からの経過秒 |
iijgio:Referer | HTTP referer と同等 |
条件タイプ
一般的に指定可能な、条件タイプは以下の通りです。
- 文字列
- 数値
- 日付と時刻
- Boolean値
- IPアドレス
- リソース記述子 (GRN)
文字列の条件
文字列マッチング・ルールに従います。
条件 | 説明 |
---|---|
StringEquals |
|
StringNotEquals |
|
StringEqualsIgnoreCase |
|
StringNotEqualsIgnoreCase |
|
StringLike |
|
StringNotLike |
|
数値の条件
- 数値マッチング・ルールに従います。
- 整数・実数ともに指定可能です。
- 分数表現や無理数はサポートしていません。
条件 | 説明 |
---|---|
NumericEquals |
|
NumericNotEquals |
|
NumericLessThan |
|
NumericLessThanEquals |
|
NumericGreaterThan |
|
NumericGreaterThanEquals |
|
日付の条件
- 日付,時刻マッチング・ルールに従います。
- 値はW3Cが規定するISO 8601日付フォーマットに従います。(http://www.w3.org/TR/NOTE-datetime)
- iijgio:CurrentTimeを指定すると、リクエスト時間を取得可能です。
- ワイルドカードは指定不可です。
条件 | 説明 |
---|---|
DateEquals |
|
DateNotEquals |
|
DateLessThan |
|
DateLessThanEquals |
|
DateGreaterThan |
|
DateGreaterThanEquals |
|
Boolean値の条件
条件 | 説明 |
---|---|
Bool | 完全一致 |
IPアドレスの条件
IPアドレスマッチング・ルールに従います。
基本的には、条件と一緒に “iijgio:SourceIp” キーを使用する形になります。
値は、標準CIDRフォーマットに従います。例: 10.52.176.0/24など
詳細はhttp://www.rfc-editor.org/rfc/rfc4632.txtをご覧ください。
条件 | 説明 |
---|---|
IpAddress | ホワイトリスト・ベースのIPアドレス(範囲指定あり) 指定 |
NotIpAddress | ブラックリスト・ベースのIPアドレス(範囲指定あり) 指定 |
- リソース記述子 (GRN) の条件
- GRNマッチング・ルールに従います。
- 対象の値はString型です。
条件 | 説明 |
---|---|
GrnEquals |
|
GrnNotEquals |
|
GrnLike |
|
GrnNotLike |
|
- サンプル
{ "Statement":[{ "Effect": "Allow", "Principal": { "IIJGIO": "210987654321" }, "Action": "grn:GetObject", "Resource": "grn:iijgio:dag:::mybucket/myobject", "Condition": { "GrnEquals": { "iijgio:SourceGrn":"grn:iijgio:dag:::mybucket/myobject" } } }] }
サポートするデータ型¶
- Access Policy Languageは、以下のデータ型をサポートしています。
- 文字列
- 数値 (整数,実数)
- Boolean値
- Null
- List
- Map
- 構造体 (ネストされたMap)
以下は、シリアライズ(JSON)した際のデータ型とのマッピングです。
値はUTF-8でなければなりません。
データ型 | JSONのデータ型 |
---|---|
String | String |
Integer | Number |
Float | Number |
Boolean | true false |
Null | null |
Date | String (ISO 8601に従う) |
IpAddress | String (RFC 4632 に従う) |
List | Array |
Object | Object |
バケットポリシーの制約¶
- 以下は、本システムに関するバケットポリシーの制約情報です。
バケットポリシーの最大サイズは20KBです
Resourceに指定する値は、バケット名またはバケット名+パス文字列(bucket/*)で開始される必要があります。
各バケットポリシーは、ユニークな Policy ID (Id) を持ちます。
バケットポリシーの中の各Statementは、ユニークなStatement ID(Sid)を持ちます。
- 各バケットポリシーは、1つのバケットまたはリソースのみを対象とします。
(バケットポリシーを書く際には、別バケットまたは別バケットにあるリソースを参照することはできません)