The best thing about the new Lambda form factor is how little it asks of you. One deploy and your app is in three regions behind one domain. The access model underneath is replicated with it, and it does not keep up.
What one command gives you
Two words carry this post. A revision is a frozen copy of your code and its settings, meaning the role it runs as, its environment variables and its timeout. An endpoint is the domain in front of it, with an auth type and a split of traffic across one or two revisions. Everything that follows is about what happens to those two things when they are copied across regions.
Pass --endpoint-type MultiRegion --regions and you get one Lambda-issued hostname with latency-based routing in front of a copy of your app in every region you listed. Because a revision never changes once created, a canary is just a traffic split, 90 to the old copy and 10 to the new, and rolling back means moving the split. Streaming is on by default, so server-sent events and token-by-token model output just work. Billing meters the CPU your code actually uses, so a request parked on a database call burns almost nothing, though memory still meters for as long as the environment is alive. Behind CloudFront, the new origin access control mode signs each request and still forwards the viewer's own Authorization header. You only have to add that header to the cache policy on every behavior that reaches the origin.
That is a lot of estate for one flag. The access model is replicated with it, and the replicas are where the trouble lives.
The revoke that takes a while
A Web Function has one resource policy. On a MultiRegion or PerRegion endpoint, Lambda copies that policy to every replica region on its own schedule. AWS's wording is that replication is eventually consistent, that a removed permission may still be honored in some regions until it completes, and that there is no customer-visible signal when it has.
Read that as an incident responder. You find a principal that should not be invoking your API. You remove it from the policy. For some window you cannot measure, Tokyo still lets it in. The documented containment path is the endpoint's throttleConfig.rateLimit. Each region enforces it independently, and unlike the policy you can watch it land region by region in regionalEndpoints.updateStatus. Set it to 0, confirm every region answers 503 with Platform.EndpointDisabled, then fix the policy, then lift the limit. Runbooks that lead with the policy edit are wrong for this resource.
Your secrets just moved
Revision configuration is replicated with the code, and revision configuration includes environment variables. An API key or a database URL kept in an environment variable is now at rest in every region the endpoint serves. With the default AWS-owned key that happens silently. With your own KMS key it needs a multi-region key with a replica in each region, and each replica carries its own key policy that you maintain. AWS is explicit that revoking key access is not an immediate traffic-containment step, because running environments keep cached key material. If the region set includes somewhere your residency review never approved, the review is wrong and nobody changed a line of code.
Two smaller edges land on the same list. A global endpoint that includes an opt-in region cannot sit behind CloudFront origin access control at all, because CloudFront cannot sign for that region and the origin returns 403. And an egress network connector, the only way to reach a private database, works on HomeRegion endpoints only. Lambda rejects a MultiRegion or PerRegion endpoint that points at a revision with a connector. So a multi-region app reaches its data over a public-facing path with its own auth, or it stays single-region. The flag is making an architecture decision.
You cannot prove who called
Invocation is a CloudTrail data event, off by default and billed separately. It is also a new resource type. A trail that already logs Lambda data events is logging AWS::Lambda::Function, and Web Function invocations arrive as AWS::Lambda::WebFunction, so the estate that thinks it has Lambda covered records nothing here until someone adds the second type. Once added, each event is recorded in the region that served the request and stays there, so the trail has to be multi-region as well.
The record has holes even then. AWS's own example event in the CloudTrail guide shows an unauthenticated invocation recorded with userIdentity.type: Unknown and nothing else, no principal, no ARN, and the guide says the access key field is never populated for any caller. A request with a missing, malformed or expired signature is not logged at all, because CloudTrail only records what gets past authentication. A request that arrives while the endpoint is disabled at rateLimit 0 is not logged either, which matters during the containment window above, when you most want to know who kept knocking. Ordinary throttles do appear, as ThrottlingException. And AWS says in so many words not to treat Web Function metrics and logs as an audit record. The audit is CloudTrail, CloudTrail is per region, and the two classes of request an attacker generates most, bad signatures and hits on a disabled endpoint, never reach it.
The policy is a shared document
PutResourcePolicy replaces the whole policy. Two teams adding statements the same afternoon, one for a partner account, one for a CloudFront distribution, will overwrite each other unless both pass the revisionId they read. If both pass the revisionId, the second write fails with a ConflictException. If a pipeline writes without a revision ID, nothing stops the overwrite, and the losing team's grant disappears without an error anywhere.
What to do about it
- Tag the function, inherit the control. Endpoints and revisions inherit the function's tags, so
aws:ResourceTagonInvokeWebFunctionEndpointgives you attribute-based access across every region. One tag on the function, one statement in the caller's policy, no per-region ARNs.
- Write the policy like a database row.
get-resource-policy, edit,put-resource-policy --revision-id. Make the pipeline fail on the conflict instead of winning it.
- Decide the region set with the data owner, not the deployer. Region sets are fixed at endpoint creation and cannot be changed, only replaced. Treat
--regionsas a residency decision that needs the same sign-off as a new bucket in a new region.
- Trail every region before the first global endpoint. A multi-region trail with data events on
AWS::Lambda::WebFunction, scoped by function ARN if the volume worries you.
- Put the rate limit first in the runbook.
rateLimit0, watch each region report 503, then the policy, then revision weights if you also need to roll back. Weight changes are asynchronous endpoint updates too, so pollupdateStatusbefore you call it done. Key revocation is not on this list because AWS says it is not an immediate containment mechanism. Deleting the endpoint is, since its domain is retired forever in every account.
