Controlled remote access
What to do when the caller and PrintLink are on different networks: VPN, reverse proxy or opening the public internet, and who is responsible.
Last updated
This path is for when the caller and PrintLink are not on the same LAN and jobs must travel over a VPN, a reverse proxy or a managed network. It is the highest-risk path — not a default, and not a cloud printing service.
First, confirm you really need it
"This app is hosted publicly" almost never needs this path: the user opens the
public page in their own browser, the page reaches PrintLink over 127.0.0.1,
and paper comes out locally. Only continue reading if the printer's computer
and the operator are not on the same network and you cannot put the operator's
browser next to that machine. See deployment topology for
the decision flow.
Three approaches (in order of preference)
| Approach | How | PrintLink configuration | Who is responsible |
|---|---|---|---|
| VPN / zero-trust network | Remote terminals join the print node's network first, then connect as on a LAN | LAN + the VPN subnet in the allow-list | The network team owns VPN identity and encryption; PrintLink only sees a private peer |
| HTTPS / WSS reverse proxy | Put a certificate-bearing proxy in front, forwarding to the local service | Local scope if the proxy is on the same machine; otherwise LAN + allow the proxy address only | You own the certificate, DNS, proxy auth and rate limits; WSS resolves the browser's mixed-content limit |
| Opening the public internet | PrintLink binds a routable address the machine really holds | Public scope + an explicitly confirmed address + a narrow allow-list | You own the firewall, port forwarding and transport encryption; the connection is plaintext, with no built-in TLS |
Prefer the first two. Opening the public internet is the last resort.
A reverse proxy must forward Origin untouched
When a browser connects through a proxy, the page's Origin is still your app's
domain, which counts as an "external / unknown site" and always has to be
paired on PrintLink — the proxy cannot authorise on the page's behalf. The proxy
must not remove or rewrite Origin:
- If the proxy is on a different machine from PrintLink, a connection without
Originis refused as a remote native client; - If the proxy is on the same machine, PrintLink sees a loopback peer — and
if the proxy stripped
Origin, every proxied remote connection would be mistaken for a trusted local client with full permissions. That is a deployment mistake you must avoid.
Prerequisites for opening the public internet
- Bind only an address the machine really holds. The NAT egress IP is not a
local address and cannot be bound;
0.0.0.0is always refused. - Binding is not reachability. Port forwarding, firewalls, ISP restrictions, DNS and certificates are all yours to handle; the product will not touch your firewall.
- Keep the allow-list narrow. Allowing every source needs an extra dangerous confirmation, and denials always win.
- There is no built-in TLS. The connection is plaintext, so tokens, parameters and uploaded content can be intercepted. Without a VPN or a proxy in front, this deployment should not be considered secure.
Floors that cannot be widened
These rules are enforced by the service and cannot be turned off in the UI:
| Floor | Meaning |
|---|---|
| Remote non-browser programs are always refused | A connection without Origin is trusted only from the loopback; a no-Origin connection arriving over the network is refused before the handshake (REMOTE_NATIVE_CLIENT_DENIED) and audited |
| Remote peers get no authorisation exemption | Exemptions are judged by the real connection path, so a connection arriving from the internet still has to pair even if it claims to be local |
| Domain-form origins always need authorisation | No exemption can cover them |
| The four checks never substitute for each other | Allowing an IP does not allow a site, and pairing does not grant the print permission |
What about remote services?
A remote Node / Java / .NET service cannot connect to PrintLink directly yet: it needs the service/device token system that does not exist. Until then, three workable options:
- Have the operator open your page on the PrintLink machine or a terminal on the same LAN, using the browser SDK and site authorisation. This is the only productised path.
- A same-machine bridge process: split out a small process deployed on the PrintLink machine, calling it over the loopback; you authenticate and encrypt the hop between your backend and that process.
- VPN / reverse proxy plus a browser: when terminals are on another network, deploy as above and still use a browser page as the client.
What remote non-browser clients still need: revocable service/device tokens with issuance, rotation, revocation and auditing; identity, least privilege and job visibility bound to that token; a settings surface for per-connection-path native client authentication; and an official cross-language SDK with compatibility guarantees.
A go-live checklist
Prove the LAN path first
On the print node's own network, complete a real print following LAN print workstation so the printer, allow-list and authorisation are all correct. The remote problem should then be only "how does the network reach it".
Choose a VPN or a WSS proxy, not a bare public listener
Prefer a VPN: PrintLink's configuration does not change and the peer stays private. Next, a WSS reverse proxy: allow only the proxy address and let the proxy do TLS, authentication and rate limiting. Only consider a direct public listener when neither is possible.
Tighten the allow-list and site policy
Allow only the precise subnet of the remote terminals or the proxy; set the new-site policy to allow-list only; lock these with machine policy.
Rehearse the rollback
Switch the scope back to LAN or local in the console: tightening takes effect immediately and drops out-of-scope sessions. "Restore secure defaults" turns authorisation checks back on. Put both steps in your operations runbook.
Verify in your own environment
Cross-internet reachability, firewalls, certificates and browser mixed content must all be tested on your own network. This documentation does not replace that step.