case study 02 / quarkus-doctor
Open source · Maven plugin
quarkus-doctor
A Java CLI and Maven plugin that compares Quarkus config with Kubernetes, Helm, and Kustomize YAML in CI. No live cluster required.
quarkus-doctor · Maven plugin · CLI
- Fails mvn verify on config errors
- JDK 11+ · no cluster needed
Problem
KubeLinter, Checkov, and Trivy never open application.properties. Quarkus quarkus.config.build-time-mismatch-at-runtime fails at startup, not in CI. The crash is a CrashLoop, not a red build.
Design
quarkus-doctor is a Java CLI and a Maven plugin (JDK 11+, no Node, no live cluster). It diffs application.properties / application.yaml against this repo’s Deployment, Helm, and Kustomize YAML. Bind the scan to Maven verify and the build fails on the current rule set: build-time ${VAR} with no default, secret defaults in Git, localhost JDBC in a manifest, trust-all TLS, CORS * with credentials, Swagger in prod, and the rest of the published rules.
Path
Clone, mvn install, then mvn verify in the app module—or run the CLI JAR, or the GitHub Action that builds the CLI from source and scans a path. --ci fails on warnings. --json and a report file are available. The plugin writes target/quarkus-doctor.json. It never talks to a cluster.
What the current rule set fails on
Full list is in the docs. These are the errors that match the brief on the home page.
| Code | Level | Meaning |
|---|---|---|
| BUILD_TIME_NULL_ENV | error | Build-time property references ${VAR} with no default. |
| SECRET_IN_ENV_DEFAULT | error | Secret key uses ${VAR:literal} — the default is the secret. |
| LOCALHOST_JDBC_IN_K8S | error | A client URL in a manifest points at loopback (localhost). |
| TLS_VERIFICATION_DISABLED | error | trust-all=true or tls.verification=none. |
| CORS_WILDCARD_WITH_CREDENTIALS | error | CORS origins=* with credentials enabled. |
| SWAGGER_IN_PROD | error | Swagger UI forced into prod. |
| PLAINTEXT_DB_PASSWORD | error | Literal password in config, not ${VAR}. |
Constraints
- Not on Maven Central. This is an early public preview.
- A green scan means no hits in the current rule set, not a full security audit.
- Build-time detection is a prefix list in the source, not Quarkus’s official lock-icon catalog.
Decisions
Config vs YAML in CI
The gap is between Quarkus config and the manifests in Git. The tool reads both. It does not need oc, kubectl, or a running API server.
Maven verify as the default gate
If the scan is a separate ritual, it will be skipped. Binding scan to verify makes the failure look like any other test failure.
Fail closed on the known-bad set
Trust-all TLS, secret literals in defaults, loopback JDBC in a manifest, and Swagger forced into prod are errors. Missing env in YAML can warn or info when there is no local manifest.
Limits
- If env is injected by another chart, ignore ENV_VAR_NOT_IN_MANIFEST.
- A scan with no findings is not a guarantee the app is production-safe.
- Helm --fix skips templates. Ignore lists live in .quarkus-doctor.yml.