Skip to content

fix(config): reject demo and templated Config Server authority before JGit - #328

Open
cursor[bot] wants to merge 11 commits into
developfrom
cursor/bc-6f907607-b8dc-4f5c-b3f2-b77815182e47-c454
Open

fix(config): reject demo and templated Config Server authority before JGit#328
cursor[bot] wants to merge 11 commits into
developfrom
cursor/bc-6f907607-b8dc-4f5c-b3f2-b77815182e47-c454

Conversation

@cursor

@cursor cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown

What changed

Default-profile Config Server rejects unset, blank, unresolved, request-templated, and retired-demo CONFIG_REPO_URI before JGit afterPropertiesSet. The YAML token remains exactly ${CONFIG_REPO_URI} with no default. The native profile remains a local-fixture mode and must be the only active profile; this slice has no xtrmetl.config.allow-native override.

This supersedes #327 at 43c4049 and #322 at 50ddcc0.

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 ConfigServerRepositoryAuthorityEnvironmentPostProcessor after config-data loading and registers it through META-INF/spring.factories. It validates repository authority before context refresh and keeps ConfigServerRepositoryAuthorityValidator as 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 registers EnvironmentPostProcessor through META-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.

  • RED b1fdb4a871fb1dbeb9cfb9ade44143e199d90104: repository configuration test requires the unsupported alternate registration resource to be absent.
  • GREEN e295de44c3b26087d007c70db2d682c48b0ae9cc: deletes only that inert registration resource; spring.factories remains the executable registration authority.
  • Doctoring 4785b03d335e6536f30743da57b35ed2dace8b4c: records the current Spring Boot contract and the Boot 4 package move (org.springframework.boot.env.EnvironmentPostProcessororg.springframework.boot.EnvironmentPostProcessor) instead of inventing a second registry.

Behavior and operator boundary

  • Set CONFIG_REPO_URI to a reviewed concrete Git destination before starting the default profile.
  • Blank, unresolved ${CONFIG_REPO_URI...}, request templates, and the retired demo host/path fail closed before Git access.
  • native may run without a remote only when it is the sole active profile. Any mixed native,* composition fails closed.
  • Git credentials, trust material, HTTP authentication, repository availability, retry/timeout policy, and readiness remain separate controls.
  • Rollback must not restore the demo repository.

Exact-head evidence — 2026-09-08

Current exact head is 4785b03d335e6536f30743da57b35ed2dace8b4c on develop@e8373b7193019e72b7a860c9f14d109fe7963ee7.

Repository-owned exact-head gates are terminal GREEN: CI 34203686648, SAST Semgrep 34203686538, Security Scan 34203686653, Dependency Review 34203686667, and CycloneDX SBOM 34203686546.

The last current review thread was informational rather than a defect. The exact source catches IllegalArgumentException around unresolved property resolution and maps it to the stable missing-authority failure. Spring Framework 6.2 documents PlaceholderResolutionException as extending IllegalArgumentException; Spring Boot 3.5 documents EnvironmentPostProcessor registration through META-INF/spring.factories. The thread is now resolved after exact-head/source verification. No qualifying independent APPROVED review exists yet.

Required central CodeQL PR 34203686651 is terminal FAILURE for the same .github owner-path sequencing defect reproduced independently on #334. Detect CodeQL languages job 101988124568 succeeded. Compatibility jobs actions 101991003365 and java-kotlin 101991003443 failed at Release runner or enforce current-head CodeQL verdict by 08:39Z, while the same generation's Dispatch current-head CodeQL scan job 101994390693 did not start until 08:49:39Z and then succeeded. This is not a consumer trigger or runner-starvation finding. The canonical repair remains ContextualWisdomLab/.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.

seonghobae and others added 7 commits August 13, 2026 19:51
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>
@opencode-agent opencode-agent Bot added area: auth Authentication, authorization, identity, or tenant isolation priority: medium Normal-priority or P2 work status: draft Draft pull request type: bug Defect or incorrect behavior labels Aug 22, 2026
@seonghobae
seonghobae marked this pull request as ready for review August 27, 2026 16:37

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Devin Review

@seonghobae seonghobae removed the status: draft Draft pull request label Sep 6, 2026
@seonghobae seonghobae added status: needs-review Open pull request requiring current-head review or checks bug Something isn't working labels Sep 6, 2026 — with ChatGPT Codex Connector
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).
@seonghobae

Copy link
Copy Markdown
Collaborator

Hourly fire inherited the remaining #327 fail-closed evidence onto this successor without dropping demo/template matching.

  • Unset CONFIG_REPO_URI now fails with the finite authority message after inherited systemEnvironment is removed, so a runner-level URI cannot satisfy the unset case.
  • native must be the only active profile; mixed native,default fails closed. The weaker allow-native production mix is gone.
  • Boot 3.5 discovery is pinned to META-INF/spring.factories.
  • Local verify: ./mvnw -B -pl config-server -am test on Temurin 25, 19 tests, BUILD SUCCESS.

Do not merge #322/#327/#189 separately. Hosted checks after this push are not polled here.

@seonghobae
seonghobae marked this pull request as draft September 8, 2026 08:19

Copy link
Copy Markdown
Collaborator

Current exact 4785b03d335e6536f30743da57b35ed2dace8b4c verification refresh after registration repair: CI 34203686648 is terminal SUCCESS on ubuntu/windows/macos; SBOM 34203686546 SUCCESS; Dependency Review 34203686667 SUCCESS. SAST 34203686538 and Security Scan 34203686653 remain queued; CodeQL PR 34203686651 remains non-terminal. The PR is therefore Draft again. Predecessor receipts are not being reused. The resolved Devin registration thread is source-repaired; the remaining current-head security/CodeQL lanes and independent review still gate Ready/merge.

@seonghobae
seonghobae marked this pull request as ready for review September 8, 2026 09:10
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-08T09:19:42.550876Z 4785b03 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +139 to +143
if (normalized.endsWith(".git")) {
normalized = normalized.substring(0, normalized.length() - 4);
}
if (normalized.endsWith("/")) {
normalized = normalized.substring(0, normalized.length() - 1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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())) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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())) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: auth Authentication, authorization, identity, or tenant isolation bug Something isn't working priority: medium Normal-priority or P2 work status: needs-review Open pull request requiring current-head review or checks type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants