Soracom

Users

ドキュメント

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

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

例: Subscriber:listSubscribers API および Group API のすべてが、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 API および Sim:listSims API を対象とする

"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 キーと API トークンを発行した 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 API を呼び出せます。
  • 2 個目のステートメントブロックでは、この API は呼び出せません。

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

pathVariable(placeholder)

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

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

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

1 つのステートメントブロックに、たとえば User:hasUserPassword APIBilling:getBilling API のように、異なる名前のプレースホルダーが含まれる 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 API の呼び出し) を許可する場合の 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 トークンを利用して API を呼び出す場合に、ステートメントブロックを有効にする

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

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