fix(security): Remove hardcoded DB password from release artifact

Production incident: quant.taxbaik.com/login threw 28P01 (password
authentication failed) after the July 7 deployment's
appsettings.Production.json carried a stale DB password. Root cause
chain:

1. The DB password for quantengine_app had been rotated at some
   point; the new password was saved to
   /home/kjh2064/.config/quantengine.env on the server, but that
   file was never wired into the quantengine.service systemd unit
   (no EnvironmentFile= directive), so it was silently unused.
2. Every appsettings.Production.json we've generated in CI
   (including tonight's prepare-release.yml) baked in a PLACEHOLDER
   password ("quantengine_app") that was never the real credential
   to begin with -- copied forward from an earlier debugging session
   without ever being verified against the live DB.

Immediate production fix (out of band, via SSH): patched the active
deployment's appsettings.Production.json with the current working
password (verified via direct psql connection) and restarted the
service. Login confirmed HTTP 200 with a clean journalctl afterward.

This commit fixes the root cause in the pipeline: prepare-release.yml
no longer writes a ConnectionStrings block into the artifact at all.
Baking any DB password (even a correct one) into a build artifact
that ships as a downloadable Gitea Release asset is unsafe and goes
stale on every credential rotation. The correct fix is for
quantengine.service to load ConnectionStrings__DefaultConnection from
/home/kjh2064/.config/quantengine.env via systemd's EnvironmentFile=,
which overrides appsettings.Production.json at runtime per standard
ASP.NET Core configuration precedence. That unit-file edit requires
interactive sudo and must be applied by hand on the server (tracked
separately, not part of this commit).

IMPORTANT: the release quant_20260711.1.6ab270f already published
tonight was built before this fix and still lacks any DB config --
do not deploy it via deploy-prod.yml until the systemd
EnvironmentFile wiring is confirmed on the server, or the login
outage will recur.
This commit is contained in:
2026-07-12 00:28:13 +09:00
parent f0e8ef9b4f
commit e49922e188
+7 -4
View File
@@ -79,10 +79,13 @@ jobs:
import json
import pathlib
# NOTE: No ConnectionStrings here on purpose. The real DB
# password lives only in /home/kjh2064/.config/quantengine.env
# on the production server and is injected via systemd
# EnvironmentFile (ConnectionStrings__DefaultConnection),
# which overrides this file at runtime. Never bake secrets
# into a build artifact that ends up in a Gitea Release.
config = {
"ConnectionStrings": {
"DefaultConnection": "Host=127.0.0.1;Database=quantenginedb;Username=quantengine_app;Password=quantengine_app;Search Path=quantengine;"
},
"Logging": {
"LogLevel": {
"Default": "Information"
@@ -96,7 +99,7 @@ jobs:
)'
test -s ./publish/appsettings.Production.json || { echo "ERROR: appsettings.Production.json is empty"; exit 1; }
echo "✓ Production config created"
echo "✓ Production config created (no secrets included)"
- name: Package Artifact
run: |