Cloudflare Workers VPC: Build globally, connect privately
Presented by: Matt Alonso
Originally aired on October 24 @ 9:00 AM - 9:30 AM EDT
Cloudflare Workers applications often need to reach APIs and databases that cannot be exposed to the public Internet. Cloudflare Workers VPC connects Workers and Hyperdrive to private networks through existing Cloudflare One connectivity, including Cloudflare Tunnel. This session follows a request from a Worker to a private service: how Cloudflare resolves a private hostname, carries the connection, returns traffic without giving the Worker a stable network identity, and limits access through explicit bindings. It also compares a VPC Service for one approved destination with broader VPC Network access for dynamic destinations, account-wide routes, and Gateway-controlled egress.
English
Transcript (Beta)
My name is Matt Alonso, and I'm a senior systems engineer here at Cloudflare. I've worked here for six years.
I started off on the Durable Objects team and helped launch that product, then helped launch Hyperdrive.
And for the past year, I've been working on our private networking products, primarily Cloudflare Workers VPC.
And Workers VPC is really neat because it lets you build your applications on Cloudflare, but it lets you connect to your resources that run outside of Cloudflare, whether it's on -premise or running in a hyperscaler VPC.
Before Workers VPC, when you used Cloudflare Workers, your only option for connecting to things outside of Cloudflare was if they were on the public Internet.
And that meant attackers could access those resources too.
And if you had something running in a hyperscaler VPC, it was up to you to set up an Internet gateway to publicly expose that resource and secure it.
And even if you did set that up, there's challenges of getting it right and some other problems.
Beyond attack surface, bandwidth pricing for getting data out of the hyperscaler VPCs is billed by the gigabyte.
And it's billed at an elevated rate compared to data that egresses over private connections.
And this can really add up if you're moving a lot of data into our developer platform.
And we already had a solution for private networking.
We have our Cloudflare One suite, which has several different connectors for getting traffic into and out of the Cloudflare One network.
From the Cloudflare One client that runs on your employee laptops to Cloudflare Tunnel, which lets you connect to resources in a private network.
Cloudflare Mesh, we have Cloudflare WAN for IPSec and Cloudflare Network Interconnect for an actual physical cable between us and your private network.
And this allowed physical devices and VMs to reach the Cloudflare One network.
But there wasn't a way for workers in our developer platform products to get their traffic into the Cloudflare One network.
And that's the problem that Worker's VPC solves. It's the missing piece that brings the developer platform into your Cloudflare One network.
And it acts as an on-ramp for traffic coming from both Cloudflare Workers and Hyperdrive and can reach private resources via our existing Cloudflare One connectors from Tunnel to Mesh and WAN and CNI.
The Cloudflare One client and other on -ramps like Cloudflare WAN work differently than Worker's VPC.
With the Cloudflare One client, your resources are exposed as if they were just available on your local area network.
But when using Worker's VPC, we don't expose your private resources through the global fetch handler on your worker.
Instead, we expose those private resources using bindings. If you haven't used Workers before, bindings are live objects that are accessible from Workers code.
And you configure them in your Wrangler configuration for your worker to define what resources on the developer platform that your worker can access at runtime.
And so the Worker's VPC binding has two options. You can use it for HTTP and you'll get a fetch method on your binding.
Or you'll get a connect method if you're using a TCP service.
And in order to create a Worker's VPC binding, you need a bindable object to actually bind to when you upload your worker.
And that is what a VPC service is.
And so to expose a specific private resource as a bindable object, you have to create a VPC service.
It has a name and it has a type. And there's two types of VPC services.
There's the TCP variant, which exposes a single port, or the HTTP variant.
And for the HTTP variant, you can have a plain text service, you can have an encrypted -only service, or you can support both HTTP and HTTPS, which is the default on the standard ports.
And the whole point of the VPC service is it describes an origin.
And so it stores all of the metadata that's necessary to establish a connection to that origin.
And so beyond the port, you have to provide a hostname or an IP address.
And then you have to provide something that we call a resolver network, which is a single object that defines both the resolver to use for private hostnames and the network that any resolved private IPs, or if you specify an IP, that that private IP is routable on.
And so if you notice here, we have only a single tunnel ID in the configuration for the resolver network.
And that's because Cloudflare Tunnel now has a built-in DNS proxy in it that allows our network to access your private resolver that's running in your network by proxying DNS queries from us through to your private resolver.
And so you only have to provide a tunnel ID, and you're able to get both a resolver and a network out of that.
But you still have the option of manually specifying a resolver IP if you want, depending on your use case.
In order to create a VPC service and in order to bind to a VPC service, you need different permissions.
And the point of this is to kind of separate who is allowed to do what with this product.
For network admins who might want to expose private resources to developers on the same account, you need to give them the connectivity directory admin role.
And this lets you control who can expose resources, while developers can be given the connectivity directory bind role, which allows them to only bind to existing workers VPC services that have already been created.
Once you have a VPC service, you're able to add it to your Angular configuration by specifying the service ID that was returned from creation.
And you need to give it a binding name, which is what's going to show up on the end object when you go and write your worker code.
And you'll get that fetch method that I mentioned earlier using an HTTP service.
And something to keep in mind for the fetch and connect method on a VPC service binding is the host name in fetch is not used for routing.
You already specified what you're going to be routed to in your VPC service configuration.
And so that host name is only used in the host header for the requests that are being sent to your origin.
It will not be used for routing. I mentioned that we also support TCP services.
And this is also useful for connecting to private databases with HyperDrive.
It's not just for workers. And the way to do this is you can specify an app protocol in your TCP service definition.
And for HyperDrive, you can do either Postgres or MySQL.
And just as you're able to set a VPC service in your Wrangler configuration, you can set a VPC service in your HyperDrive configuration under the origin field instead of providing the typical fields that you would have in a connection string.
And this lets you access private databases that are running on premise.
Or maybe you're using a hosted database product on one of the hyperscalers.
And you can do this just by running tunnel in your VPC. And you're able to access that database without having to expose it to the public Internet.
VPC works pretty similar to the Cloudflare 1 client.
And it is also an on-ramp. But the way that we actually proxy traffic behind the scenes is pretty different.
Workers' VPC is not a layer 3 on-ramp like the Cloudflare 1 client and Cloudflare WAN.
Those on-ramps are getting traffic into Cloudflare as packets that are already coming out of an operating system.
But with Workers' VPC, this is different. Because we run workers in a sandbox.
They're not virtual machines. They're not containers.
And so they don't have access to the host OS. Everything that a worker can do is defined by the bindings that it has and the implementation of those bindings in the worker's runtime.
And for Workers' VPC, we don't expose the host OS to the worker.
There's no good way to configure the system resolver on demand to use a specific private resolver and send that traffic through a tunnel.
And so we implement a user space DNS client.
And that allows us to send the DNS queries for the private host name in your VPC service configuration when a connection is initiated by your worker by calling the fetch method on the binding through to Cloudflare tunnel and through to your private DNS resolver.
The results come back for the private host name and you get a private IP.
And we're then able to establish a connection.
If you notice here, Workers' VPC is also responsible for doing the TLS session.
That is because we don't want to do any encryption inside of the shared worker sandbox.
We like to keep that outside of the shared address space. And so the plain text byte stream that comes out of Cloudflare Workers gets upgraded into the TLS session and that flows on to your private origin.
And from the perspective of your private origin, those packets are going to appear as if they're coming from the machine that the Cloudflare D is running on with the same source IP as that machine.
And so VPC services are really great for if you want like per resource capabilities, you want to define specific destinations that you know about ahead of time.
They're also useful when you don't want to have a single global routing table.
A good example of when this can happen is let's say you do an acquisition and you have multiple hyperscaler VPCs that are under your responsibility.
And they're all using the same shared address space.
If you had a global routing table, you'd have to decide what VPCs you're going to change that address space to use.
But with VPC services, you're defining your resources and you're giving them an ID.
And so Workers can identify those resources by their ID instead of using IPs that can conflict across networks.
But sometimes you don't want to specify all of your private resources ahead of time.
Maybe you're doing service discovery or you need to connect to a ton of resources or change that at runtime.
And that's what the VPC network binding is for.
And we have two variants of the VPC network binding.
There's the VPC network binding to tunnels and the VPC network binding to the entire Cloudflare 1 network.
And for VPC network bindings to tunnels, you're exposing everything that Cloudflare D can access.
So if Cloudflare D is running, anything that it can access, including the public Internet, is available.
And this is useful for not just connecting to dynamic resources and your private APIs and databases, but you can also connect to things on the public Internet.
And it's kind of like a VPN for your worker where your subrequests can appear as if they're coming from your network, but you still can keep your compute on our platform.
The coolest feature of Workers VPC, though, is arguably the Cloudflare 1 network binding, which lets you use the existing Cloudflare 1 routing table, which exposes not just Cloudflare Tunnel, but all of our other off-ramps, including the Layer 3 off-ramps like Cloudflare WAN for IPsec and Cloudflare Network Interconnect and Cloudflare Mesh.
And something else that happens when you're using the CF1 network binding is your traffic is going through Cloudflare Gateway.
And this means your traffic that is coming from Workers VPC using the CF1 network binding is logged and processed and has policies applied to it just like traffic coming from the Cloudflare 1 client or from Cloudflare WAN.
And so this lets you use Gateway to monitor what is happening in your workers.
And this is really useful if you're running agents and workers, because you can use all of the same protections that you use for your employees for agentic traffic.
And so you can set up Gateway to log all the network traffics from your agents.
And you can also use Gateway policies to filter the sites your agent can access.
You can use our data loss prevention product to inspect network payloads coming to and from your agents for sensitive data.
The Cloudflare 1 network, like I said, supports more Layer 3 off-ramps like IPsec, CNI, and Mesh.
And those work differently behind the scenes than when we send traffic to Cloudflare Tunnel.
For Layer 4 tunnels, we're getting a byte stream out of workers, and we're just proxying that over to Cloudflare D.
The machine that it's running on is responsible for turning that into Layer 3 packets.
But when we're off-ramping to one of our Layer 3 products, it's Cloudflare's responsibility to take that byte stream coming out of workers and turn it into packets.
And one of the difficult problems of that is that could happen on any machine in our fleet.
And so we need to make sure that we have a way to get that traffic back to the same machine that initiated the Layer 4 to Layer 3 downgrade.
And the way we do that is with Cloudflare source IPs, which identify the specific Cloudflare metal that is being used for the downgrade.
So when they come back with the return side packets with that source IP now in the destination field, any of our metals is able to look at that packet and then route it to the original metal responsible for the downgrade.
It can get turned back into a byte stream and returned to the worker.
What's coming next for workers EPC?
We're exploring more connectivity options inside of EPC services.
We want to support MTLS so you can configure the client cert and private key that's going to be used when we establish the TLS session.
And you can configure a list of server certs that you trust.
And we want to support more connectors like mesh so you can provide the ID of a mesh node, not just the tunnel ID when you create an EPC service.
And we're also looking into deeper integrations with gateway.
We want to make it possible to tag traffic that's coming out of workers.
And one of the neat things that this might enable is tagging traffic with an identity that you can create at runtime.
And this might be useful for agentic workloads that are running in dynamic workers or in sandboxes.
You'd be able to run those and your runtime around them can decide this agent is running on behalf of this human.
And you can use policy that is not just operating on an agent pretending to be a human, but an agent using delegated authority that will be separate.
And I think this is going to enable a ton of neat use cases. And so let's recap.
VPC services are best for exposing specific private resources without having to configure a routing table.
VPC networks are best for when you want to connect to a whole tunnel and expose everything that that tunnel can access.
Or if you want to leverage your existing investment in the Cloudflare 1 routing tables or you want to use one of our Layer 3 off-ramps.
CF1 network bindings also let you send traffic through Cloudflare gateway for using gateway policies for filtering or data loss prevention or doing logging for traffic.
Awesome.
Thank you guys for coming.
