A database that works before the VPN connects and fails after it is rarely a credential problem. Cloud firewalls match source addresses, and a full tunnel replaces the one they were matching. The gap between what you think your laptop sends and what the server receives is the entire bug, and it is measurable in one step.

What the source address becomes

In a full tunnel, every packet leaves through the VPN gateway, so the server sees the gateway's egress address rather than your home connection. If a forward proxy sits in the path, the proxy's address is what arrives instead. Both are legitimate sources, and neither is the address in your original rule.

Azure SQL's server-level and database-level firewall rules match the client address that reaches the logical server, which after a full tunnel is the egress address. An AWS security group allowing a single address behaves the same way. The packet is dropped before authentication, so the error you get back looks like a network failure rather than a permissions problem. That is exactly why people start resetting passwords.

Where the allowlist is decided

Read the rule that matches the failing path, not the rule you remember creating. Note its scope, its port, its protocol and whether it is evaluated before any identity check.

Then decide which layer legitimately owns the decision. An address rule answers where traffic comes from. A private endpoint answers whether the service is reachable over a private path at all. A split-tunnel exception answers which destinations bypass the tunnel. They are not interchangeable, and each one fails differently when the tunnel changes.

Three repairs, three layers

Each option below fixes the flow for a different reason, and choosing the wrong one produces a connection that works until the next gateway change.

RepairLayer it changesWhat it does not fix
Add the egress address to the ruleSource address matchingNothing about routing, and it breaks when the egress moves
Use a private endpointWhether the service is reached privatelyA client that still resolves the public name
Add a split-tunnel exceptionWhich flows bypass the tunnelAn expired credential or a wrong password

Adding the egress address is the smallest change and the most fragile, because a new gateway or a different region invalidates it silently. Document the address beside the tunnel definition so the two move together. A temporary broad range is a diagnostic, not a repair; leaving it in place is how internal services end up exposed.

Why a managed platform cannot join the tunnel

Application platforms such as Heroku, AppHarbor or CloudBees run your code in an environment with no tun or tap device and no privileges to create one. Their inbound model is HTTP rather than an arbitrary listening socket. A buildpack that ships a VPN binary still has nowhere to put the interface. The workable patterns are a static egress address the database can allow, a private connection product the platform offers, or a proxy in a DMZ reached over HTTPS.

That proxy is an access path with its own authentication and logging. It does not make the platform a member of your VPN, and describing it that way produces rules nobody can audit.

Verify from the client that failed

Reconnect and repeat the exact client path. Check the source address the service logs, the route the client selects for the database name, and the result of the actual query, in that order. A test from the gateway proves the gateway works, which was never in doubt. If the connection now authenticates and the query still fails, the remaining problem is database permission.

Review these rules whenever the tunnel changes. A replaced gateway or a new egress range breaks the path with no application configuration change at all.

Artaigilean co-cheangailte