Configure the services

Installation overview ยท Install and upgrade

Configuration files

Each service uses appsettings-common.json and appsettings.json from its application directory. Put server-specific settings and secrets in a protected appsettings.<machine-name>.json file, using the Windows computer name. Later files override earlier ones:

  1. appsettings-common.json, then its environment and machine overrides.
  2. appsettings.json, then its environment, machine and user overrides.

Restrict secret-bearing files and configuration backups to administrators and the relevant service identity. Do not commit credentials to source control.

API

Configure these values in the API settings:

Setting Purpose
ConnectionStrings:OTBackupDb Application database connection.
ConnectionStrings:OTBackupAuditLogDb Audit database connection when the SQL audit sink is enabled.
AppSettings:AuthenticationService Local, Keycloak or Azure; see Authentication setup.
LocalAuthentication:SetupUri Public HTTPS UI address ending in /setup-account for invitations and recovery links.
Cors:UI Exact UI origin, including scheme and port.
Kestrel:Endpoints:Https HTTPS listener and certificate path/password when using a PFX.

The API applies application database migrations at startup, so its database identity needs migration permissions during deployment. Only the API connects to the application and audit databases; configure database credentials, permissions and SQL logging sinks there, not in the UI.

When upgrading an existing audit database, widen both AuditLog.Who and AuditLog.SourceName to nvarchar(256), add nullable AuditLog.ActorUserId as nvarchar(450), and align any custom SQL sink column lengths. The API migration adds and indexes ActorUserId in OTBackupDb, and backfills ID-only rows only by matching an existing user ID. It snapshots local UserName or external ProviderUserName; it does not match by username.

API startup migrations update OTBackupDb, not a separate OTBackupAuditLogDb; the SQL audit sink does not create or migrate its table. For a separate sink database, apply the schema changes there as well:

IF COL_LENGTH(N'dbo.AuditLog', N'Who') BETWEEN 0 AND 511
    ALTER TABLE dbo.AuditLog ALTER COLUMN Who nvarchar(256) NULL;

IF COL_LENGTH(N'dbo.AuditLog', N'SourceName') BETWEEN 0 AND 511
    ALTER TABLE dbo.AuditLog ALTER COLUMN SourceName nvarchar(256) NULL;

IF COL_LENGTH(N'dbo.AuditLog', N'ActorUserId') IS NULL
    ALTER TABLE dbo.AuditLog ADD ActorUserId nvarchar(450) NULL;

IF NOT EXISTS (
    SELECT 1 FROM sys.indexes
    WHERE name = N'IX_AuditLog_ActorUserId'
      AND object_id = OBJECT_ID(N'dbo.AuditLog'))
    CREATE INDEX IX_AuditLog_ActorUserId ON dbo.AuditLog(ActorUserId);

The application migration cannot backfill a separate sink database unless it can join that database's audit rows to the application user table by ID. Leave unmatched legacy IDs unchanged; they display as Deleted user (<ID>) rather than being attributed by a reused username. Do not remove ActorUserId or rewrite Who during rollback if preserving captured actor history is required. Without the schema update, the SQL sink cannot write new audit records.

The API generates an integration key on first startup if none is configured. Protect the API machine settings file and see Integration credentials.

Reverse proxy forwarding

Forwarded client addresses and schemes are ignored by default. To enable them, configure each service independently in that service's own settings: the UI trust list describes proxies in front of the UI, and the API trust list describes proxies in front of the API. Do not put this setting in shared appsettings-common.json unless both services intentionally share the same proxy topology.

For example, add this to the UI or API configuration as appropriate:

{
  "ReverseProxy": {
    "Enabled": true,
    "TrustedProxies": [ "192.0.2.10", "2001:db8:100::/48" ],
    "ForwardLimit": 1
  }
}

TrustedProxies accepts explicit IPv4 or IPv6 addresses and CIDR networks. ForwardLimit defaults to one forwarded hop; when multiple proxies append forwarded values, set a positive finite limit and list every intermediary that the application should trust. Enabling forwarding without valid trusted entries, or with an invalid address/network or hop limit, prevents the service from starting.

The UI and API process X-Forwarded-For and X-Forwarded-Proto only from configured trusted proxies. Configure each proxy to remove or sanitize forwarding headers supplied by clients before adding its own values. Restrict the application listener so only the configured proxy peers can reach it; otherwise clients may bypass the proxy. Use HTTPS at the public edge and configure the external service URLs and callbacks with their public HTTPS addresses.

Authentication audit details distinguish the immediate transport peer (PeerIpAddress / ApiPeerIpAddress) from the address resolved by trusted forwarding (ResolvedClientIpAddress). When the UI reports an authentication failure to the API, ReportedClientIpAddress is UI-supplied metadata and is not treated as a trusted API-side network identity.

UI, Queue and TEE

  • Configure the UI HTTPS listener and certificate and the shared API address and ports. Provider settings and client secrets belong on the API, not the UI.
  • Keep shared actor names, addresses and ports consistent across services. Defaults assume the services run on one server.
  • The core TEE uses AppSettings:WorkerType set to Server. Agent deployments use Agent and DOTNET_ENVIRONMENT=Agent; install required vendor software and grant the TEE identity access.

The UI uses operational file logging and reports authentication requests rejected before reaching the API to the API for audit logging. If reporting is unavailable, the UI retains its local log; reports are not queued for retry.

When changing an address or port, update the affected services, listeners, firewall rules, reverse proxy and integration URLs together. Use trusted TLS certificates and avoid exposing unnecessary ports.

An error has occurred. This app may no longer respond until reloaded. Reload ๐Ÿ—™