AWS Lambda Function URLs: Direct HTTPS Endpoints Without API Gateway
Lambda Function URLs attach a dedicated HTTPS endpoint directly to a function, bypassing API Gateway. Learn the IAM auth model, a worked resource-based policy example, and the limits you hit without edge validation.
14 Feb 2026, 03:34 UTC

The short answer
Use a Lambda Function URL when a single function needs its own HTTPS endpoint and you do not need API Gateway's request validation, usage plans, or custom domain mapping. The feature attaches a dedicated HTTPS URL directly to the function, removing the extra network hop and the separate API Gateway bill. The trade-off is that all edge concerns—throttling, API keys, payload validation, and WAF inspection—become your responsibility inside the function or in a layer you add yourself.
How the endpoint and authentication work
A Function URL is a regional HTTPS endpoint that AWS generates for one function. The address follows the pattern https://<url-id>.lambda-url.<region>.on.aws. You choose one of two authentication modes when you create it:
NONE—the endpoint is open to the public internet. Anyone who knows the URL can invoke the function.AWS_IAM—callers must sign requests with Signature Version 4 (SigV4). The function's resource-based policy then decides which IAM principals are allowed to invoke the URL.
When a request arrives, Lambda packages it as a JSON event and passes it to your handler. The event contains the HTTP method, path, headers, body, and request context. Your handler returns a JSON object with statusCode, headers, and body. You can also configure Cross-Origin Resource Sharing (CORS) on the URL itself, which controls which browser origins may call the endpoint.
Access control for AWS_IAM mode is separate from the function's execution role. The execution role grants the function permission to call other AWS services. The resource-based policy attached to the function grants callers permission to reach the URL.
Worked example: an IAM-protected webhook receiver
Suppose an internal service running under the IAM role WebhookCallerRole needs to POST events to a Lambda function named webhook-handler. You want to expose the function over HTTPS without opening it to the internet.
1. Handler code
The handler receives the HTTP details inside requestContext.http. A minimal Python handler looks like this:
import json
def handler(event, context):
http = event.get('requestContext', {}).get('http', {})
method = http.get('method')
path = http.get('path')
if method != 'POST':
return {
"statusCode": 405,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({"error": "Method not allowed"})
}
# Application logic: parse event['body'], validate, enqueue, etc.
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({"status": "accepted"})
}
2. Resource-based policy
Attach a policy to the function that allows only the caller role to invoke the URL. In the Lambda console, open the function's Permissions tab and add a resource-based policy statement, or apply the equivalent JSON:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowWebhookCaller",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/WebhookCallerRole"
},
"Action": "lambda:InvokeFunctionUrl",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:webhook-handler"
}
]
}
Replace 123456789012 with your account ID and us-east-1 with your deployment region.
3. Create the URL with IAM auth
In the console, go to Configuration > Function URL and set the auth type to AWS_IAM. If you prefer the CLI, the command shape is:
aws lambda create-function-url-config \
--function-name webhook-handler \
--auth-type AWS_IAM
Run this from a shell or CI environment whose credentials have lambda:CreateFunctionUrlConfig and lambda:AddPermission permissions.
4. Verify the result
An unsigned request should be rejected. From any terminal with outbound internet access:
curl -i https://<url-id>.lambda-url.us-east-1.on.aws
Expected check: you should receive an HTTP 403 response because the request lacks a SigV4 signature. A signed request from WebhookCallerRole should reach the handler and return the 200 response defined above.
Limits and common mistakes
Function URLs solve a narrow problem well, but they lack several capabilities that API Gateway provides natively.
| Capability | Lambda Function URL | API Gateway |
|---|---|---|
| Custom domain name | Not supported natively | Supported |
| Request validation / schema enforcement | Not available | Available |
| API keys and usage plans | Not available | Available |
| AWS WAF integration | Only via CloudFront in front | Native for REST and HTTP APIs |
| Per-client throttling | Not available | Available |
No custom domains
The URL always uses the AWS-generated lambda-url pattern. If you need api.example.com, you must place Amazon CloudFront or API Gateway in front of the Function URL. That adds cost and configuration, which may erase the simplicity advantage.
Public mode is fully public
Choosing AUTH_TYPE_NONE exposes the function to the entire internet. The URL identifier is not a secret and should not be treated as one. If you use public mode, implement application-level authentication (for example, a shared secret in a header) and consider fronting the URL with CloudFront and WAF to block abusive traffic.
Edge validation is your job
Because there is no built-in request validation, malformed payloads, oversized bodies, and unexpected content types all reach your function. Validate the body, headers, and query parameters inside the handler. Return 4xx responses early to avoid wasted execution time.
CORS is not authorization
Configuring CORS allowed origins controls browser behavior, not server-side access. A non-browser client can still call the endpoint regardless of CORS settings. Use AWS_IAM or application-level checks for actual authorization.
Removing the endpoint
If you need to undo the change, delete the URL configuration. This stops public or IAM invocation immediately:
aws lambda delete-function-url-config \
--function-name webhook-handler
Deleting the URL does not delete the function or its code.
A practical way to check your work
After deployment, confirm three things: the auth type shown in the console or get-function-url-config output matches your intent; the resource-based policy lists only the principals you expect; and an unsigned curl to the URL returns 403 when AWS_IAM is selected. If any of these differ, revisit the policy attachment before sending production traffic. Because AWS service capabilities evolve, verify the current CLI syntax and console layout in the AWS documentation before deploying to production.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.