Step by step, with screenshots: SSH and VS Code into a workspace with one key.

The device underneath all three

Every Linux guest gets a virtio network device attached through NAT (VZNATNetworkDeviceAttachment, covered in the device inventory post). That puts the guest on a private virtual subnet, usually 192.168.64.x, with the Mac as its gateway. Every path below follows from that.

Path 1: Mac to guest, direct

Because the Mac is the gateway, it can already reach the guest's subnet. Your Mac's browser or terminal reaches a service in the guest at its address, http://<VM_IP>:<port>, with nothing to configure. A workspace's Access tab shows that address and a ready-to-copy ssh command. The complete AI agent guide uses this path to open a web UI running in the VM.

macOS treats that virtual subnet as part of the local network, so the first time Velo Workspaces checks a workspace's SSH server or opens its terminal, macOS asks whether to allow Local Network access. The app only connects to its own workspaces; if you decline, the Access tab says so and links to the setting.

Path 2: guest to the internet, through NAT

Outbound traffic works as it does for any device behind a router. The guest gets a private address by DHCP and the Mac translates everything going out. Nothing to set up.

Path 3: another computer to the guest, which needs a hop

Another machine on your LAN, a phone or a second Mac, can't route into the guest's subnet the way your Mac can, because that subnet exists only inside your Mac. You need a hop through the Mac, and there are two easy ones.

For SSH, jump through the Mac. Turn on Remote Login in System Settings › General › Sharing, and the Access tab gives you an ssh -J command that signs in to the Mac and hops from there to the workspace. The workspace needs to accept that other computer's key (you can add public keys when you create it) or allow password logins.

For a web service, forward a port. For example, caddy reverse-proxy --from :8081 --to <VM_IP>:4096 makes the Mac listen on port 8081 and pass traffic to the guest's port 4096, so any device on the LAN can open http://<MAC_IP>:8081. The outside port doesn't have to match the inside one, which helps when the guest's port is already taken on the Mac.

The guest's address doesn't drift

Velo Workspaces derives each workspace's MAC address from its ID instead of randomizing it, so a guest keeps the same DHCP lease, and the same IP address, across restarts. Without that, the addresses in the commands above would change every time the workspace started.

Why path 3 needs a hop: NAT only, for now

Bridged networking, where the guest would get its own address on your LAN, needs the com.apple.vm.networking entitlement, which the app doesn't have. The Kali Linux post covers a case where that matters: a testing toolkit that expects to see other devices on the LAN runs into the NAT boundary, and a port forward doesn't fully replace a bridge.

Related reading: the Virtualization.framework device inventory, Linux VM network performance, and Kali Linux on Apple Silicon, where the NAT boundary matters most. Or download Velo Workspaces and try it yourself.