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

Author · public projectConfig mistakes can fail the Maven build instead of failing at pod startup.
QuarkusMavenKubernetesHelmKustomize
  • 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.

Static analysis tool: validates Quarkus configuration against Kubernetes manifests.

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.

CodeLevelMeaning
BUILD_TIME_NULL_ENVerrorBuild-time property references ${VAR} with no default.
SECRET_IN_ENV_DEFAULTerrorSecret key uses ${VAR:literal} — the default is the secret.
LOCALHOST_JDBC_IN_K8SerrorA client URL in a manifest points at loopback (localhost).
TLS_VERIFICATION_DISABLEDerrortrust-all=true or tls.verification=none.
CORS_WILDCARD_WITH_CREDENTIALSerrorCORS origins=* with credentials enabled.
SWAGGER_IN_PRODerrorSwagger UI forced into prod.
PLAINTEXT_DB_PASSWORDerrorLiteral 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.