Skip to content

COG-1158: Move datasource credentials to DB_USER/DB_PASSWORD env vars - #333

Open
patrickbradley-cog wants to merge 2 commits into
masterfrom
devin/cog-1158-w1-move-datasource-credentials-in-applicationproperties-to
Open

patrickbradley-cog wants to merge 2 commits into
masterfrom
devin/cog-1158-w1-move-datasource-credentials-in-applicationproperties-to

Conversation

@patrickbradley-cog

@patrickbradley-cog patrickbradley-cog commented Sep 30, 2026 •

Copy link
Copy Markdown

Summary

Linear: COG-1158 — W1 · Move datasource credentials in application.properties to environment variables

Removes the plaintext DB password from UserFront/src/main/resources/application.properties (W1 forward-compatible refactor; still Boot 1.5.4 / Java 8).

-spring.datasource.username = root
-spring.datasource.password = avengers1993
+spring.datasource.username = ${DB_USER:root}
+spring.datasource.password = ${DB_PASSWORD}

testWhileIdle, validationQuery, ddl-auto and the MySQL5Dialect line are untouched (W2/W3 pivots).

Why there's a small new class (config/DataSourcePasswordCheck). On Boot 1.5 the @ConfigurationProperties binder resolves placeholders leniently: when DB_PASSWORD is unset, the literal string ${DB_PASSWORD} is used as the password and startup only dies later with a misleading Access denied for user 'root'. The ticket requires startup to fail loudly, so a BeanFactoryPostProcessor calls environment.getRequiredProperty("spring.datasource.password") (strict nested-placeholder resolution) before any bean is created:

IllegalStateException: Datasource password is not configured: set the DB_PASSWORD environment variable
Caused by: IllegalArgumentException: Could not resolve placeholder 'DB_PASSWORD' in value "${DB_PASSWORD}"

It checks the resolved spring.datasource.password, not DB_PASSWORD directly, so anything that overrides the datasource password (the Testcontainers initializer, SPRING_DATASOURCE_PASSWORD, a profile file) still works. It runs after ApplicationContextInitializers, so the harness's initializer overrides are already in place when the check runs.

Local dev. UserFront/application-local.properties.[REDACTED SECRET] is committed. Copy it to UserFront/application-local.properties (git-ignored in UserFront/.gitignore) and run from UserFront/ with SPRING_PROFILES_ACTIVE=local. It lives in the module root, not src/main/resources, because Boot loads file:./application-{profile}.properties from the working directory. That means it works with both mvn spring-boot:run and java -jar, and it never gets packaged into the jar. The two variables are documented in README.md.

Follow-ups / merge notes

Verification (JDK Temurin 8u, MySQL 5.7 in docker on :3306, root password s3cr3t-local)

Environment-only note: with the current JDK 8 update, TLSv1/1.1 are disabled and the Boot-managed Connector/J 5.1.42 can't handshake with MySQL 5.7. So every local run passed ...onlinebanking?useSSL=false as a runtime override (--spring.datasource.url / SPRING_DATASOURCE_URL). This happens on master too and is not changed by this PR.

Scenario Result
java -jar with no DB_PASSWORD exit 1 within ~0.5s: IllegalStateException: Datasource password is not configured: set the DB_PASSWORD environment variable
DB_PASSWORD=wrong java -jar … exit 1, Access denied for user 'root' (real password actually used)
DB_PASSWORD=s3cr3t-local java -jar … Started UserFrontApplication in 3.202 seconds; Tomcat on 8080
SPRING_PROFILES_ACTIVE=local java -jar … with a local application-local.properties, no env vars The following profiles are active: local → Started UserFrontApplication in 3.133 seconds
DB_PASSWORD=s3cr3t-local mvn -B verify Tests run: 1, Failures: 0, Errors: 0 → BUILD SUCCESS
SPRING_DATASOURCE_PASSWORD=s3cr3t-local mvn -B verify (override, no DB_PASSWORD, like the harness) Tests run: 1, Failures: 0, Errors: 0 → BUILD SUCCESS
mvn -B verify with nothing set contextLoads errors with the explicit DB_PASSWORD message (expected, fails fast)

End-to-end flow against MySQL with DB_PASSWORD set:

$ curl -X POST localhost:8080/signup -d 'firstName=Env&lastName=Test&username=envtest&email=envtest@[REDACTED SECRET].com&phone=5551234&password=pw12345'
signup POST -> 302 http://localhost:8080/
$ curl -c cj -X POST localhost:8080/index -d 'username=envtest&password=pw12345'
login POST -> 302 http://localhost:8080/userFront
$ curl -b cj localhost:8080/userFront | grep -o 'Primary Balance\|Savings Balance'
Primary Balance
Savings Balance
mysql> select user_id,username,email from user;
1  envtest  envtest@[REDACTED SECRET].com

(Seeded role(0,'ROLE_USER') first. The app expects that row to exist.)

Link to Devin session: https://app.devin.ai/sessions/433572ebc8644182ba2fd6afcb1285e5
Open in Devin Desktop: https://app.devin.ai/desktop/session/433572ebc8644182ba2fd6afcb1285e5?variant=devin
Requested by: @patrickbradley-cog


Devin Review

Status Commit
⚪ Not started —

Run Devin Review

Devin Review (Staging)


Devin Review

Co-Authored-By: patrick.bradley <patrick.bradley@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: patrick.bradley <patrick.bradley@cognition.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant