Two new capabilities are available in UDP Gateway today. The first allows WireGuard Listeners to accept connections from any client without pre-registration — the same model HTTPS uses for websites. The second allows Lambda destinations to be invoked asynchronously, firing a packet into a long-running workflow without the Gateway waiting for a response. Together they open up a class of public-facing, event-driven WireGuard services that previously required significant custom infrastructure to build.
WireGuard Listeners have always required every connecting client to be pre-registered: you list each peer's public key in your CloudFormation template, and the Listener rejects any handshake from an unknown key. That model fits private services with a managed set of devices. But it creates a problem for anything that needs to be accessible by a large or unknown set of clients.
Consider a mobile app that generates a WireGuard keypair on first launch. Or a fleet of devices provisioned on demand where central key management is operationally impractical. Or any public-facing service where clients you've never seen before need to connect. With the previous model, every one of those clients required an out-of-band registration step and a CloudFormation update before it could complete a handshake. That's not a model that scales to public services.
The new AllowUnknownPeers property removes that restriction. Set it to true
on a WireGuard Listener and the Gateway will complete the handshake with any valid WireGuard client,
regardless of whether its public key is listed. The connection is still fully encrypted — WireGuard's
cryptographic properties don't change. The difference is simply that the Listener no longer requires
the key to be known in advance.
The analogy to HTTPS is intentional. When you visit a website over HTTPS, the server doesn't need to know who you are before establishing an encrypted connection. The TLS handshake completes, the channel is encrypted, and authentication (if it happens at all) is a separate concern at the application layer. Open WireGuard endpoints work the same way: the transport is encrypted, and identity can be handled by your Lambda or Step Functions destination however your application requires.
Fully open enrollment — accepting literally any WireGuard client — is appropriate for some services.
For others, you want the encryption and the open handshake, but you also want to prevent connections
from clients that weren't issued credentials. The UnknownPeerPreSharedKey property
provides a lightweight gate for exactly this case.
When UnknownPeerPreSharedKey is set, unknown peers must include that PSK in their
WireGuard configuration or the handshake fails. It's not per-device authentication — every client
uses the same secret — but it meaningfully restricts access to clients that were issued the PSK.
Think of it like a shared API key for transport-layer access: not strong identity, but a real
barrier against arbitrary connections from clients who were never given credentials.
Distributing the PSK to clients is your application's responsibility. Store it in AWS Secrets Manager and reference it from your CloudFormation stack on the infrastructure side; provision it to devices during manufacturing or enrollment on the client side.
WireGuardListener:
Type: Custom::ProxylityUdpGatewayListener
Properties:
ServiceToken: !FindInMap [ProxylityConfig, !Ref "AWS::Region", ServiceToken]
ApiKey: !FindInMap [ProxylityConfig, Account, ApiKey]
Protocols:
- wg
AllowUnknownPeers: true
UnknownPeerPreSharedKey: !Sub "{{resolve:secretsmanager:${WireGuardPSK}:SecretString}}"
Destinations:
- Name: packet-handler
DestinationArn: !GetAtt HandlerLambda.Arn
Role:
Arn: !GetAtt ProxylityRole.Arn
Named peers (listed in the Peers array) are unaffected by AllowUnknownPeers
and UnknownPeerPreSharedKey. They use their own per-peer SharedSecret as
before. The two models can coexist on a single Listener: a fixed set of known devices with per-device
PSKs, and an open slot for dynamic clients behind a shared credential.
Lambda destinations in UDP Gateway have always used synchronous RequestResponse invocation:
the Gateway delivers a batch of packets, waits for the function to complete, and uses the function's
return value to send reply packets back to clients. That model is the default to align with how
UDP request/response patterns work.
But synchronous invocation becomes limiting for workloads where a function's job is to kick off
processing that outlives a single invocation. Lambda durable functions address exactly this: using
a checkpoint-and-replay mechanism, a durable function can execute for up to one year, automatically
resuming after failures without losing progress. The Event invocation type is the right
delivery model here — the Gateway fires the packet batch and moves on while the durable execution
continues independently.
The new UseAsyncInvoke argument changes the invocation type to Lambda's Event
mode. The Gateway delivers the packet batch and immediately receives an HTTP 202 Accepted without
waiting for the function to complete. No reply is sent to the UDP client. The function runs to
completion independently of the Gateway's request lifecycle.
The primary use case is triggering durable workloads. A function invoked with
UseAsyncInvoke receives the inbound packet batch, starts a durable execution (or
dispatches to Step Functions if you prefer that orchestration model), and returns immediately.
The remote client sent a UDP packet; a long-running, fault-tolerant workflow is now running on
its behalf, with checkpointed progress and automatic recovery from failures — none of which
requires the Gateway to hold a connection open.
Destinations:
- Name: workflow-trigger
DestinationArn: !GetAtt WorkflowTriggerLambda.Arn
Role:
Arn: !GetAtt ProxylityRole.Arn
Arguments:
UseAsyncInvoke: "true"
A few things to keep in mind when using async invocation:
UseAsyncInvoke and
UseResponseStreaming cannot both be true on the same destination — they represent
opposite delivery models.These two features are independent, but they combine naturally for a specific pattern: a public WireGuard endpoint that triggers a long-running backend workflow.
Imagine a device provisioning service. Devices are manufactured without pre-registered keys — they generate a keypair on first boot, connect to the open WireGuard Listener using the shared PSK, and send a provisioning request packet. A Lambda function receives the packet, starts a Step Functions state machine that handles the full provisioning workflow — identity registration, certificate issuance, DynamoDB record creation, SNS notification — and returns. The state machine runs for minutes or hours. The device receives no immediate reply; provisioning confirmation comes through a separate channel once the workflow completes.
None of that requires managing a key registry before devices ship. None of it requires the Gateway to hold a connection open for the duration of provisioning. It's a packet in, a workflow started, and no infrastructure running between events.
The same pattern applies to any inbound-triggered workflow where the sender doesn't need an immediate response, such as device commands that kick off multi-step validation before execution, and audit events that need durable processing guarantees across multiple systems.
Both features are available now across all regions where UDP Gateway is supported. Neither requires
changes to existing Listeners or destinations — AllowUnknownPeers defaults to
false and existing peer-list behavior is unchanged, and Lambda destinations continue
to use synchronous invocation unless UseAsyncInvoke is explicitly set.
For complete configuration details, see the WireGuard Listeners documentation and the Lambda destination documentation. The full CloudFormation property reference for AllowUnknownPeers and UnknownPeerPreSharedKey covers all options including mixing named and unknown peers on the same Listener.
Get started with Proxylity UDP Gateway today. No upfront costs ‐ pay only for what you use.
Buy with AWS Try the Examples Explore Documentation