SigV4 署名を計算出来ない環境下でAWS APIを実行する一例

[アローラ！](https://www.pokemon.jp/special/alola/guide)

最近は Slack のワークフローや Power Automate など、ノーコード・ローコードでワークフローを組めるサービスが増えてきました。もちろんAWSと組み合わせたいですよね。

しかしワークフローが.公式の「AWS コネクタ」やプラグインを提供していない場合、自力でAWS へのリクエストに必要な Signature Version 4（SigV4）を計算し、API呼び出し時にヘッダーに載せる必要があります。

私は、半日くらいかけてPowerAutomateで署名を作ろうと頑張ったのですが

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759541/8aa870be-85ef-448e-9c95-da8bf1858594.png" width=500>

（具体的にはSHA256でHMACを計算するところで巨人に食べられました。）

一番手っ取り早い方法としては、「メインロジックを含む Lambda をURL公開（関数URLなど）して、直接ワークフローから呼びだす」構成が考えられます。
ですが、それだと**本番運用のコアロジック**が **パブリックに晒される**形になってしまうため少し怖いですよね。


そこで**AWS Signature Version 4 の署名発行用エンドポイント**と**IAM 認証保護されたメインエンドポイント**を分離した構成を考えました。
本記事ではその紹介と使い方をご説明します。٩( ᐛ )و

## リポジトリ

https://github.com/iisyos/aws_issue_sigv4?tab=readme-ov-file


## アーキテクチャ概要

下図のように API Gateway に2つのパスを用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759541/60445abe-6f80-4392-8ade-fad7123433fa.png)

1. **`/sigv4`: SigV4 エンドポイント**  
   - `AccessKey` / `SecretKey` / `service` / `region` などを **POST** すると、`Authorization`, `X-Amz-Date` 等を計算して返すだけ。  
   - ここは一応パブリックでも可。ただし、IP制限やAPI Keyなどで保護するとなお良し。  
   - 実際のAWS操作は行わず、**あくまで署名文字列を返すだけ**なので、大事なロジックが晒されるリスクは低いです。

2. **`/`: メインエンドポイント**  
   - **AWS_IAM 認証**を設定し、**SigV4 署名つき**でないと呼べないよう保護。  
   - ここで実際のロジック（S3 への PUT、DynamoDB への書き込みなど）を行う。  
   - Public には公開されておらず、IAM のアクセス権限が必要。

この2つを繋ぎ合わせることで、ワークフローでは **2段階** の呼び出しを行い、  
署名ロジック自体はAWSのLambdaに任せる形にできます。

## 具体的な使い方

### (1) `/sigv4` に署名リクエストを送る

```bash
curl -X POST \
  -H "Content-Type: application/json" \
  https://<API_ID>.execute-api.<REGION>.amazonaws.com/prod/sigv4 \
  -d '{
    "accessKey": "YOUR_ACCESS_KEY",
    "secretKey": "YOUR_SECRET_KEY",
    "service":   "execute-api",
    "region":    "ap-northeast-1",
    "method":    "POST",
    "host":      "xxx.execute-api.ap-northeast-1.amazonaws.com",
    "path":      "/prod/",
    "payload":   "{\"some\":\"data\"}"
  }'
```

するとレスポンスには、こんな感じの `Authorization` ヘッダ等が含まれます。

```json
{
  "signedHeaders": {
    "Host": "xxx.execute-api.ap-northeast-1.amazonaws.com",
    "X-Amz-Date": "20250407T123456Z",
    "X-Amz-Content-SHA256": "xxxx",
    "Authorization": "AWS4-HMAC-SHA256 Credential=..."
  },
  "url": "https://xxx.execute-api.ap-northeast-1.amazonaws.com/prod/",
  "method": "POST"
}
```

### (2) 戻ってきた署名ヘッダを使ってメイン処理を呼ぶ

```bash
curl -X POST \
  "https://xxx.execute-api.ap-northeast-1.amazonaws.com/prod/" \
  -H "Host: xxx.execute-api.ap-northeast-1.amazonaws.com" \
  -H "x-amz-date: 20250407T123456Z" \
  -H "x-amz-content-sha256: xxxx" \
  -H "Authorization: AWS4-HMAC-SHA256 Credential=..." \
  -H "Content-Type: application/json" \
  -d '{"some":"data"}'
```

これで**IAM 認証が通った形**になり、メインの Lambda が実行されます。  
(“バイパス”というより、正規の V4 署名が付いているため通っているイメージです)


## Microsoft PowerAutomateとの連携例

1. **HTTP (POST)** で `/sigv4` にアクセス  
   - Body に `{accessKey, secretKey, region, service, …}` を JSON で送信  
2. **Compose (JSON Parse)** などで、返ってきた `Authorization` や `X-Amz-Date` を取り出す  
3. 再度 **HTTP (POST)** アクションで “メインエンドポイント” を呼ぶ  
   - 手順2で取り出したヘッダをセットして実行！

この2ステップさえ組めば、**Power Automate から AWS への SigV4 リクエストが可能**になります。

また、PowerAutomateのHTTPアクションは送信元IPが公開されているため、ホワイトリストで制御すればなお良さそうです🌷

https://qiita.com/hatanowf/items/95146ade23b90d852a26

https://learn.microsoft.com/ja-jp/azure/logic-apps/logic-apps-limits-and-config?tabs=consumption#outbound-ip-addresses

## まとめ

どうしても「外部サービス（ノーコード系）から AWS を呼び出したいが、SDK も SigV4 実装も無い…」という場合、**署名だけを発行するエンドポイント**と**IAM 保護の本エンドポイント**を分ける構成が便利です。  

再度になりますが、実際の実装サンプルは[こちらのリポジトリ](https://github.com/iisyos/aws_issue_sigv4)で Terraform 化しているので、よければどうぞ◎