はじめに
API Gatewayをプライベートなネットワークで利用したい場合、REST API(Private)を利用する案が出てくるかと思います。
その時、すべてのユーザーにAPIを自由に作成・削除できる権限を与えてしまうと、REST API(Private)以外のプロトコル・エンドポイントタイプで作成されてしまう可能性があります。
そのため、API自体の作成・削除は管理者が行い、他のユーザーはAPI内の変更のみできる権限を検証しました。
以下のドキュメントに記載されているポリシーを参考にしました。
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-private-api
作成ポリシー
実際に作成したポリシーは以下になります。
読み取り権限やAPI実行権限は別途付与されている想定として除外しています。
{
"Statement": [
{
"Action": [
"apigateway:PUT",
"apigateway:POST",
"apigateway:PATCH",
"apigateway:DELETE"
],
"Condition": {
"ForAllValues:StringEqualsIfExists": {
"apigateway:Request/EndpointType": "PRIVATE",
"apigateway:Resource/EndpointType": "PRIVATE"
}
},
"Effect": "Allow",
"Resource": [
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*/*/*",
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*/*",
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*"
],
"Sid": "APIGatewayAllowPolicy"
}
],
"Version": "2012-10-17"
}
背景
以下のドキュメントを見ていただくとわかりますが、API Gateway向けに定義されているアクションはそれほど多くはありません。
それらのアクションの中でもCreateRestApiやPutMethodなどのアクションは主に以下の5つのアクションに統合されています。
- GET
- POST
- PATCH
- PUT
- DELETE
そのため、CreateRestApiやDeleteRestApiだけ拒否するといった細かい権限制御がしづらくなっており、実現するために色々と検証したので、せっかくなので残しておこうと思ったのでこの記事書いています。
検証時の経緯
最初はAllowの権限を付与した上でAPI作成・削除機能のみDenyするアプローチを取っていたのですが、上述した細かい権限制御がしづらい理由から想定外の操作もDenyされてしまい、中々やりたいことが実現できませんでした。
そこでDenyするアプローチから、Allowで許可する範囲を限定するアプローチに変更したところ、これがうまくいきました。
特に工夫した箇所は以下のResource部分になります。
"Resource": [
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*/*/*",
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*/*",
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*"
],
Rource部分を実装する上で確認したのは以下のドキュメントです。
Amazon API Gateway Management で定義されるリソースタイプ
https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_amazonapigatewaymanagement.html
例としてDELETEアクションを見ていただくとわかるのですが、API Gatewayは1つのアクションに対して複数の操作権限が混在しているので、アクションで指定できるリソースタイプも複数あります。
そして各リソースタイプで指定できるARNの値を見てみると、かなり細かいARN構造となっていることがわかります。
その中でRest APIのARN構造を見てみると、以下のように最初に「restapis」があり、メソッドやステージなどのAPIを構成する要素は「restapis」の後ろに付与されるようになっていました。
arn:${Partition}:apigateway:${Region}::/restapis
arn:${Partition}:apigateway:${Region}::/restapis/${RestApiId}
arn:${Partition}:apigateway:${Region}::/restapis/${RestApiId}/resources
arn:${Partition}:apigateway:${Region}::/restapis/${RestApiId}/models
arn:${Partition}:apigateway:${Region}::/restapis/${RestApiId}/stages
・
・
・
その構造から、恐らくRest API作成削除時には以下のリソースタイプを対象としてCreateRestApiやDeleteRestApiが実行されると想定しました。
それを前提とすると、ポリシーのResource指定でそれらを含めなければ、リクエストに対してAllow権限を判定する際にResourceの記述が足りていないため、API作成削除操作ができなくなると考えました。
arn:${Partition}:apigateway:${Region}::/restapis
arn:${Partition}:apigateway:${Region}::/restapis/${RestApiId}
また、操作させたくないのはRest APIの作成と削除のみでメソッドの作成やステージの更新などはさせたいため、それを踏まえて以下のように設定しRest API内の要素は操作できるように実装をしました。
"Resource": [
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*/*/*",
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*/*",
"arn:aws:apigateway:ap-northeast-1::/restapis/*/*"
],
ConditionでリクエストとレスポンスのエンドポイントタイプがPrivateであることを指定しているので、これでRest API(Private)の要素のみの編集が可能な権限の完成です。
"Condition": {
"ForAllValues:StringEqualsIfExists": {
"apigateway:Request/EndpointType": "PRIVATE",
"apigateway:Resource/EndpointType": "PRIVATE"
}
},
おわりに
ユースケースとしてはあまりない内容な気がするので、果たして他の方の参考になるかはわからないのですが、この記事がどなたかの参考になれば幸いです。