Deployment
Development runs on defaults that are deliberately unsuitable for a real deployment. This page covers what changes.
Publish
Section titled “Publish”dotnet publish src/Docsentry.Web/Docsentry.Web.csproj -c Release -o /path/to/outputSet ASPNETCORE_ENVIRONMENT to your environment name. Anything other than Development turns on
the strict checks described below, which is the point.
The four settings that will stop you
Section titled “The four settings that will stop you”Three fail loudly at startup. One fails quietly, and is the harder afternoon.
ConnectionStrings:DefaultConnection
Section titled “ConnectionStrings:DefaultConnection”Must authenticate as a member of DocsentryAppRole - not the deployment or schema-owner
principal. A startup probe verifies this and refuses to continue if the application is running
with more privilege than it should have.
DataProtection:KeyPath
Section titled “DataProtection:KeyPath”Required outside Development. An absolute path, outside the content root. The host refuses to start without it.
The key ring protects every authentication cookie, the “remember this machine” two-factor cookie, stored secrets such as the antivirus API key, and the keys that encrypt every stored document. Reading it is enough to forge a session for any user. Losing it without a backup means losing every encrypted document.
It is deliberately absent from appsettings.json rather than present-but-empty, because a value
in that file would override one supplied by the hosting environment.
DataProtection:CertificateThumbprint
Section titled “DataProtection:CertificateThumbprint”Optional, but required in three cases: a non-Windows host, a multi-instance deployment, and any deployment whose recovery plan involves different hardware.
Omitted, the key ring is protected with Windows DPAPI, which is machine-scoped - a DPAPI-protected
key ring cannot be restored onto a different machine. Set a thumbprint from the CurrentUser
or LocalMachine My store to encrypt with an X.509 certificate instead.
AllowedHosts
Section titled “AllowedHosts”Ships as the placeholder docsentry.example.com.
Database
Section titled “Database”Deploy the schema before starting the application - see Database deployment.
Two distinct database identities are required:
| Principal | Does | Must not |
|---|---|---|
| Deployment | Creates the database, applies the Identity migration and DMS scripts, writes schema versions. | Be used by the running application. |
| Application | Data reads and writes under deployed grants. Member of DocsentryAppRole. |
Create databases, alter schema, or apply schema versions. |
Governance surfaces such as the audit log and workflow history are append-only for the application principal, and the audit log is additionally sealed and verified, so a defect or compromise in the application cannot rewrite history unnoticed.
Enable Transparent Data Encryption on the database and encrypt its backups. Document contents are encrypted by the application, but the database holds metadata, extracted OCR text and the audit trail.
Behind a reverse proxy
Section titled “Behind a reverse proxy”Populate Security:ForwardedHeaders:KnownProxies or KnownNetworks with your proxy, and set
ForwardLimit to the number of proxies in the chain.
Handling is fail-closed: with neither configured, forwarded headers are not trusted at all. That is the safe default - it stops a spoofed client address slipping past address-based rate limiting - but the cost of leaving it unconfigured is that every request appears to originate from the proxy, which makes per-address rate limiting meter your proxy rather than your users.
Terminate TLS at the proxy or at the application, and confirm Security:Hsts matches your
intent before enabling preload - preload is difficult to reverse.
If you use the optional content host, the proxy must forward both hostnames to the application and
preserve the requested host, AllowedHosts must list both, and the proxy’s access log should drop
the ct query parameter. See Security hardening.
Optional components
Section titled “Optional components”Install what you need, and know what you are giving up otherwise:
| Component | Without it |
|---|---|
| LibreOffice | Office documents get no preview. |
| Tesseract | Document contents are not indexed. |
| A real antivirus scanner | Change Antivirus:ScannerKind from its default. The default recognises only a test string. |
| SQL Server Full-Text Search | Search falls back to a scan, which is slow at scale. |
See Installation.
Pre-flight checklist
Section titled “Pre-flight checklist”- Schema deployed;
900_schema_contract.sqlpasses -
ConnectionStrings:DefaultConnectionuses the least-privilege application principal, supplied from the environment or a secret store -
DataProtection:KeyPathset, absolute, outside the content root, on an encrypted volume, and backed up -
DataProtection:CertificateThumbprintset if non-Windows, multi-instance, or portable recovery -
AllowedHostsset to the real hostname (both hostnames if a content host is used) -
ASPNETCORE_ENVIRONMENTset to a non-Development value - Forwarded headers configured if behind a proxy
- Transparent Data Encryption enabled, and database backups encrypted
- Storage root and log directory on encrypted volumes;
Storage:WorkingCopyPathon local disk, outside backups -
Antivirus:ScannerKindchanged from the default test scanner -
BreachedPasswords:Sourceset toOfflineFilewith a current corpus -
Emailconfigured,PublicSite:BaseUrlset, and a test email received - invitations depend on it - Bootstrap administrator seeded and enrolled in two-factor, then
Bootstrap:AdminPasswordremoved from the environment - Audit seal log events routed to an external log collector
- Backups covering the database, the storage root, and the key ring
- A restore rehearsed - see Backup and restore
Verifying
Section titled “Verifying”curl https://your-host/api/v1/healthThen sign in, upload a document, and confirm it previews. That exercises configuration, the database, encrypted storage, the scanner, and the background jobs in one pass. Finally, open Audit integrity under Administration and run a verification; it should report Healthy.
Scale-out
Section titled “Scale-out”Multiple instances against one database work, with two requirements: the key ring must be shared and certificate-protected rather than DPAPI-protected, and the storage root must be shared storage that every instance can reach.
Related
Section titled “Related”- Security hardening - the full security surface.
- Background jobs - the startup schema check.
- Performance and tuning - capacity settings.