Access Policy Language (APL)

概要

Access Policy Language (APL) とは、バケットポリシーを設定するための言語です。

下の図と表は、リソースのアクセス制御を行うメインコンポーネントとのやりとりを示しています。

../_images/policy_02.png
  1. リソースの所有者

  2. リソース

    本サービスの内部にあるものです。バケット, オブジェクトなど。

  3. バケットポリシー
    本サービス内では、1バケットにつき1バケットポリシーとなります。
    本サービスのAPIはバケットポリシーの更新を行います。
  4. 複数の利用者からサービスへリクエスト

  5. Access Policy Language で書かれた評価コード

    来たリクエストに対して適用可能なバケットポリシーを評価し、リソースへアクセス可能/不可能を判断します。

Access Policy Language を使う

下の表は、Access Policy Languageを使用してどのようにアクセス制御がされるかを示しています。

../_images/policy_03.png
Access Policy Languageによるアクセス制御のプロセス
  1. バケットリソースに対してバケットポリシーを書きます。

  2. 本サービスへバケットポリシーをアップロードします。
    本サービスでは、バケットポリシーを更新できるAPIを提供しています。
    例えば、利用者はAPIの PUT Bucket policy を使用することで、バケットへバケットポリシーをセットすることができます。
  3. ユーザがリソースへリクエストします。
    例)あるユーザがバケットへオブジェクトをアップロードします。
  4. 本サービスは、そのリクエストへどのバケットポリシーが適用可能かを判断します。
    例)利用可能なすべてのバケットポリシーを見て、どれが適用可能かを判断します。
    (判断基準は対象のリソースが何か、リクエストしたユーザが誰か、などの情報から)
  5. 本サービスはバケットポリシーを評価します。
    例)バケットポリシーを見て、そのユーザがバケットへオブジェクトをアップロード可能かを判断します。
  6. サービスは、リクエストを拒否する、または、リクエストの処理を続行します。
    例)バケットポリシーの評価結果より、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は独立したものと見なします。

../_images/policy_01.png

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=AllowDefault Denyを上書きできます。
  • Effect=AllowExplicit Denyを上書きできません。

Explicit Deny

“Effect=Deny” の Statement を持つ結果です。

評価ロジック

評価処理のゴールは、与えられたリクエストの許可/拒否を決めることです。

評価ロジックは、下記のように幾つかのルールからなります。
  • デフォルトでは、リソースに対するリクエストは すべて拒否します。
  • Allow設定は、デフォルトの Deny設定を上書きします。
  • Explicit Deny設定は、Allow設定を上書きします。
  • バケットポリシーが複数存在する場合、評価結果は評価の順序に関与しない(どのバケットポリシーから評価しても同じ結果となる)。
../_images/policy_04.png
  1. Default Deny からスタートします。
  2. リクエストに適用可能なコードを実行し、評価します。
  3. それらのバケットポリシーの中から、リクエストに対してExplicit Denyを指示するものがあるかを確認します。1つでも存在する場合はDenyを返し、評価プロセスを終了します(Explicit Deny)。
  4. Explicit Denyが存在しない場合、次にAllowを指示するものがあるかを確認します。1つでも存在する場合はAllowを返し、評価プロセスを終了します。
  5. Allowが存在しない場合はDenyを返します(Default Deny)。

Explicit Deny と Default Deny

リクエストに直接適用するバケットポリシーがない場合Default Denyを返します。

Statement内のどのConditionにも該当しない場合Default Denyを返します。

Conditionが存在する場合は、バケットポリシー内のEffectタグの内容に従いAllowまたはDenyを返します。

例)Antarcticaから来たリクエストを拒否することを考えてみると、「Antarctica以外から来たリクエストを許可(Allow)する」というバケットポリシー(ここでは”Policy A1”と呼ぶ)を書くことができます。

../_images/policy_05.png

もしU.S.からリクエストが来た場合、(Antarcticaから来たリクエストではないため)このConditionが適用されます。従ってリクエストはAllowと評価されます。

もしAntarcticaからリクエストが来た場合は,このConditionは適用されないため、評価結果はDefault Denyとなります。

Explicit Denyを使用して、以下のようにバケットポリシーを書くこともできます(”Policy A2” と呼びます)。

../_images/policy_06.png

もしAntarcticaからリクエストが来た場合は このConditionが適用されるのでExplicit Denyが返されます。

Default DenyExplicit Denyの違いは重要でDefault DenyAllowにより上書きされますがExplicit Denyは上書きされません。

以下は「2010/06/01に到着したリクエストを許可(Allow)する」というもう1つのバケットポリシー(”Policy B” と呼ぶ)を考えた例です。
  • 「シナリオ1」はPolicy A1Policy Bの組み合わせです。
  • 「シナリオ2」はPolicy A2Policy Bの組み合わせです。
  • どちらにも「2010/06/01 にAntarcticaからリクエストを受け取った」というケースを流します。
../_images/policy_07.png
  • シナリオ1Policy A1は前述の通りDefault Denyを返します。Policy Bでは、リクエストが 2010/06/01に来ているのでAllowとなります。

    Policy Bの結果のAllowPolicy A1の結果のDefault Denyを上書きするため、リクエストは許可されます。

  • シナリオ2Policy A2Explicit Denyを返し、Policy BAllowを返します。

    Policy A2の結果のExplicit DenyPolicy Bの結果のAllowを上書きするため、リクエストは拒否されます。

APLの書き方

バケットポリシーの基本的な構造

バケットポリシーは、JSONドキュメントで表現され、下図のような情報を含みます。

  • 各バケットポリシーで共通の情報(オプション)
  • 1つ以上の個々のStatement

個々のStatementは、アクセス制御の命令セットを保持します。

バケットポリシーが複数のStatementを含む場合、評価時に論理和(OR)が適用されます。

Statementは、幾つかの要素の集合からなります。

../_images/policy_08.png

バケットポリシーの要素

全ての要素はオプションとなっています。

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"

Effect

結果としてAllowなのかExplicit Denyなのかを示す必須の要素です。

値は Allow または Deny のみが許可されます。
"Effect":"Allow"

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を持つことができます。

../_images/policy_09.png

Conditionブロックを作成する際、各Conditionの名前と少なくとも1つのKey-Valueペアを定義する必要があります。

使用できるKeyは、本システムで提供されているものがあります。

以下は、NumericEquals を使用した例です。
  • foo の値が A か B のどちらかである必要がある。
  • bar の値が C である必要がある。
../_images/policy_10.png

さらに 「2009/01/01以降のアクセスを拒否する」 という条件を追加したい場合、DateGreaterThan を使用します。

../_images/policy_11.png

Conditionブロック内のCondition間、およびCondition内のKey間では、論理積(AND)が適用されます。

単一KeyのValue間では、論理和(OR)が適用されます。

../_images/policy_12.png

使用できる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” と同義です。

表. Condition のキー一覧
キー 説明
iijgio:CurrentTime 日付/時刻 に関する条件
iijgio:SecureTransport リクエストがSSLを使用されているかを示すboolean値
iijgio:SourceIp リクエスト側のIPアドレス
iijgio:UserAgent リクエスト側のクライアントアプリケーションの種類
iijgio:EpochTime エポック時間からの経過秒
iijgio:Referer HTTP referer と同等

条件タイプ

一般的に指定可能な、条件タイプは以下の通りです。

  • 文字列
  • 数値
  • 日付と時刻
  • Boolean値
  • IPアドレス
  • リソース記述子 (GRN)

文字列の条件

文字列マッチング・ルールに従います。

表. Condition の文字列の条件
条件 説明
StringEquals
完全一致
【Short version】 streq
StringNotEquals
一致しない
【Short version】 strneq
StringEqualsIgnoreCase
完全一致(大文字・小文字の区別なし)
【Short version】 streqi
StringNotEqualsIgnoreCase
一致しない(大文字・小文字の区別なし)
【Short version】strneqi
StringLike
部分一致。

複数文字にマッチするワイルドカード(*)が使用可能です。

【Short version】 strl

StringNotLike
(部分的にも)一致しない

StringLike と同じく、ワイルドカード文字を使用可能です。

【Short version】 strnl

数値の条件

  • 数値マッチング・ルールに従います。
  • 整数・実数ともに指定可能です。
  • 分数表現や無理数はサポートしていません。
表. Condition の数値の条件
条件 説明
NumericEquals
値が一致する
【Short version】 numeq
NumericNotEquals
値が一致しない
【Short version】 numneq
NumericLessThan
Less than マッチング
【Short version】 numlt
NumericLessThanEquals
Less than or equals マッチング
【Short version】 numlteq
NumericGreaterThan
Greater than マッチング
【Short version】 numgt
NumericGreaterThanEquals
Greater than or equals マッチング
【Short version】 numgteq

日付の条件

  • 日付,時刻マッチング・ルールに従います。
  • 値はW3Cが規定するISO 8601日付フォーマットに従います。(http://www.w3.org/TR/NOTE-datetime
  • iijgio:CurrentTimeを指定すると、リクエスト時間を取得可能です。
  • ワイルドカードは指定不可です。
表. Condition の 日付の条件
条件 説明
DateEquals
完全一致
【Short version】 dateeq
DateNotEquals
一致しない
【Short version】 dateneq
DateLessThan
キーが無効になる時点の時間
【Short version】 datelt
DateLessThanEquals
キーが無効になる時点の時間
【Short version】 datelteq
DateGreaterThan
キーが無効になる時点の時間
【Short version】 dategt
DateGreaterThanEquals
キーが無効になる時点の時間
【Short version】 dategteq

Boolean値の条件

表. Condition の 真偽値の条件
条件 説明
Bool 完全一致

IPアドレスの条件

  • IPアドレスマッチング・ルールに従います。

  • 基本的には、条件と一緒に “iijgio:SourceIp” キーを使用する形になります。

  • 値は、標準CIDRフォーマットに従います。例: 10.52.176.0/24など

    詳細はhttp://www.rfc-editor.org/rfc/rfc4632.txtをご覧ください。

表. Condition の IPアドレスの条件
条件 説明
IpAddress ホワイトリスト・ベースのIPアドレス(範囲指定あり) 指定
NotIpAddress ブラックリスト・ベースのIPアドレス(範囲指定あり) 指定
リソース記述子 (GRN) の条件
  • GRNマッチング・ルールに従います。
  • 対象の値はString型です。
表. Condition のリソース記述子(GRN) の条件
条件 説明
GrnEquals
完全一致
【Short version】 arneq
GrnNotEquals
一致しない
【Short version】 arnneq
GrnLike
部分一致
GRNは6つのコロンで分割された値から成り、各部分には 複数文字にマッチするワイルドカード(*)および単一文字にマッチするワイルドカード(?)が指定可能です。
【Short version】 arnl
GrnNotLike
部分一致しない

GrnLikと同じく、ワイルドカード指定が可能です。

【Short version】arnnl

サンプル
{
    "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でなければなりません。

表. Access Policy Language でサポートしているデータ型
データ型 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つのバケットまたはリソースのみを対象とします。

    (バケットポリシーを書く際には、別バケットまたは別バケットにあるリソースを参照することはできません)

ページ先頭へ