# Secure Deployment

> Harden a TX Text Control deployment: HTTPS and wss, a private Document Editor backend port, least-privilege accounts, no secrets in images, logs and updates.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Security > Secure Deployment
- **2700 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/security/deployment/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/security/deployment/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/security/deployment/llms-full.txt

---

When an application moves from a developer machine to a production server, some defaults that make development easy have to change. The Document Editor backend listens on all network interfaces, HTTPS has to be set up for the server or its proxy, and a *nuget.config* with an API token can end up in the publish output. The checklist below names each point, explains why it matters and links the page of the [Deployment Guide](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/llms-full.txt) that shows the steps for your platform.

### The Checklist

| Check | Why | Read |
|---|---|---|
| The site runs on HTTPS, and the editor connects with `wss` | Documents and editing sessions are encrypted in transit | [Serve the Application Over HTTPS](#serve-the-application-over-https) |
| The Document Editor backend listens on the loopback address or a private network only | Its TCP port accepts connections from any client that reaches it | [Keep the Backend Private](#keep-the-backend-private) |
| The application's account has only the rights it needs | The backend and its worker processes share the account | [Run With Least Privileges](#run-with-least-privileges) |
| No *nuget.config* with credentials in the output or in an image | It contains the API token of the Text Control Private NuGet Feed | [Keep Secrets Out of the Deployment](#keep-secrets-out-of-the-deployment) |
| The backend's messages reach your logs | They show whether the backend runs and which editors connect | [Watch the Logs](#watch-the-logs) |
| All TX Text Control packages are current and on the same version | Service packs contain fixes, and mixed versions cause connection problems | [Keep the Packages Current](#keep-the-packages-current) |

Protecting the endpoints themselves with authentication and access tokens is part of [Authentication](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/authentication/llms-full.txt) and [WebSocket Security](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/websockets/llms-full.txt).

### Serve the Application Over HTTPS

On a page served over HTTPS, the Document Editor connects with `wss`, because it builds its WebSocket address from the address of the page, and the connection uses the same security layer as the page. The Document Viewer uses ordinary HTTP requests, so HTTPS protects both.

- **Redirect to HTTPS and send HSTS headers.** The ASP.NET Core templates call `UseHttpsRedirection` and, outside the development environment, `UseHsts`. HSTS tells browsers to use only HTTPS for the site; Microsoft recommends starting with a short maximum age when you introduce HTTPS and raising it later.
- **Terminate HTTPS at the reverse proxy.** Behind nginx, the proxy listens on port 443 with a certificate from a trusted certificate authority, and the application behind it stays on HTTP on the loopback address. The Forwarded Headers Middleware tells the application the original scheme; without it, HTTPS redirection behind such a proxy ends in a redirect loop. [Prepare the Application](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/linux/ubuntu/#prepare-the-application) in Ubuntu shows the code.
- **Trust only your own proxies.** The Forwarded Headers Middleware accepts headers only from proxies on the loopback address by default. For a proxy on another machine, add its address to the known proxies instead of accepting all, or clients can spoof their IP address.
- **Configure a certificate for a service without IIS.** An ASP.NET Core application that runs as a Windows service can't use the HTTPS development certificate, as [Host the Document Editor in a Service](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/windows/windows-service/#host-the-document-editor-in-a-service) notes.

Microsoft describes the options in [Enforce HTTPS in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl) and [Configure ASP.NET Core to work with proxy servers and load balancers](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer).

### Keep the Backend Private

The WebSocket middleware in your application talks to the Document Editor backend `TXTextControl.Web.Server.Core` over plain TCP. Without configuration, the backend listens on port 4283 on all network interfaces, for IPv4 and IPv6, and accepts connections from any client that reaches the port. Only your application needs to reach it.

When the backend runs on the same machine or in the same container as the application, bind it to the loopback address: set `ListenAddress` to `127.0.0.1` in the `DocumentEditorWorker` section of *appsettings.json* and pass the same address and port to `app.UseTXWebSocketMiddleware("127.0.0.1", 4283)`, as [Prepare the Application](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/linux/ubuntu/#prepare-the-application) in Ubuntu shows. If the values differ, the editor can't connect. In containers and cloud services, the environment variables `DocumentEditorWorker__ListenAddress` and `DocumentEditorWorker__Port` set the same values, as [Run the Backend in the Application Container](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/docker/multiple-processes/#run-the-backend-in-the-application-container) shows.

The application log then shows "Listen address "127.0.0.1" provided via options.", and on Linux, `sudo ss -ltnp` shows the backend on `127.0.0.1:4283`.

> Warning
>
> **Working Directory.** Start the application from its own folder: if it doesn't find *appsettings.json* in its working directory, the backend listens on all interfaces again.

Where the backend runs decides how you keep its port closed:

| Setup | How the port stays private | Read |
|---|---|---|
| Backend started by the application on a server | Loopback address, and the firewall closes every port the site doesn't use | [Configure the Firewall](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/linux/ubuntu/#configure-the-firewall) |
| Backend in the application container | Loopback address, and port 4283 isn't published with `-p` | [Run the Backend in the Application Container](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/docker/multiple-processes/#run-the-backend-in-the-application-container) |
| Backend in its own container | `expose` in Docker Compose makes the port reachable for the other services only; no `ports` entry | [Run the Backend in Its Own Container](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/docker/multiple-processes/#run-the-backend-in-its-own-container) |
| Backend on its own machine | The firewall allows port 4283 for the web servers only | [Host the Document Editor in a Service](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/windows/windows-service/#host-the-document-editor-in-a-service) |
| Azure App Service on Linux | App settings bind the backend to the loopback address; a container needs no exposed port for it | [Configure the Application With App Settings](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/azure/app-service-linux/#configure-the-application-with-app-settings) |

When the backend runs on another machine, keep both machines in a private network. [Network Ports](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/linux/requirements/#network-ports) lists every port an application uses.

### Run With Least Privileges

The Document Editor backend and its worker processes run under the account of your application, so every right of this account is also a right of the backend. The account needs read access to the application folder and write access only where the application writes.

- **Containers.** The Dockerfile of [Write the Dockerfile](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/docker/dockerfile/#write-the-dockerfile) switches to the non-root user `app` of the .NET images with `USER $APP_UID`. Chiseled images go further: they contain only the files .NET needs, have no shell or package manager and run as a non-root user by default. TX Text Control needs the gconv modules in them, as [Use a Chiseled Image](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/docker/dockerfile/#use-a-chiseled-image) shows.
- **Linux with systemd.** The service runs as *www-data*, which owns the application files; the backend and its worker processes run as the same user, as [Run the Application as a systemd Service](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/linux/ubuntu/#run-the-application-as-a-systemd-service) shows.
- **IIS.** The application pool runs as `IIS AppPool\<name>` and needs read and execute permissions on the application folder. Keep the generated *web.config*: without it, IIS may serve files such as *MyApp.runtimeconfig.json* to the public. Don't use top-level wildcard bindings such as `http://*:80/`. [IIS](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/windows/iis/#create-the-site-and-the-application-pool) shows the steps.
- **Windows services.** A dedicated account with the right to log on as a service runs the service and every process it starts. Grant it access only to the folders, certificates and databases the service uses, as [What Changes in a Service](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/windows/windows-service/#what-changes-in-a-service) describes.

### Keep Secrets Out of the Deployment

The license of TX Text Control is compiled into your assembly when you build it, so a deployment needs no license key or other secret for TX Text Control at run time. The only secret TX Text Control involves is the API token of the Text Control Private NuGet Feed, and it's needed only while packages are restored:

- **Keep *nuget.config* out of the project folder.** A web project copies *.config* files from its folder into the build and publish output, so a *nuget.config* next to the project file would be deployed together with its API token. Keep it in the folder above.
- **Pass it to Docker as a build secret.** A build secret is available only during the restore and isn't written to any image layer. A *.dockerignore* file keeps *nuget.config* out of the build context. [Keep nuget.config Out of the Image](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/docker/dockerfile/#keep-nuget-config-out-of-the-image) shows both.
- **Store the credentials as pipeline secrets.** Build servers write *nuget.config* from secrets before the first `dotnet` command, as [CI/CD Authentication](https://docs.textcontrol.com/tx-text-control-dotnet-server/installation/nuget/private-feed/ci-cd/llms-full.txt) describes.
- **Replace a leaked token.** If a token or a *nuget.config* was shared by mistake, delete the token under **Manage API tokens** and create a new one, as [Creating an API Token](https://docs.textcontrol.com/tx-text-control-dotnet-server/installation/nuget/private-feed/api-token/llms-full.txt) describes.

Certificates for digital signatures are secrets of your application; [Digital Signatures](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/signatures/#keep-the-private-key-safe) covers them.

### Watch the Logs

`DocumentEditorWorkerManager` forwards the output of the backend to the logging of your application, with the prefix `[TXTextControl.Web.Server.Core]`, and the configuration file in the backend package writes nothing to disk. The messages show whether the backend started and which editors connect: for each editor, the backend logs "Starting web editor worker process with connection ID" followed by the ID.

- **Windows services.** The event log shows messages of level *Warning* and higher by default. Set `Logging:EventLog:LogLevel:Default` to `Information` to see the backend's output.
- **File logging.** With `LogTarget` set to `File`, the backend writes log files to its `FolderPath`, *./logs* in the working directory in the configuration the package ships, and the account needs write access there.

### Keep the Packages Current

Service packs contain bug fixes and minor updates to many components, and Text Control recommends updating your applications to the latest service pack. Subscribers receive an email when one is released.

- **Update all packages together.** Keep the engine package, the web packages and the npm packages of the Document Editor and the Document Viewer on the same major version; client and server packages of different versions can cause connection problems. `dotnet list package --outdated` lists the packages with newer versions, as [Updating NuGet Packages](https://docs.textcontrol.com/tx-text-control-dotnet-server/installation/upgrading/nuget/llms-full.txt) shows.
- **Redeploy a separate backend.** A backend that runs in its own container or on its own machine is updated when you rebuild and redeploy it, not with the application.
- **Scan for known vulnerabilities.** [SBOM](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/sbom/llms-full.txt) describes the signed SBOMs of the TX Text Control packages and the vulnerability checks of the .NET SDK.

### Next Steps

- [Authentication](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/authentication/llms-full.txt): protect the endpoints of the editor, the viewer and your controllers.
- [WebSocket Security](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/websockets/llms-full.txt): check the WebSocket connection of the Document Editor before it's accepted.
- [Deployment Guide](https://docs.textcontrol.com/tx-text-control-dotnet-server/deployment/llms-full.txt): the complete steps for Windows, Linux, Docker, Kubernetes and the cloud.
- [Security Overview](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/overview/llms-full.txt): the parts of an application and how they fit into its security.

---

## Nearby

- **Previous:** [SBOM](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/sbom/llms-full.txt)
- **Next:** [Compliance](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/compliance/llms-full.txt)
