u/testix001

I scanned 50 open-source Spring Boot projects for config drift. 53% had issues that wouldn't fail a single test.

I got tired of manually diffing application-dev.yml against application-prod.yml before every deployment. So I built a small CLI to do it automatically — and then ran it against 50 well-known Spring Boot projects on GitHub to see how widespread the problem actually is.

The short version: 26 out of 50 projects had at least one issue.

The three patterns I kept seeing

1. The Actuator leak

# application-dev.yml
management.endpoints.web.exposure.include: "*"

Completely reasonable in dev. Dangerous when it drifts into prod. /actuator/env returns all your environment variables — including secrets. /actuator/heapdump lets anyone download a full JVM heap dump.

The Spring PetClinic — Spring's own reference application — ships with include: * as a default. 78 modules across the scanned projects had this.

2. The database schema destroyer

# application-dev.yml
spring.jpa.hibernate.ddl-auto: update

Convenient in dev. If it drifts into prod and your entity model changes, Hibernate silently modifies your production schema. No migration script, no warning. I've seen this kill a database.

3. The missing feature flag

# dev + staging: feature.new-payment-flow.enabled: true
# prod:          (key doesn't exist)

Spring Boot falls back to null. If you're lucky you get a NullPointerException at startup. If you're not, it silently disables a feature in production that worked fine in every test environment.

Why this is so hard to catch

Code review won't find it — you're looking at diffs, not at the relationship between files. Tests won't find it — they run against one profile. CI won't find it — the app starts fine.

The tool

I built spring-drift to catch this in CI or as a pre-deploy check:

$ spring-drift scan ./src/main/resources

✓ Found 4 profiles: default, dev, staging, prod
✗ 7 drift issues found

[DANGEROUS_DEFAULT] management.endpoints.web.exposure.include
  default:  health,info
  dev:      *
  prod:     *           ← matches dev — likely accidental

[DANGEROUS_DEFAULT] spring.jpa.hibernate.ddl-auto
  dev:      update
  prod:     update      ← destructive in production

[MISSING_KEY] feature.new-payment-flow.enabled
  dev:      true
  prod:     <missing>   ← will fall back to null

Report written to drift-report.md

Single binary via GraalVM Native Image (no JRE needed), ~26ms on a real project, outputs Markdown you can paste into a PR.

GitHub: https://github.com/jolle93/spring-boot-config-drift-detector

Docs + download: https://julianpaul.dev/spring-drift

reddit.com
u/testix001 — 3 days ago