Overview
The goal is to keep the connection string off appsettings.json and stored in a
protected file on the server that only the service account (www-data) can read. This prevents
developers with SSH access from accidentally (or intentionally) seeing production credentials.
Step 1 — Clear appsettings.json
"ConnectionStrings": {
"AppDbConnection": ""
}
Step 2 — Create the Secrets File
sudo mkdir -p /etc/your-api
sudo nano /etc/your-api/secrets.env
Add the connection string inside the file:
ConnectionStrings__AppDbConnection=Host=...;Port=5432;Database=...;Password=...;Username=postgres;
The __ (double underscore) maps to ConnectionStrings:AppDbConnection in .NET
configuration automatically. No code changes needed.
Step 3 — Lock Down File Permissions
sudo chown www-data:www-data /etc/your-api/secrets.env
sudo chmod 600 /etc/your-api/secrets.env
Only www-data can read the file. Developer accounts will get Permission denied if
they try to open it.
Step 4 — Update the systemd Service File
sudo nano /etc/systemd/system/your-api-uat.service
[Unit]
Description=your-api uat Service
After=network.target
[Service]
WorkingDirectory=/var/www/your-api/uat/app
ExecStart=/usr/bin/dotnet /var/www/your-api/uat/app/BF.Tracker.Api.dll
Restart=always
RestartSec=10
SyslogIdentifier=your-api-uat
User=www-data
EnvironmentFile=/etc/your-api/secrets.env
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
Step 5 — Reload and Restart the Service
sudo systemctl daemon-reload
sudo systemctl restart your-api-uat
daemon-reload is required every time the service file is edited. Without it, systemd will still
use the old version of the file.
Step 6 — Verify
sudo systemctl status your-api-uat
How It Works
Here's a summary of who can access the secrets file and why:
| Who | Can read secrets.env? |
|---|---|
www-data (service account) |
✅ Yes |
| Developer accounts | ❌ No — Permission denied |
| Root / Sysadmin | ✅ Yes |
The app reads the connection string normally via .NET configuration — no code changes needed:
var conn = builder.Configuration.GetConnectionString("AppDbConnection");
Cleanup (When No Longer Needed)
If you need to fully remove the service and secrets file from the server:
# Stop and remove the service
sudo systemctl stop your-api-uat
sudo systemctl disable your-api-uat
sudo rm /etc/systemd/system/your-api-uat.service
sudo systemctl daemon-reload
# Delete the secrets file
sudo rm -rf /etc/your-api