fix(config): reject demo and templated Config Server authority before JGit - #328
fix(config): reject demo and templated Config Server authority before JGit#328cursor[bot] wants to merge 11 commits into
Conversation
Removing the demo Git default is not fail-closed: Spring Cloud Config 5.0.4 still starts with an unset or empty CONFIG_REPO_URI. Validate destination authority at default-profile startup and keep native fixtures independently startable. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
… JGit Move the default-profile check to an EnvironmentPostProcessor so blank, retired-demo, and request-templated CONFIG_REPO_URI values fail closed before JGit afterPropertiesSet, including cloneOnStart=true. Keep the InitializingBean as defense in depth. native plus prod/production now requires xtrmetl.config.allow-native=true. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Show the next action for native fixtures versus a reviewed CONFIG_REPO_URI so operators can start or stop without reading the full doctoring note. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Port #327 live isolation and native-only composition into #328 without dropping demo, template, Unicode, or SCP matching. Unset CONFIG_REPO_URI now fails with the finite authority message after systemEnvironment is removed, and mixed native profiles cannot skip Git destination checks. Verified: ./mvnw -B -pl config-server -am test (Temurin 25, 19 tests).
|
Hourly fire inherited the remaining #327 fail-closed evidence onto this successor without dropping demo/template matching.
Do not merge #322/#327/#189 separately. Hosted checks after this push are not polled here. |
|
Current exact |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4785b03d33
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (normalized.endsWith(".git")) { | ||
| normalized = normalized.substring(0, normalized.length() - 4); | ||
| } | ||
| if (normalized.endsWith("/")) { | ||
| normalized = normalized.substring(0, normalized.length() - 1); |
There was a problem hiding this comment.
Strip trailing slash before matching the demo path
When CONFIG_REPO_URI is https://github.com/your-repo/config-repo.git/, the .git check runs while the path still ends in /; removing the slash afterward leaves /your-repo/config-repo.git, which does not equal the retired path. The processor therefore accepts this equivalent demo destination, and clone-on-start=true can contact GitHub instead of failing before JGit; normalize the trailing slash before stripping .git.
AGENTS.md reference: AGENTS.md:L21-L21
Useful? React with 👍 / 👎.
| */ | ||
| @Override | ||
| public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { | ||
| if (ConfigServerRepositoryAuthority.requireSafeProfileComposition(environment.getActiveProfiles())) { |
There was a problem hiding this comment.
Include effective default profiles in the native-only check
When profiles are configured through spring.profiles.default and no explicit active profile is set, Spring uses those defaults for @Profile matching but getActiveProfiles() remains empty. Consequently, spring.profiles.default=native,prod plus any accepted Git URI passes this check while Spring can still select the native backend, bypassing the requirement that native be the sole effective profile; inspect default profiles as well when the active set is empty.
AGENTS.md reference: AGENTS.md:L21-L21
Useful? React with 👍 / 👎.
| continue; | ||
| } | ||
| activeCount++; | ||
| if ("native".equalsIgnoreCase(profile.trim())) { |
There was a problem hiding this comment.
Match the native profile with Spring's case semantics
With spring.profiles.active=NATIVE, this case-insensitive comparison treats native mode as active and makes the environment post-processor skip URI validation, while Spring's profile matching does not treat NATIVE as the native profile. The Git backend and @Profile("!native") validator can therefore be created, and with clone-on-start=true JGit may contact a blank or retired-demo destination before the unordered validator runs; only skip validation for the exact profile name Spring recognizes.
AGENTS.md reference: AGENTS.md:L21-L21
Useful? React with 👍 / 👎.
What changed
Default-profile Config Server rejects unset, blank, unresolved, request-templated, and retired-demo
CONFIG_REPO_URIbefore JGitafterPropertiesSet. The YAML token remains exactly${CONFIG_REPO_URI}with no default. Thenativeprofile remains a local-fixture mode and must be the only active profile; this slice has noxtrmetl.config.allow-nativeoverride.This supersedes #327 at
43c4049and #322 at50ddcc0.Root cause and repair lineage
#327 removed the demo fallback but an ordinary validator bean was not ordered ahead of JGit. Spring Cloud Config 5.0.4 can reach Git initialization before such a validator when cloning is enabled, and empty authority could otherwise defer failure until request time.
The branch therefore uses
ConfigServerRepositoryAuthorityEnvironmentPostProcessorafter config-data loading and registers it throughMETA-INF/spring.factories. It validates repository authority before context refresh and keepsConfigServerRepositoryAuthorityValidatoras defense in depth.Fresh review found a separate registration-evidence defect: the branch also carried
META-INF/spring/org.springframework.boot.env.EnvironmentPostProcessor, while Spring Boot 3.5 registersEnvironmentPostProcessorthroughMETA-INF/spring.factories. The extra resource was inert on Boot 3.5 and the doctoring incorrectly described it as a future Boot 4 discovery path.b1fdb4a871fb1dbeb9cfb9ade44143e199d90104: repository configuration test requires the unsupported alternate registration resource to be absent.e295de44c3b26087d007c70db2d682c48b0ae9cc: deletes only that inert registration resource;spring.factoriesremains the executable registration authority.4785b03d335e6536f30743da57b35ed2dace8b4c: records the current Spring Boot contract and the Boot 4 package move (org.springframework.boot.env.EnvironmentPostProcessor→org.springframework.boot.EnvironmentPostProcessor) instead of inventing a second registry.Behavior and operator boundary
CONFIG_REPO_URIto a reviewed concrete Git destination before starting the default profile.${CONFIG_REPO_URI...}, request templates, and the retired demo host/path fail closed before Git access.nativemay run without a remote only when it is the sole active profile. Any mixednative,*composition fails closed.Exact-head evidence — 2026-09-08
Current exact head is
4785b03d335e6536f30743da57b35ed2dace8b4condevelop@e8373b7193019e72b7a860c9f14d109fe7963ee7.Repository-owned exact-head gates are terminal GREEN: CI
34203686648, SAST Semgrep34203686538, Security Scan34203686653, Dependency Review34203686667, and CycloneDX SBOM34203686546.The last current review thread was informational rather than a defect. The exact source catches
IllegalArgumentExceptionaround unresolved property resolution and maps it to the stable missing-authority failure. Spring Framework 6.2 documentsPlaceholderResolutionExceptionas extendingIllegalArgumentException; Spring Boot 3.5 documentsEnvironmentPostProcessorregistration throughMETA-INF/spring.factories. The thread is now resolved after exact-head/source verification. No qualifying independent APPROVED review exists yet.Required central CodeQL PR
34203686651is terminal FAILURE for the same.githubowner-path sequencing defect reproduced independently on #334.Detect CodeQL languagesjob101988124568succeeded. Compatibility jobs actions101991003365and java-kotlin101991003443failed atRelease runner or enforce current-head CodeQL verdictby 08:39Z, while the same generation'sDispatch current-head CodeQL scanjob101994390693did not start until 08:49:39Z and then succeeded. This is not a consumer trigger or runner-starvation finding. The canonical repair remainsContextualWisdomLab/.github#1929: the exact current-generation scan/SARIF receipt must exist and authenticate before compatibility enforcement consumes it.The source slice is ready for independent review. Ready-for-review status is review admission only; merge remains blocked on a valid current-head central CodeQL verdict and qualifying independent approval. No predecessor receipt, synthetic status, source-neutral retrigger, self-approval, or gate weakening is accepted.
Merge / succession boundary
Keep unmerged until the unchanged exact head has terminal applicable required gates, zero valid unresolved findings, and qualifying independent review. After normal acceptance, #189/#322/#327 may be retired only by complete-succession verification. Do not force-push or destructively rebase.