- AWS
Lambda関数URLの使い方|認証・CORS・ストリーミング
Lambda 関数 URL(Function URL)は、Lambda 関数に専用の HTTPS の URL を付ける機能です。 API Gateway を作らずに、https://<url-id>.lambda-url.<region>.on.aws の形の URL で関数を呼び出せます。URL の利用自体に追加の料金はかかりません(関数の実行分だけ)。
aws lambda create-function-url-config \
--function-name my-function \
--auth-type NONE \
--cors 'AllowOrigins=https://www.example.com,AllowMethods=GET,POST,MaxAge=300'
| 設定 | 値 | 意味 |
|---|---|---|
| AuthType | NONE |
認証なし(公開)。リソースベースポリシーで公開を許可する |
AWS_IAM |
IAM の SigV4 署名つきリクエストだけ受け付ける | |
| InvokeMode | BUFFERED(既定) |
関数の処理が終わってから返す。応答は最大 6 MB |
RESPONSE_STREAM |
書いた分から順に返す。応答は最大 200 MB | |
| Cors | AllowOrigins など6項目 |
ブラウザから別のオリジンで呼ぶときの設定 |
| Qualifier | エイリアス名か $LATEST |
URL を付ける対象(番号付きのバージョンには付けられない) |
確認環境:AWS CLI 1.46.1(botocore 1.43.62)の create-function-url-config・update-function-url-config・delete-function-url-config・add-permission を、moto 5.2.4 のサーバーモードに --endpoint-url で向けて実行し、CLI が送る API のパス・メソッド・本文を --debug で確かめました。ハンドラは Python 3.11 で、ドキュメントのイベント形式を渡して動かしました。認証・CORS・応答形式・ストリーミング・クォータは AWS のドキュメントで確かめた内容です(確認日 2026年10月13日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Lambda関数URLの使い方|認証・CORS・ストリーミング」
関数 URL を作る(AWS CLI)
1. 関数を用意する
関数 URL は、作成済みの関数に付けます。関数の作成は、関連記事「AWS CLIでLambdaを作成・更新 環境変数とレイヤー」で扱っています。
2. URL を作る:create-function-url-config
aws lambda create-function-url-config \
--function-name url-demo \
--auth-type NONE \
--cors 'AllowOrigins=https://www.example.com,AllowMethods=GET,POST,AllowHeaders=content-type,MaxAge=300'
--debug で見ると、CLI は次の API を呼んでいました。
POST /2021-10-31/functions/url-demo/url
{"AuthType": "NONE", "Cors": {"AllowOrigins": ["https://www.example.com"], "AllowMethods": ["GET", "POST"], "AllowHeaders": ["content-type"], "MaxAge": 300}}
--cors の省略形(Shorthand)では、AllowMethods=GET,POST のように「,」で区切った値がリストになりました。 戻り値の FunctionUrl が、呼び出しに使う URL です。
{
"FunctionUrl": "https://1f89d7b83e5441fba968aa0c9fd81cba.lambda-url.ap-northeast-1.on.aws",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:url-demo",
"AuthType": "NONE",
"Cors": { "AllowOrigins": ["https://www.example.com"], "AllowMethods": ["GET", "POST"], "AllowHeaders": ["content-type"], "MaxAge": 300 }
}
(moto が返した値。url-id の部分は作るたびに変わります)
Lambda 開発者ガイドの CLI 例には --cors-config と書かれていますが、AWS CLI 1.46.1 のオプション名は --cors でした。 --cors-config を付けると次のエラーになりました。
Unknown options: --cors-config, AllowOrigins=*
3. 公開するなら権限を2つ足す(AuthType NONE)
NONE でも、リソースベースポリシー(関数側の許可)で公開を許可しないと、403 Forbidden になります。 ドキュメントには「2025年10月から、新しい関数 URL には lambda:InvokeFunctionUrl と lambda:InvokeFunction の両方の権限が必要」とあります。ステートメントは1つずつ別のコマンドで足します。
# 1つめ:関数 URL 経由の呼び出しを許可
aws lambda add-permission \
--function-name url-demo \
--statement-id FunctionURLAllowPublicAccess \
--action lambda:InvokeFunctionUrl \
--principal '*' \
--function-url-auth-type NONE
# 2つめ:関数の実行を、関数 URL 経由に限って許可
aws lambda add-permission \
--function-name url-demo \
--statement-id FunctionURLInvokeAllowPublicAccess \
--action lambda:InvokeFunction \
--principal '*' \
--invoked-via-function-url
2つめのコマンドで CLI が送った本文は次の通りでした。--invoked-via-function-url は InvokedViaFunctionUrl: true になります。
POST /2015-03-31/functions/url-demo/policy
{"StatementId": "...", "Action": "lambda:InvokeFunction", "Principal": "*", "InvokedViaFunctionUrl": true}
ドキュメントに載っている、NONE のときにできるポリシーです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "FunctionURLAllowPublicAccess",
"Effect": "Allow",
"Principal": "*",
"Action": "lambda:InvokeFunctionUrl",
"Resource": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
"Condition": { "StringEquals": { "lambda:FunctionUrlAuthType": "NONE" } }
},
{
"Sid": "FunctionURLInvokeAllowPublicAccess",
"Effect": "Allow",
"Principal": "*",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
"Condition": { "Bool": { "lambda:InvokedViaFunctionUrl": "true" } }
}
]
}
lambda:InvokedViaFunctionUrl の条件があるので、2つめのステートメントは「関数 URL 経由の呼び出し」に限られます。 Invoke API での直接呼び出しまで公開するものではありません。zsh では * がファイル名に展開されるため、--principal '*' と引用符で囲みます。
4. 変更・確認・削除
# 認証や呼び出し方式を変える
aws lambda update-function-url-config \
--function-name url-demo \
--auth-type AWS_IAM \
--invoke-mode RESPONSE_STREAM
# 今の設定を見る
aws lambda get-function-url-config --function-name url-demo
# 削除する
aws lambda delete-function-url-config --function-name url-demo
| コマンド | CLI が呼んだ API |
|---|---|
create-function-url-config |
POST /2021-10-31/functions/{関数名}/url |
update-function-url-config |
PUT /2021-10-31/functions/{関数名}/url |
delete-function-url-config |
DELETE /2021-10-31/functions/{関数名}/url |
add-permission |
POST /2015-03-31/functions/{関数名}/policy |
--qualifier live を付けると、クエリ文字列 ?Qualifier=live が付き、エイリアス live 用の URL になりました。--auth-type を付けないと、送る前に CLI が the following arguments are required: --auth-type で止まりました。
ドキュメントによると、削除した URL は元に戻せず、作り直すと別の URL になります。 また、NONE の URL を削除しても、足したリソースベースポリシーは残ります。
AuthType:NONE と AWS_IAM
NONE |
AWS_IAM |
|
|---|---|---|
| 認証 | Lambda は認証しない | SigV4 で署名したリクエストだけ通す |
| 必要な許可 | リソースベースポリシーで Principal: "*" を許可 |
呼び出す側の IAM ポリシー(他アカウントなら関数側のポリシーも) |
| 必要なアクション | lambda:InvokeFunctionUrl と lambda:InvokeFunction |
同じ2つ |
| 向いている場面 | Webhook の受け口、公開 API(関数の中で独自に認証) | 社内のサービス間、CloudFront からの呼び出し |
requestContext.authorizer |
null |
呼び出し元の iam(userArn など)が入る |
AWS_IAM の URL を curl で呼ぶときは、--aws-sigv4 で署名します。 AWS のチュートリアルの形です(サービス名は lambda)。
curl --request GET "https://<url-id>.lambda-url.us-east-1.on.aws/" \
--user "AKIAIOSFODNN7EXAMPLE" \
--aws-sigv4 "aws:amz:us-east-1:lambda" \
--no-buffer
--user にアクセスキー ID を渡すと、シークレットアクセスキーを聞かれます。
イベントの形式(関数が受け取るもの)
関数 URL のイベントは、API Gateway HTTP API のペイロード形式 2.0 と同じ形です。 ドキュメントの例から主な項目を抜き出しました。
{
"version": "2.0",
"routeKey": "$default",
"rawPath": "/my/path",
"rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value",
"cookies": ["cookie1", "cookie2"],
"headers": { "header1": "value1", "header2": "value1,value2" },
"queryStringParameters": { "parameter1": "value1,value2", "parameter2": "value" },
"requestContext": {
"accountId": "123456789012",
"apiId": "<urlid>",
"authorizer": { "iam": { "userArn": "arn:aws:iam::111122223333:user/example-user" } },
"domainName": "<url-id>.lambda-url.us-west-2.on.aws",
"http": {
"method": "POST",
"path": "/my/path",
"protocol": "HTTP/1.1",
"sourceIp": "123.123.123.123",
"userAgent": "agent"
},
"requestId": "id",
"time": "12/Mar/2020:19:03:58 +0000",
"timeEpoch": 1583348638390
},
"body": "Hello from client!",
"pathParameters": null,
"isBase64Encoded": false,
"stageVariables": null
}
| 読みたいもの | 場所 |
|---|---|
| メソッド | event["requestContext"]["http"]["method"] |
| パス | event["rawPath"](URL の後ろはすべて関数に届く) |
| クエリ | event["queryStringParameters"](同じ名前は「,」でつながる) |
| ヘッダー | event["headers"](同じ名前は「,」でつながる) |
| 本文 | event["body"]。バイナリなら Base64 で isBase64Encoded: true |
| 呼び出し元の IP | event["requestContext"]["http"]["sourceIp"] |
pathParameters と stageVariables は null です。 ルーティング(/users/{id} のような分け方)は無いので、rawPath を見て関数の中で分けます。
応答の形式(関数が返すもの)
{
"statusCode": 201,
"headers": { "Content-Type": "application/json", "My-Custom-Header": "Custom Value" },
"body": "{ \"message\": \"Hello, world!\" }",
"cookies": [
"Cookie_1=Value1; Expires=21 Oct 2021 07:48 GMT",
"Cookie_2=Value2; Max-Age=78000"
],
"isBase64Encoded": false
}
statusCode を含まない JSON を返すと、Lambda が形を推測します。 ドキュメントの説明です。
| 関数の戻り値 | クライアントが受け取るもの |
|---|---|
{"statusCode": 201, "body": "..."} |
指定どおり(statusCode は 100〜599) |
{"message": "Hello, world!"}(statusCode なし) |
200、content-type: application/json、本文は戻り値の JSON |
"Hello, world!"(文字列) |
200、content-type: application/json、本文は "Hello, world!" |
Cookie は Set-Cookie ヘッダーではなく cookies の配列で返します。 Lambda が set-cookie ヘッダーに変換します。
Python のハンドラ例(コピペ用)
import base64
import json
def lambda_handler(event, context):
http = event["requestContext"]["http"]
body = event.get("body") or ""
if event.get("isBase64Encoded"):
body = base64.b64decode(body).decode("utf-8")
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"cookies": ["visited=1; Max-Age=3600; Secure; HttpOnly"],
"body": json.dumps({
"method": http["method"],
"path": event["rawPath"],
"query": event.get("queryStringParameters"),
"body": body,
"sourceIp": http["sourceIp"],
}, ensure_ascii=False),
}
rawPath が /orders、クエリが page=2、Base64 の本文 {"item":"本"} のイベントを渡すと、次の値が返りました。
{
"statusCode": 200,
"headers": { "Content-Type": "application/json" },
"cookies": ["visited=1; Max-Age=3600; Secure; HttpOnly"],
"body": "{\"method\": \"POST\", \"path\": \"/orders\", \"query\": {\"page\": \"2\"}, \"body\": \"{\\\"item\\\":\\\"本\\\"}\", \"sourceIp\": \"203.0.113.10\"}"
}
Python の handler の基本とローカルでのテストは、関連記事「AWS Lambda Python入門|3.14対応handler例とローカルテスト」で扱っています。
CORS の設定
ブラウザから別のオリジン(ドメイン)の関数 URL を呼ぶときは、関数 URL の Cors を設定します。 設定すると、Lambda がすべての応答に CORS のヘッダーを付けます。
| 設定項目 | 付くヘッダー | 例 |
|---|---|---|
AllowOrigins |
Access-Control-Allow-Origin |
https://www.example.com、* |
AllowMethods |
Access-Control-Allow-Methods |
GET、POST、* |
AllowHeaders |
Access-Control-Allow-Headers |
content-type、X-Custom-Header |
ExposeHeaders |
Access-Control-Expose-Headers |
X-Request-Id |
AllowCredentials |
Access-Control-Allow-Credentials |
true(CLI のヘルプでは既定 false) |
MaxAge |
Access-Control-Max-Age |
秒数。300 |
MaxAge の既定値は、AWS CLI 1.46.1 のヘルプでは「0(ブラウザはキャッシュしない)」、開発者ガイドの表では「5 (default)」と書かれていました。値を明示すると迷いません。
aws lambda update-function-url-config \
--function-name url-demo \
--cors '{"AllowOrigins":["https://www.example.com"],"AllowMethods":["GET","POST"],"AllowHeaders":["content-type"],"MaxAge":300}'
関数の中でも CORS ヘッダーを返すと重複する
ドキュメントでは、関数 URL の CORS 設定と、関数が返す CORS ヘッダーの両方があるときの動きが、リクエストの種類で違うと説明されています。
| リクエスト | 応答の CORS ヘッダー |
|---|---|
| プリフライト(OPTIONS) | 関数 URL の設定だけ |
| GET・POST など | 関数 URL の設定と関数の戻り値の両方(重複する) |
重複すると、ブラウザで次のエラーになります(ドキュメントの例)。
The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed
CORS は関数 URL の設定に寄せ、関数のコードからは返さないのが、ドキュメントの勧めです。CORS エラーの読み方は、関連記事「CORSエラーの原因と解決方法|エラーメッセージ別に解説」で扱っています。
レスポンスストリーミング
RESPONSE_STREAM にすると、関数が書いた分から順にクライアントへ送られます。 生成 AI の文章を少しずつ表示する、大きなファイルを返す、といった場面で使います。
| 項目 | BUFFERED | RESPONSE_STREAM |
|---|---|---|
| 内部で使う API | Invoke |
InvokeWithResponseStream |
| 応答の最大サイズ | 6 MB | 200 MB |
| 帯域 | ― | 最初の 6 MB は制限なし、その後は最大 2 MBps |
| 対応ランタイム | すべて | Node.js のマネージドランタイム(ほかはカスタムランタイムか Lambda Web Adapter) |
| VPC に置いた関数 | 使える | 関数 URL ではストリーミングできない |
aws lambda update-function-url-config \
--function-name my-streaming-function \
--invoke-mode RESPONSE_STREAM
Node.js のハンドラは、awslambda.streamifyResponse() で包みます。awslambda は Lambda の Node.js ランタイムが用意するグローバルなオブジェクトで、import はいりません。状態コードとヘッダーは awslambda.HttpResponseStream.from() で付けます。AWS のチュートリアルの形です。
// index.mjs
export const handler = awslambda.streamifyResponse(
async (event, responseStream, _context) => {
const metadata = {
statusCode: 200,
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
}
// 包んだあとのストリームを使う(包む前のものを使わないよう上書きする)
responseStream = awslambda.HttpResponseStream.from(responseStream, metadata)
for (let i = 0; i < 3; i++) {
responseStream.write(`Hello ${i}\n`)
await new Promise((r) => setTimeout(r, 1000))
}
responseStream.end()
await responseStream.finished()
},
)
curl --no-buffer "https://<url-id>.lambda-url.ap-northeast-1.on.aws/"
ドキュメントの注意点です。
- 書き終わったら
responseStream.end()で閉じる(pipeline()を使えば自動で閉じる)。 - Node.js 24 からは、ハンドラが返ったあとに残った Promise を Lambda が待たない。非同期の処理は
awaitする。 - クライアントが途中で切っても、関数は止まらず、実行した時間の分の料金がかかる。
- コンソールのテストでは、応答はバッファされて表示される。
API Gateway との比較
Lambda のドキュメント「HTTP リクエストで関数を呼ぶ方法の選び方」と、各サービスのクォータのページの内容を表にしました。
| 項目 | 関数 URL | API Gateway(HTTP API) | API Gateway(REST API) |
|---|---|---|---|
| 料金 | URL 自体は無料(関数の実行分だけ) | 呼び出し回数・転送量 | 呼び出し回数・転送量・キャッシュ |
| 待てる時間 | 関数のタイムアウト(最大 900 秒) | 最大 30 秒 | 50 ミリ秒〜29 秒(リージョン・プライベートは引き上げ可) |
| 本文のサイズ | 6 MB(ストリーミングは応答 200 MB) | 10 MB | 10 MB |
| 認証 | NONE か IAM |
IAM・JWT・Lambda オーソライザー | IAM・Cognito・Lambda オーソライザー・API キー |
| ルーティング | なし(rawPath を関数で見る) |
ルートごとに関数を分けられる | リソース・メソッドごと |
| 入力チェック・変換 | なし | ― | リクエストの検証・マッピングテンプレート |
| 流量の制限 | 関数の同時実行数(予約同時実行 ×10 が最大 RPS) | ステージ・ルート単位 | ステージ・メソッド単位、使用量プラン |
| 独自ドメイン | なし(CloudFront を前に置く方法がある) | あり | あり |
| WAF | ― | ― | あり |
| CORS | 設定だけで付く | 設定で付く | 自分で設定(OPTIONS メソッドなど) |
(「―」はドキュメントの比較で触れられていない項目)
ドキュメントの勧めは、関数 URL は「簡単なアプリや試作で、認証と入出力が基本的なもので足り、コストと手間を抑えたい」とき、API Gateway は「本番の大きな規模や、独自ドメイン・豊富な認証・流量制限・キャッシュ・変換などが要る」ときです。
29 秒(REST API)・30 秒(HTTP API)を超える処理を同期で返したいときは、関数 URL が候補になります。 API Gateway の REST API と HTTP API の違いは、関連記事「API Gateway Lambda|REST APIとHTTP APIの違い」、独自の認証は関連記事「API Gateway Lambdaオーソライザーの作り方|トークン型とリクエスト型」で扱っています。
SAM・CloudFormation で書く
SAM では FunctionUrlConfig を書きます。AuthType は必須、Cors と InvokeMode は省略できます(InvokeMode の既定は BUFFERED)。
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: index.handler
Runtime: nodejs22.x
FunctionUrlConfig:
AuthType: AWS_IAM
InvokeMode: RESPONSE_STREAM
Cors:
AllowOrigins:
- https://www.example.com
AllowMethods:
- GET
Outputs:
MyFunctionUrlEndpoint:
Value:
Fn::GetAtt: HelloWorldFunctionUrl.FunctionUrl
SAM のドキュメントでは、URL は既定で $LATEST に付き、AutoPublishAlias を設定するとそのエイリアスに付く、と説明されています。CloudFormation で直接書くときは AWS::Lambda::Url(AuthType・TargetFunctionArn が必須)を使います。
よくあるつまずき
| 症状 | 原因 | 直し方 |
|---|---|---|
NONE なのに 403 Forbidden |
リソースベースポリシーに許可が無い | InvokeFunctionUrl と InvokeFunction の2つを add-permission |
AWS_IAM で 403 |
署名が無い・権限が足りない | --aws-sigv4、呼び出す側に2つのアクションを許可 |
| 429 が返る | 予約同時実行の上限、または予約同時実行が 0 | 同時実行の設定を見直す(0 は URL を止める方法として案内されている) |
Access-Control-Allow-Origin が2つ付く |
関数 URL の CORS と関数の戻り値の両方 | 関数の戻り値から CORS ヘッダーを外す |
Unknown options: --cors-config |
オプション名の誤り | --cors |
| 番号付きバージョンに URL を付けられない | 仕様(エイリアスか $LATEST だけ) |
エイリアスを作って --qualifier |
| ストリーミングにならない | InvokeMode が BUFFERED、VPC の関数、コンソールのテスト |
RESPONSE_STREAM にし、curl --no-buffer で確かめる |
よくある質問
Q. 独自ドメインで公開できますか。 A. 関数 URL 自体には独自ドメインの設定がありません。CloudFront を前に置き、オリジンに関数 URL を指定する構成がよく使われます。
Q. VPC の中からだけ呼びたいです。 A. ドキュメントでは、関数 URL はパブリックなインターネットからだけ使え、AWS PrivateLink には対応していないとされています。閉じた経路が要るなら、API Gateway のプライベート API などを検討します。
Q. URL は変わりますか。 A. 作成した URL は変わりません。削除して作り直すと、別の URL になります。
まとめ
- 関数 URL は
create-function-url-config1つで HTTPS の URL が付く。URL 自体は無料 - AuthType は
NONEかAWS_IAM。2025年10月からInvokeFunctionUrlとInvokeFunctionの両方の許可が必要 - イベントは ペイロード形式 2.0。ルーティングは無いので
rawPathで分ける - CORS は関数 URL 側で設定し、関数のコードからは返さない
RESPONSE_STREAMで応答 200 MB まで。Node.js はawslambda.streamifyResponse- 30 秒を超える同期処理は関数 URL、独自ドメイン・豊富な認証・流量制限は API Gateway
参考・出典
確認日はいずれも 2026年10月13日です。
- AWS Lambda デベロッパーガイド「Creating and managing Lambda function URLs」:https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html
- AWS Lambda デベロッパーガイド「Control access to Lambda function URLs」:https://docs.aws.amazon.com/lambda/latest/dg/urls-auth.html
- AWS Lambda デベロッパーガイド「Invoking Lambda function URLs」:https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html
- AWS Lambda デベロッパーガイド「Response streaming for Lambda functions」:https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html
- AWS Lambda デベロッパーガイド「Writing response streaming-enabled Lambda functions」:https://docs.aws.amazon.com/lambda/latest/dg/config-rs-write-functions.html
- AWS Lambda デベロッパーガイド「Tutorial: Creating a response streaming Lambda function with a function URL」:https://docs.aws.amazon.com/lambda/latest/dg/response-streaming-tutorial.html
- AWS Lambda デベロッパーガイド「Select a method to invoke your Lambda function using an HTTP request」:https://docs.aws.amazon.com/lambda/latest/dg/furls-http-invoke-decision.html
- AWS Lambda デベロッパーガイド「Lambda quotas」:https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html
- Amazon API Gateway デベロッパーガイド「Quotas for configuring and running a REST API」:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-execution-service-limits-table.html
- Amazon API Gateway デベロッパーガイド「Quotas for configuring and running HTTP APIs」:https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-quotas.html
- AWS SAM デベロッパーガイド「FunctionUrlConfig」:https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-functionurlconfig.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Lambda関数URLの使い方|認証・CORS・ストリーミング」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。