Soracom

Users

ドキュメント

SAM アクセス権限設定のためのパーミッション構文

はじめに 

SORACOM Access Management (SAM) を利用すると、SAM ユーザーに対してコンソールおよび API のアクセス権限の制御を行うことが可能になります。

このアクセス権限制御を行うための書式のことを、「パーミッション構文」と呼びます。

パーミッション構文を使って記述した内容を SAM ユーザーに直接権限設定するか、もしくはロールに設定することで、アクセス権限の制御を柔軟に行うことができます。

パーミッション構文の構成 

パーミッション構文は、JSON 形式で表されます。JSON は以下の様な構造をとります。

構文例 

{
  "statements": [
    {
      "effect": "allow",
      "api": ["Subscriber:list*", "Group:*"],
      "condition": "currentDate >= date(2016, 02, 01) and ipAddress('10.0.0.1/24')"
    }
  ]
}

statements が、中に構文が入るルート要素です。statements の中には、api,effect,condition の 3 つの要素が入ります。 この 3 つの要素が入ったオブジェクトをステートメントブロックと呼びます。

パーミッションは複数のステートメントブロックから構成されます。この例ではステートメントブロックが 1 つですが、要素としては配列になっていることに注意してください。

上記の例では、Subscriber API の list の名前のつく API と Group API のすべてが、2016 年 2 月 1 日以降、IP アドレスレンジ 10.0.0.1/24 のクライアントから利用可能になる、という意味になります。

またこの API の制限はそのままユーザーコンソールに反映されるため、コンソールでも Subscriber の list (SIM の一覧を取得する操作) とグループに対する操作が可能になり、それ以外の操作はできません。

以下に、ステートメントブロックの各要素について説明をしていきます。

effect (必須) : API 実行の許可または拒否 

effect 要素は、allow もしくは deny のいずれかの値がセットできます。この要素はステートメントブロックの中で必須となります。

この要素は、ステートメントブロックが API 実行を許可 (allow) を示すものか、拒否 (deny) を示すものかを設定する要素です。

  • allow: ステートメントブロックがマッチする API 呼び出しが行われた場合、API の利用を許可します。
  • deny: 他のパーミッション構文に API 呼び出しにマッチする allow のステートメントブロックがあった場合でも、API の利用を拒否します。

api (必須) : 対象 API 

ステートメントブロックが対象とする API を指定します。この要素はステートメントブロックの中で必須となります。

api に記述する値は、Subscriber:listSubscribers のように記述します。Subscriber の部分はサービス名を示し、listSubscribers の部分はオペレーション名を示します。

サービス名およびオペレーション名は SORAOCM API リファレンス で確認できます。

サービス名とオペレーション名

特定の API を指定する 

特定の API を指定するには、サービス名とオペレーション名を指定します。

  • 例: listSubscribers API だけを対象とする
	"api": ["Subscriber:listSubscribers"]

ワイルドカードで API を指定する 

サービス名、オペレーション名には以下のようにワイルドカードで指定することもできます。サービス単位などでまとめて API を指定するにはワイルドカードを使うと便利です。

  • 例: Subscriber サービスの list 系の API をすべて対象にする
	"api": ["Subscriber:list*"]

またサービス名を省略して * とすることで、すべての操作を対象にできます。

  • 例: すべての API を対象にする
	"api": "*"

なお、すべての API を対象にした場合でも、オペレーター (ルートアカウント) のパスワード変更やメールアドレス変更などのオペレーター (ルートアカウント) に対する API は実行できません。

複数 API を指定する 

API をリスト形式で記述すると、複数の API を同時に指定できます。リスト指定の場合は、OR で条件マッチを行います。

  • 例: Subscriber の一覧取得とグループ設定の API を対象にする
	"api":["Subscriber:listSubscribers","Group:*"],

condition (オプション) : 条件 

condition は、IP アドレスや時刻などを使用して、ステートメントブロックがマッチする条件を指定できます。condition はオプション要素となりますので、指定してもしなくても構いません。

例えば、以下のようなユースケースに適用できます。

  • 例: ある特定の日時からパーミッション構文を有効にする
"condition": "currentDate >= date(2016,01,27)"

このように記述すると、「2016 年 1 月 27 日以降」という条件指定になります。

  • 例: API クライアントの IP 制限をかける
"condition": "ipAddress('10.0.0.1/24')"

IP アドレスが 10.0.0.1/24 の範囲内にあるものだけ、という指定になります。

  • 例: API 単位ではなく、HTTP メソッド単位で指定する
"condition": "httpMethod('GET')"

HTTP GET メソッドの API、という指定になります。

演算子 

condition には演算子を使用でき、複雑な条件を記述できます。下記の演算子を利用できます。

比較演算子 

  • eq (==)
  • ne (!=)
  • lt (<)
  • le (<=)
  • gt (>)
  • ge (>=)
  • matches 正規表現で文字列マッチを実施します。

論理演算子 

  • and
  • or
  • not (!)

数値演算子 

  • +
  • -
  • *
  • div (/)
  • mod (%)

変数 

condition 中には、下記の変数を利用できます。

  • currentDate: 現在日 (yyyyMMdd) (UTC)
  • currentDateTime: 現在時刻 (yyyyMMddHHmmss) (UTC)
  • sourceIp : ソース IP アドレス
  • httpMethod: HTTP メソッド (GET/POST/PUT/DELETE などの文字列)
  • samUserName: ログインしている SAM ユーザー (つまり自分自身の SAM ユーザー名)

currentDate 

現在日が代入されています。おもに後述する date 関数と組み合わせて利用します。

  • 例: 特定の日付より後を条件とする
"condition": "currentDate >= date(2016,01,27)"

currentDateTime 

現在日時が代入されています。主に、後述する dateTime 関数と組み合わせて利用します。

  • 例: 特定の日時より後を条件とする
"condition": "currentDateTime >= dateTime(2016,01,27,15,00,00)"

sourceIp 

API クライアントの IP アドレスが文字列として代入されています。IP 制限を行いたい場合に、eqmatch 演算子を利用して記述する利用法があります。

  • 例: 特定の IP からのアクセスを条件とする
"condition": "sourceIp == '10.0.0.1'"
"condition": "sourceIp matches '10\.0\.0.*'"

より柔軟に指定したい場合は、変数を使った IP アドレス指定よりも、後述の ipAddress() 関数を使用することを推奨します。

httpMethod 

API の HTTP メソッドが文字列として代入されています。

  • 例: GET 操作のみ許可する
"condition": "httpMethod == 'GET'"

より柔軟に指定したい場合は、後述の httpMethod() 関数を指定することを推奨します。

samUserName 

ログインしている SAM ユーザーの名前、すなわち自分自身の SAM ユーザー名が文字列として代入されています。

  • 例: 特定のユーザーを条件とする
"condition": "samUserName == 'EXAMPLE-USER'"

この変数は、後述の pathVariable() 関数と組み合わせることで柔軟な権限管理を行うことが可能です。

関数 

condition 中には、下記の関数を利用できます。

date(yyyy,MM,dd) 

  • 例:
date(2016, 01, 27);

1 桁の数字の引数は 011 の両方が記述できます。

dateTime(yyyy,MM,dd,HH,mm,ss) 

  • 例:
dateTime(2016, 01, 27, 15, 00, 00);

1 桁の数字の引数は 011 の両方が記述できます。

date(2016,01,27)dateTime(2016,01,27,00,00,00) は同義です。

ipAddress(CIDR…) 

API クライアントの IP アドレスが指定範囲内になっているかを判定します。

  • 例:
ipAddress("10.0.0.1/24");

アドレスは CIDR 記法で指定します。上記の例では、IP アドレスが 10.0.0.110.0.0.254 の範囲となります。引数は複数指定できます。

ipAddress("10.0.0.1/24", "10.0.0.2/24");

OR 条件で評価されますので、この場合は IP アドレスが 10.0.0.110.0.0.25410.0.1.110.0.1.254 の範囲ということになります。

httpMethod(methods…) 

API の HTTP メソッドが引数の methods になっているかを判定します。

  • 例:
httpMethod("GET");

例えば、すべての API のうち GET メソッドの API のみを許可する、といった使い方ができます。その場合のパーミッション構文は以下のようになります。

{
  "statements": [
    {
      "effect": "allow",
      "api": "*",
      "condition": "httpMethod('GET')"
    }
  ]
}

引数は複数指定できます。

  • 例:
httpMethod("GET", "POST");

引数は OR 条件で評価されますので、この場合は GET と POST メソッドの API のみ、という指定になります。

演算子 not と組み合わせることもできます。例えば、以下のような statement では、DELETE メソッドの API は許可しない、という評価になり、結果的に DELETE メソッド以外すべての API 実行が allow (許可) と評価されます。

{
  "statements": [
    {
      "effect": "allow",
      "api": "*",
      "condition": "not httpMethod('DELETE')"
    }
  ]
}

ただ、この記述はわかりにくいので、引数を複数取れることを利用して、明示的に

"condition":"httpMethod('GET', 'POST', 'PUT')"

と記述する方が分かりやすくなります。

pathVariable(placeholder) 

API のパス中のプレースホルダーに含まれている値を返します。

例えば、/operators/{operator_id}/users/{user_name}/password というパス定義を持つ API がある時、 実際の API 呼び出しが /operators/OP9999999999/users/EXAMPLE-USER/password というパスで行われた場合、 pathVariable('operator_id')OP9999999999pathVariable('user_name')EXAMPLE-USER がそれぞれ返却されます。

  • 例:

以下のように記述すると、user_name (すなわちログインしている SAM ユーザーの名前) が EXAMPLE-USER の場合のみ SAM ユーザーのパスワードの変更を許可することができます。

{
  "statements": [
    {
      "effect": "allow",
      "api": "User:updateUserPassword",
      "condition": "pathVariable('user_name') == 'EXAMPLE-USER'"
    }
  ]
}
右辺値に具体的な値を設定する際は文字列型として入力する必要があります。つまり上記の例のように、右辺値をシングルクォーテーションでクォートする必要があることに注意してください。

この記法を samUserName 変数と組み合わせると、SAM ユーザーが自分自身のパスワードのみを変更すること を許可できる (つまり、他 SAM ユーザーのパスワード変更処理は拒否する) ようになります。

{
  "statements": [
    {
      "effect": "allow",
      "api": "User:updateUserPassword",
      "condition": "pathVariable('user_name') == samUserName"
    }
  ]
}

API のパス定義及びプレースホルダーの定義については API Reference を参照してください。

パーミッション構文の例 

パーミッション構文の例は よくあるご質問 をご覧ください。