こんにちは。Supership の前田です。
この記事は Supershipグループ Advent Calendar 2025 の 3日目の記事です。
はじめに
AWSでAPIを提供して、他の特定のサーバーからのアクセスのみを許可したい状況があります。手法はいくつか存在しますが、ここではAPI GatewayのHTTP APIを使った方法を紹介します。
便宜上、APIを提供するアカウントを Provider、APIにアクセスするアカウントを Client とします。
⚠️ API Gatewayには2種類ありますが、今回はHTTP APIを取り扱うことに留意してください。
構成図
結論
Assume Role と AWS SigV4 を使えば可能です。
事前準備
-
Client は自身のAWS Account IDを Provider に伝えます
- 細かくアクセス制御をしたい場合はロールまで伝える必要がありますが、ここでは全てのロールを許可することにします
- Provider はAssume Role用のロールを作成し、信頼ポリシーとして登録します
ClientがAPIを呼び出す流れ
- Assume Roleを行い、一時的な認証情報を得ます
- AWS SigV4署名に認証情報を含めてリクエストします
HTTP APIにはIAMによる認可の機能があります。すなわち、Assume Roleを使えば他アカウントからのアクセスを制御できます。
Assume Roleについて簡単に説明すると、アクセスを許可するAWS Account IDを事前に登録しておけば、そのアカウントが別のアカウントのリソースにアクセスできる仕組みです。
AWS Signature Version 4 (SigV4)
SigV4署名を作成するときに必要な情報は以下の通りです。
| 項目 | 値 |
|---|---|
access_key |
Assume Roleで取得 |
secret_key |
Assume Roleで取得 |
session_token |
Assume Roleで取得 |
Region |
アクセス先のリージョン(例: ap-northeast-1) |
Service |
execute-api |
コマンド例
# 1. Assume Roleで一時的な認証情報を取得
CREDENTIALS=$(aws sts assume-role \
--role-arn arn:aws:iam::<PROVIDER_ACCOUNT_ID>:role/<ROLE_NAME> \
--role-session-name my-session \
--query 'Credentials' \
--output json)
export AWS_ACCESS_KEY_ID=$(echo $CREDENTIALS | jq -r '.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $CREDENTIALS | jq -r '.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $CREDENTIALS | jq -r '.SessionToken')
# 2. SigV4署名付きでAPIを呼び出す
curl --aws-sigv4 "aws:amz:ap-northeast-1:execute-api" \
--user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
-H "x-amz-security-token: $AWS_SESSION_TOKEN" \
"https://<API_ID>.execute-api.ap-northeast-1.amazonaws.com/<STAGE>/<PATH>"
💡 curlコマンドには
--aws-sigv4オプションが存在します
REST APIとの比較
| 観点 | HTTP API | REST API |
|---|---|---|
| 料金 | 安い | HTTP APIの約3.5倍 |
| ロールごとの制御 | Assume Roleが必要 | 不要(リソースポリシーで制御可) |
- 金銭コストを抑えたい → HTTP API
- Assume Roleの手間を減らしたい → REST API
REST APIには他にも様々な機能がありますが、ここでは割愛します。
他のアクセス制御方法
簡単に説明すると以下の方法が挙げられます。
- VPCプライベートリンク: Clientが別のAWSアカウントのVPC内サーバーからアクセスする場合に有効です
- 固定IPアドレスによる制御
余談
業務でAPI Gatewayを使って他のAWSアカウントからのアクセスを制御する必要が出てきました。インターネット上ではREST APIの情報が多い一方で、HTTP APIの情報はあまり見つかりませんでした。
私が調べた範囲では今回の問題を解決する方法はAWS re:Post(AWS公式のQ&Aページ)にのみ書かれていました。また、Claude Codeでそのサイトにアクセスを試みたところブロックされたため、Qiitaに載せることでAIエージェントにとっても情報を取得しやすくなると考えました。
参考
最後に宣伝です。
Supershipではプロダクト開発やサービス開発に関わる人を絶賛募集しております。
ご興味がある方は以下リンクよりご確認ください。
Supership 採用サイト
是非ともよろしくお願いします。
