Since your services communicate over untrusted networks, some security mechanism is necessary. Even if you have control over the network, “zero trust” principles would suggest to use security mechanisms.
The connection itself can be protected via TLS. You can issue self-signed certificates for the service, and deploy this certificate to all components that connect to this service.
If you want to check that the downstream components are authorized to connect to the service, you could use TLS with client authentication, but software support in web frameworks might be more limited. And at that point, you would probably want to run your own certificate authority (not necessarily difficult, but a potential weak point in your security architecture). TLS client authentication is not better or worse than other mechanisms like authorization tokens on a HTTP level, they just apply on different layers of the network stack and thus have different capabilities. It's also worth considering if you should authenticate clients or actions taken by those clients, e.g. consider the confused deputy problem. E.g. if one service contacts another internal service on behalf of an external user who provided a JWT token, it could make sense to use the permissions encoded into that token internally as well.
Even with TLS, you're still communicating over another (untrusted) network, so any device on that network could contact your services as well. This may be undesirable – you typically want to disable incoming connections to your internal services, except through ingress points, bastion hosts, or proxies that can be more easily defended (→ DMZ).
Luckily, the physical network topology does not force a particular logical network layout. You can use a site-to-site VPN that connects a router in each network, so that your multiple networks can talk directly with each other. This makes it possible to contact services without giving them a publicly routable IP address.
In any case, you will want appropriate firewall rules that limit what incoming connections can do. A sane default is to drop all incoming TCP connections other than for SSH, and then to allowlist IP ranges from which connections to your service shall be permitted.