Reverse Proxy and TLS¶
Applies to: All subscriptions
Purpose¶
Configure the single public entry point correctly: terminate TLS, route requests to the right place, serve the application without breaking browser routing, and apply the security headers a customer's security review will look for.
Audience¶
Infrastructure engineers and system administrators. The security header and TLS sections are also read by security reviewers.
Prerequisites¶
- Install on Windows Server complete and the API listening
- Front-end Deployment complete and the build published
- Certificates issued for every published hostname
- DNS records in place
Steps¶
1. Decide the routing¶
The proxy has exactly two jobs, and one fallback rule:
| Request | Destination |
|---|---|
Paths beginning /api/ |
The application API, on its configured port |
| A path matching a real static file | That file from the published build |
| Anything else | The application's entry page, so the browser resolves the route |
The third rule is not optional. Without it, refreshing an inner page or following a bookmark returns HTTP 404 — a fault that never appears during a click-through test and always appears on day one of user acceptance testing.
2. Terminate TLS¶
| Setting | Requirement |
|---|---|
| Minimum protocol version | TLS 1.2, with TLS 1.3 preferred |
| Cipher suites | Modern suites only; no legacy ciphers |
| Certificate | Valid, trusted, covering every published hostname |
| Certificate chain | Complete. An incomplete chain works in browsers and fails for the ERP calling in |
| HTTP to HTTPS redirect | Enabled |
| Renewal | Automated, with a named owner |
Verify: The minimum TLS version above is a recommendation, not a stated platform requirement. Align it to the customer's own standard. Recorded as assumption E1 in the Assumptions Register.
The incomplete-chain failure is worth dwelling on: browsers usually repair a missing intermediate certificate automatically, so the application looks fine while every ERP integration fails TLS validation. Test with a tool that does not repair the chain, not with a browser.
3. Apply security headers¶
| Header | Purpose |
|---|---|
Strict-Transport-Security |
Forces HTTPS on subsequent visits |
X-Content-Type-Options: nosniff |
Prevents content-type guessing |
X-Frame-Options or a frame-ancestors policy |
Prevents the application being framed |
Referrer-Policy |
Limits referrer leakage |
Content-Security-Policy |
Restricts what the page may load |
The content-security policy needs specific care in a Complifly deployment: generated files are served from a different origin by design. If the policy does not allow that origin, downloads fail with no useful error. Enumerate the origins the application legitimately uses before writing the policy — see Domains and URLs.
4. Set timeouts and body limits¶
| Setting | Guidance |
|---|---|
| Proxy read timeout | Longer than the slowest legitimate operation. Government calls and bulk operations are slower than an ordinary request |
| Request body limit | Large enough for the biggest upload the business will attempt, and no larger |
| Header size limit | Adequate for tokens, which can be sizeable |
| Keep-alive | Enabled toward the API |
A proxy timeout shorter than a legitimate government call produces an HTTP 504 while the operation actually completes at NIC. The user retries, and the retry is rejected as a duplicate. Size timeouts to the slow path, not the median.
5. Handle cross-origin requests deliberately¶
If the front end and API are served from the same origin, no cross-origin configuration is needed and none should be added. If they are on different hostnames, cross-origin access must be configured on the API for exactly those origins — never a wildcard.
6. Do not expose anything else¶
Only the proxy is reachable from outside. The API, worker, database and queue must not be. Verify this by attempting to reach them from outside the network, not by inspecting a configuration file.
Validation¶
| Check | Method | Pass condition |
|---|---|---|
| HTTPS works | Open the application URL | Loads with a valid certificate and no warning |
| Redirect works | Request the HTTP URL | Redirects to HTTPS |
| Certificate chain complete | Test with an external TLS checker, not a browser | Full chain served |
| TLS version and ciphers | External TLS checker | Meets the agreed standard |
| API routing works | Request the health path through the proxy | HTTP 200 |
| Static assets served | Load the application | Assets return HTTP 200 |
| Deep link fallback works | Open an inner page directly in a new tab, then refresh it | Loads both times. HTTP 404 means the fallback rule is missing |
| Security headers present | Inspect response headers | All expected headers present |
| Downloads work | Generate and download a document | Downloads succeed. Failure here is usually the content-security policy |
| Long operations survive | Perform a bulk operation at realistic size | Completes without an HTTP 504 |
| Upload size adequate | Upload the largest file the business will use | Accepted |
| Internal components not exposed | Attempt to reach the API port, database port and queue port from outside | All refused |
Troubleshooting¶
| Symptom | Cause | Action |
|---|---|---|
| HTTP 502 | The proxy cannot reach the API | Confirm the API is listening and the proxy target port matches. The application log will be silent |
| HTTP 504 on government operations | Proxy timeout shorter than the operation | Raise the read timeout. Note the operation may have succeeded at NIC — check before retrying, or the retry will be rejected as a duplicate |
| Works until refresh, then HTTP 404 | Single-page-application fallback rule missing | Add the fallback |
| Browsers fine, ERP integration fails TLS | Incomplete certificate chain | Serve the full chain. Browsers repair this; other clients do not |
| Downloads fail with no clear error | Content-security policy blocks the download origin | Allow that origin explicitly |
| Cross-origin errors in the browser console | Front end and API on different origins without configuration | Configure allowed origins on the API for exactly those hostnames |
| Large uploads rejected | Body size limit too low | Raise it to the largest legitimate file, and no further |
| Sign-in loops or fails after redirect | Redirect URL not registered, or protocol mismatch between configuration and reality | Register the exact URL including scheme and path |
| Site becomes unreachable overnight | Certificate expired | Automate renewal and monitor expiry. See Monthly Checks |
| Some users blocked, others fine | Strict transport security cached against an old certificate or hostname | Expected behaviour of the header; plan hostname changes carefully |
Related Articles¶
- Front-end Deployment — what the proxy serves
- Domains and URLs — the hostnames and origins involved
- Network and Firewall — the paths through the proxy
- Security Hardening — the wider posture
- Post-Installation Verification — the completion gate