Soracom

Users

ドキュメント

権限設定のためのパーミッション構文

SAM ユーザーに権限を設定するときの書式のことを「パーミッション構文」と呼びます。

例: Subscriber:listSubscribers および Group のすべてが、2021 年 2 月 1 日以降、IPv4 アドレスレンジ 10.0.0.1/24 のクライアントから利用可能になる設定

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

パーミッション構文は、JSON フォーマットに従っています。ここでは、各プロパティの意味や、設定する内容を説明します。

プロパティ説明
statements[]Arrayステートメントブロック (apieffectcondition の 3 つの要素が入ったオブジェクト) の配列です。
statements[].api *Arrayステートメントブロックが対象とする API を配列で指定します。詳しくは、API を指定する を参照してください。
statements[].effect *String

同じステートメントブロックの api に指定した API の利用を、SAM ユーザーに許可するか、禁止するかを指定します。

  • allow : api に指定した API の利用を許可します。
  • deny : api に指定した API の利用を禁止します。
statements[].conditionStringIPv4 アドレスや API を呼び出した時刻などを使用して、ステートメントブロックが有効になる条件を指定できます。詳しくは、条件を指定する を参照してください。
SAM で実現できないアクセス制御について

以下のようなアクセス制御は実現できません。

  • SIM グループ、LoRaWAN グループ、Sigfox グループごとに、閲覧の可否を制御することはできません。
  • 一部の IoT SIM のみ SIM 管理画面に表示するかどうかを制御することはできません。

一方、パスに {imsi} のようなプレースホルダーが含まれる API は pathVariable(placeholder) を使用して、利用を許可したり、禁止したりできます。

例:

このほかにもプレースホルダーが含まれる API は数多くあります。詳しくは、SORACOM API リファレンス を参照してください。

ステートメントブロックが有効になることと API の呼び出しが許可されることは別の概念です

condition で指定した条件を満たしたときに有効になるのは「ステートメントブロック」です。

つまり effectallow の場合は、condition で指定した条件を満たしたときに限り、API の実行が許可 (allow) されます。

一方で effectdeny の場合は、condition で指定した条件を満たしたときに限り、API の実行が禁止 (deny) されます。

JSON を入力する画面について

パーミッション構文に従った JSON は、以下のいずれかの画面で入力します。

  • SAM ユーザーの [権限設定][直接指定]。詳しくは、直接指定 を参照してください。
  • ロールの [権限設定]。詳しくは、ロールの作成 を参照してください。
パーミッション構文 (JSON) の例
そのほかの例は、「技術的なお問い合わせ」の SAM のパーミッション構文のサンプルはありますか? を参照してください。

API を指定する 

ひとつの api プロパティの中に、複数の API を指定できます。

例:

"api": [
  "Subscriber:listSubscribers",
  "Group:*"
]

: の前の部分を「サービス名」、: の後の部分を「オペレーション名」と呼びます。

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

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

SORACOM プラットフォームの機能と SORACOM API の対応については、SORACOM プラットフォームの機能と API の対応 を参照してください。

特定の API を指定する 

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

例: Subscriber:listSubscribers および Sim:listSims を対象とする

"api": [
  "Subscriber:listSubscribers",
  "Sim:listSims"
]

ワイルドカード (*) で複数の API をまとめて指定する 

api に指定するサービス名とオペレーション名には、ワイルドカード (*) を指定できます。サービス単位などでまとめて API を指定したり、似たような機能を持つ API をまとめて指定するときに便利です。

すべての API を対象にした場合でも、SAM ユーザーからルートユーザーのパスワードやメールアドレスを変更することはできません。

api プロパティに、1 件だけ指定する場合は、String でも指定できます。

"api": "*"

条件を指定する 

condition には、IPv4 アドレスや API を呼び出した時刻などを使用して、ステートメントブロックが有効になる条件を指定できます。

演算子、変数、関数の 3 つを組み合わせて、条件を指定できます。

項目説明
演算子比較演算子、論理演算子を利用できます。
変数currentDatecurrentDateTime などを利用できます。
関数currentDatecurrentDateTime と比較するための date(yyyy,MM,dd)dateTime(yyyy,MM,dd,HH,mm,ss) などを利用できます。
  • 例 1: 2021 年 1 月 27 日 15:00:00 以降に、ステートメントブロックを有効にする

    "condition": "currentDate >= dateTime(2021, 01, 27, 15, 00, 00);"
    
  • 例 2: クライアントの IPv4 アドレスが「10.0.0.1/24」に一致する場合に、ステートメントブロックを有効にする

    "condition": "ipAddress('10.0.0.1/24')"
    
  • 例 3: HTTP メソッドが GET の場合に、ステートメントブロックを有効にする

    "condition": "httpMethod('GET')"
    

    したがって、以下のように指定すると、HTTP メソッドが GET のすべての API が許可されます。

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

演算子 

比較演算子、論理演算子を利用できます。

かっこ () を使って評価の優先順位を指定できます

以下のように記載すると、かっこの中が先に評価されます。

"condition": "not (samUserName eq 'example-user-name')"

比較演算子 

文字列や数値を比較できます。

例:

"condition": "samUserName eq 'example-user-name'"
演算子説明
eq / ==

等しい

  • samUserName eq 'example-user-name'
  • samUserName == 'example-user-name'
  • currentDate eq date(2021,11,11)
  • currentDate == date(2021,11,11)
ne / !=

等しくない

  • samUserName ne 'example-user-name'
  • samUserName != 'example-user-name'
  • currentDate ne date(2021,11,11)
  • currentDate != date(2021,11,11)
lt / <

より小さい (*1)

  • currentDate lt date(2021,11,11)
  • currentDate < date(2021,11,11)
le / <=

より小さいか等しい (*1)

  • currentDate le date(2021,11,11)
  • currentDate <= date(2021,11,11)
gt / >

より大きい (*1)

  • currentDate gt date(2021,11,11)
  • currentDate > date(2021,11,11)
ge / >=

より大きいか等しい (*1)

  • currentDate ge date(2021,11,11)
  • currentDate >= date(2021,11,11)
matches

文字列が正規表現と一致する

  • samUserName matches 'example-.*'
  • (*1) 文字列の比較には利用しないでください。

論理演算子 

andornot を利用すると、複雑な条件を指定できます。

例:

"condition": "(samUserName eq 'example-user-name') and (currentDate eq date(2021,11,11))"
演算子説明
and

演算子の前後の条件の、両方を満たす

  • (samUserName eq 'example-user-name') and (currentDate eq date(2021,11,11))
or

演算子の前後の条件の、両方もしくは一方を満たす

  • (samUserName eq 'example-user-name') or (currentDate eq date(2021,11,11))
not / !

演算子の後の条件を満たさない

  • not (samUserName eq 'example-user-name')

変数 

ステートメントブロックを有効にする条件として、以下の変数を利用できます。

変数説明
currentDate現在の日付 (UTC) を表すオブジェクト。date(yyyy, MM, dd) で取得したオブジェクトと比較します。
currentDateTime現在の日時 (UTC) を表すオブジェクト。dateTime(yyyy, MM, dd, HH, mm, ss) で取得したオブジェクトと比較します。
sourceIpクライアントの IPv4 アドレスを表す文字列。例: 10.0.0.1198.51.100.1
より柔軟に指定する場合は、この sourceIp ではなく ipAddress(CIDR...) を使用してください。
httpMethodHTTP メソッドを表す文字列。例: GET POST PUT DELETE
より柔軟に指定する場合は、この httpMethod ではなく httpMethod(method...) を使用してください。
samUserNameAPI トークンを発行した SAM ユーザー名。SORACOM ユーザーコンソールの場合は、ログインした SAM ユーザー名です。pathVariable() と組み合わせても便利です。
変数と関数の使用例については、使用例 を参照してください。

関数 

ステートメントブロックを有効にする条件として、以下の関数を利用できます。

変数と関数の使用例については、使用例 を参照してください。

date(yyyy, MM, dd) 

日付 (UTC) を表すオブジェクトを取得します。

引数: 
引数説明
yyyyInteger
MMInteger月 (*1)
ddInteger日 (*1)
  • (*1) 数字が 1 桁の場合は、先頭の 0 は省略できます。
戻り値: 

日付 (UTC) を表すオブジェクトを返します。

例: 
date(2021, 01, 27)

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

日時 (UTC) を表すオブジェクトを取得します。

引数: 
引数説明
yyyyInteger
MMInteger月 (*1)
ddInteger日 (*1)
HHInteger時 (*1)
mmInteger分 (*1)
ssInteger秒 (*1)
  • (*1) 数字が 1 桁の場合は、先頭の 0 は省略できます。
戻り値: 

日時 (UTC) を表すオブジェクトを返します。

例: 
dateTime(2021, 01, 27, 15, 00, 00)
date(2021, 01, 27)dateTime(2021, 01, 27, 00, 00, 00) は、同じ値です。

ipAddress(CIDR...) 

API クライアントの IPv4 アドレスが、CIDR に指定した範囲に含まれているかどうかを判定します。

引数: 
引数説明
CIDRString (*1)API クライアントの IPv4 アドレスの範囲。CIDR 表記で指定します。
  • (*1) 複数指定できます。
戻り値: 

以下のいずれかの値を返します。

  • true : API クライアントの IPv4 アドレスが、CIDR に指定した範囲のいずれかに含まれています。
  • false : API クライアントの IPv4 アドレスが、CIDR に指定したどの範囲にも含まれていません。
例: 

API クライアントの IPv4 アドレスが 10.0.1.010.0.1.255 の範囲に含まれる場合に、true を返します。

ipAddress("10.0.1.0/24")

API クライアントの IPv4 アドレスが 10.0.1.010.0.1.255 または 10.0.2.010.0.2.255 の範囲に含まれる場合に、true を返します。

ipAddress("10.0.1.0/24", "10.0.2.0/24");

httpMethod(method...) 

API の HTTP メソッドが、methods に指定した HTTP メソッドと一致するかどうかを判定します。

引数: 
引数説明
methodString (*1)HTTP メソッド。大文字で指定します。
  • (*1) 複数指定できます。
戻り値: 

以下のいずれかの値を返します。

  • true : API の HTTP メソッドが、methods に指定した HTTP メソッドのいずれかと一致します。
  • false : API の HTTP メソッドが、methods に指定したどの HTTP メソッドとも一致しません。
例: 
httpMethod('GET', 'POST');

すべての API のうち GET メソッドおよび POST メソッドを使用する API のみを許可する場合の JSON は以下のとおりです。

{
  "statements": [
    {
      "effect": "allow",
      "api": "*",
      "condition": "httpMethod('GET', 'POST')"
    }
  ]
}
論理演算子 not と組み合わせないことをおすすめします

httpMethod(method...) と 論理演算子 not を組み合わせて、以下のように設定することもできます。

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

1 個目のステートメントブロックと、2 個目のステートメントブロックは、同じ効果があるように見えますが、これは同じではありません

  • 1 個目のステートメントブロックのように指定すると、HEAD メソッドを使用する FileEntry:getFileMetadata を呼び出せます。
  • 2 個目のステートメントブロックでは、この API は呼び出せません。

このように、not を組み合わせて許可 (allow) すると、今後、SORACOM API に、ほかの HTTP メソッド (例: PATCH メソッド) を使用した API が増えたときに、予期しない形で権限を許可することになります。そのようなことがないように、not と組み合わせない指定方法をおすすめします。

pathVariable(placeholder) 

API のパス中のプレースホルダーに指定した値を取得します。

たとえば、User:hasUserPassword のように、パス中にプレースホルダー ({operator_id}{user_name} などのこと) が含まれる API を呼び出したとき、プレースホルダー ({operator_id}{user_name}) に指定した値を取得できます。

異なるプレースホルダーが含まれる API は同じステートメントブロックに入れられません

1 つのステートメントブロックに、たとえば User:hasUserPasswordBilling:getBilling のように、異なる名前のプレースホルダーが含まれる API を入れて、かつ pathVariable(placeholder) を指定することはできません。

{
  "statements": [
    {
      "effect": "allow",
      "api": [
        "User:hasUserPassword",
        "Billing:getBilling"
      ],
      "condition": "pathVariable('user_name') == 'EXAMPLE-USER'"
    }
  ]
}

これは、Billing:getBilling を呼び出した際、評価対象のプレースホルダー {user_name} が存在しないために、pathVariable('user_name')null を返すための制限です。

これを回避するためには、ステートメントブロックを以下のように分けて指定してください。

{
  "statements": [
    {
      "effect": "allow",
      "api": [
        "User:hasUserPassword"
      ],
      "condition": "pathVariable('user_name') == 'EXAMPLE-USER'"
    },
    {
      "effect": "allow",
      "api": [
        "Billing:getBilling"
      ]
    }
  ]
}
引数: 
引数説明
placeholderStringプレースホルダー名。プレースホルダー名については、SORACOM API リファレンス を参照してください。
戻り値: 

指定したプレースホルダーの値が String 型で返されます。

パスにプレースホルダーが含まれなかった場合は、'null' が返されます。

例: 

SAM ユーザー EXAMPLE-USER のパスワードの更新 (User:updateUserPassword の呼び出し) を許可する場合の JSON は以下のとおりです。

{
  "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"
    }
  ]
}

使用例 

condition に変数と関数を組み合わせた場合の使用例は以下のとおりです。

  • 例 1: 2021 年 1 月 27 日以降に、ステートメントブロックを有効にする

    "condition": "currentDate >= date(2021, 01, 27)"
    

    数字が 1 桁の場合は、以下のように先頭の 0 は省略できます。

    "condition": "currentDate >= date(2021, 1, 27)"
    
  • 例 2: 2021 年 1 月 27 日 15:00:00 以降に、ステートメントブロックを有効にする

    "condition": "currentDateTime >= dateTime(2021,01,27,15,00,00)"
    
  • 例 3: 特定の IPv4 アドレス (10.0.0.1) からアクセスされた場合に、ステートメントブロックを有効にする

    "condition": "sourceIp == '10.0.0.1'"
    
    "condition": "sourceIp matches '10\.0\.0.*'"
    
  • 例 4: GET メソッドの API を呼び出す場合に、ステートメントブロックを有効にする

    "condition": "httpMethod == 'GET'"
    
  • 例 5: 特定のユーザーが発行した API トークンを利用して API を呼び出す場合に、ステートメントブロックを有効にする

    "condition": "samUserName == 'EXAMPLE-USER'"
    
  • 例 6: 特定のユーザーの情報に対する API 呼び出しの場合 (API パスにプレースホルダー {user_name} を含み、その値が特定のユーザーの場合) に、ステートメントブロックを有効にする

    "condition": "pathVariable('user_name') == 'EXAMPLE-USER'"