ちょっと話題の記事

[新機能] API のアクセスコントロールが簡単に!API Gateway でリソースポリシーが設定可能になりました

API Gatewayでリソースポリシーが設定可能になり、IAMユーザやIPアドレスでのアクセス制御ができるようになりました。
2018.04.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、菊池です。

今回紹介する新機能はこちら。

API Gatewayでリソースポリシーが設定可能になり、IAMユーザやIPアドレスでのアクセス制御ができるようになりました。

API Gatewayにリソースポリシーを設定する

さっそく試してみます。公式ドキュメントに、リソースポリシーのサンプルも公開されていますので参考に設定します。

マネジメントコンソールからは、対象のAPIを選択すると、左のメニューに「リソースポリシー」があります。

画面下の、「AWSアカウントのホワイトリスト」「IP範囲のブラックリスト」を選択すると、サンプルのポリシードキュメントが表示されますので、簡単に設定ができそうです。

AWSアカウントのホワイトリスト

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::{{otherAWSAccountID}}:root"
          "arn:aws:iam::{{otherAWSAccountID}}:user/{{otherAWSUserName}}",
          "arn:aws:iam::{{otherAWSAccountID}}:role/{{otherAWSRoleName}}"
        ]
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "execute-api:/{{stageNameOrWildcard*}}/{{httpVerbOrWildcard*}}/{{resourcePathOrWildcard*}}"
      ]
    }
  ]
}

IP範囲のブラックリスト

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "execute-api:Invoke",
      "Resource": [
        "execute-api:/{{stageNameOrWildcard*}}/{{httpVerbOrWildcard*}}/{{resourcePathOrWildcard*}}"
      ],
      "Condition" : {
        "NotIpAddress": {
          "aws:SourceIp": [ "{{sourceIpOrCIDRBlock}}", "{{sourceIpOrCIDRBlock}}" ]
        }
      }
    }
  ]
}

今回は、簡単に試すことができそうな、IPアドレスによる制限を設定してみます。サンプルを参考に、以下のようにポリシードキュメントを設定してみます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:ap-northeast-1:xxxxxxxxxxxx:xxxxxxxxxx/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": "xxx.xxx.xxx.xxx"
                }
            }
        }
    ]
}

特定のIPアドレスからのアクセスを拒否します。リソースポリシーを設定・変更したら、APIのデプロイを必ず実行しましょう。デプロイしないとポリシーの反映が行われないようです。

設定できたら、アクセスして確認してみます。

許可されたIPからのアクセス

$ curl -i https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prd/
HTTP/2 200
date: Wed, 04 Apr 2018 01:59:35 GMT
content-type: application/json
content-length: 29
x-amzn-requestid: d2e9e7f3-37ab-11e8-b01b-xxxxxxxxxxxx
x-amz-apigw-id: EyytIE35tjMFSew=
x-amzn-trace-id: sampled=0;root=1-5ac43187-xxxxxxxxxxxxxxxxxxxxxx

"Hello from Lambda"

こちらは問題なくアクセスできました。

拒否対象のIPからのアクセス

$ curl -i https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prd/
HTTP/2 403
date: Wed, 04 Apr 2018 01:59:52 GMT
content-type: application/json
content-length: 159
x-amzn-requestid: dd20a6d6-37ab-11e8-9b3a-xxxxxxxxxxxx
x-amzn-errortype: AccessDeniedException
x-amz-apigw-id: EyyvzF-xxxxxxx=

{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:ap-northeast-1:********6521:xxxxxxxxxx/prd/GET/"}

拒否対象のIPからのアクセスでは、403のレスポンスとなっています。

最後に

リソースポリシーに対応したことで、API Gatewayに対するアクセス制御が手軽に設定可能になりました。IPアドレス以外にも、IAMにも対応してますので、クロスアカウントの制御なんかもできそうです。

クライアント側の制約で認証情報をコントロールできないケースなんかでも、サーバレスアプリケーションをプライベートに公開する手段になりますね。