Skip to content

Fixes #34464: Accept upper/mixed-case Azure AD tenant GUIDs in SAML validation - #34522

Closed
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fixes-34464-accept-upper-mixed-case-azure-ad-tenan-7c2cdd
Closed

detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fixes-34464-accept-upper-mixed-case-azure-ad-tenan-7c2cdd

Conversation

@detail-app

@detail-app detail-app Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Detail bug report: View on Detail

Describe your changes:

Fixes #34464

I fixed a case-sensitivity defect in SamlValidator.validateAzureAdTenant that rejected valid Azure AD tenant GUIDs entered in upper- or mixed-case, because:

  • the tenant-ID format regex [a-f0-9\\-]{36} admitted only lowercase hex digits, so a GUID like A1B2C3D4-E5F6-7890-1234-567890ABCDEF failed with "Invalid Azure AD tenant ID format" before any network check ran; and
  • the follow-on issuer.contains(tenantId) comparison was case-sensitive, and Azure's OpenID-config endpoint returns a lowercase issuer even for an uppercase path-segment GUID — so fixing the regex alone would convert the error into "Tenant ID mismatch".

These are one logical defect (case-sensitive tenant-ID handling end-to-end). The config simply could not be saved for an uppercase/mixed-case tenant GUID; no security or data-integrity impact.

Type of change:

  • Bug fix

High-level design:

N/A — small change.

The fix normalizes the extracted tenant ID to lowercase once (tenantId.toLowerCase(Locale.ROOT)) right after extraction, then uses the normalized value for both the GUID format check and the OpenID-config URL construction, and for the issuer.contains(...) comparison. The admin's original (pre-normalization) input is preserved in all error messages, so the admin still sees what they typed.

Tests:

Use cases covered

  • Admin saves a SAML SAML config with an Azure AD entity ID whose tenant GUID is upper-case (e.g. https://sts.windows.net/A1B2C3D4-.../) → config saves successfully.
  • The same config with a lowercase GUID still saves (no regression).

Unit tests

  • I added unit tests for the new/changed logic.
  • Files updated: openmetadata-service/src/test/java/org/openmetadata/service/security/auth/validator/SamlValidatorTest.java — added validateSamlConfigurationAcceptsUppercaseAzureTenantGuid, which drives the public validateSamlConfiguration entry point (the same path SystemRepository.validateSecurityConfiguration calls in production) with an uppercase entity-ID GUID, a mocked lowercase issuer, and a reachable in-process SSO server. It asserts null (success). This test fails on the unfixed code with Invalid Azure AD tenant ID format: A1B2C3D4-... and would also fail if only the regex were loosened (the lowercase issuer would not contains the uppercase tenant, producing "Tenant ID mismatch"), so it guards both halves of the defect.

Backend integration tests

  • Not applicable (no backend API changes). The validation is exercised through its public entry point by the unit test above.

Ingestion integration tests

  • Not applicable (no ingestion changes).

Playwright (UI) tests

  • Not applicable (no UI changes).

Manual testing performed

  • Verified Azure's external invariant the fix relies on: curl https://login.microsoftonline.com/72F988BF-86F1-41AF-91AB-2D7CD011DB47/v2.0/.well-known/openid-configuration returns HTTP 200 with an issuer whose path GUID is the lower-cased form — identical to the lowercase-GUID response.
  • Ran a live probe invoking the production SamlValidator.validateSamlConfiguration (no mocks) against the real public Microsoft Azure AD tenant 72f988bf-86f1-41af-91ab-2d7cd011db47, once with the entity ID GUID in upper case and once in lower case. Both returned null (success) with a real HTTPS roundtrip to login.microsoftonline.com.
  • I could not run the full docker dev stack + admin-UI click-through: bringing up docker/development/docker-compose.yml failed because Docker Hub returned 429 Too Many Requests pulling mysql:8.0, and no openmetadata/server image is cached locally; the Elasticsearch service (cached elastic image) started fine. The substitute live probe above exercises the exact production code path the server uses at config-save time, so the behavioral guarantee is covered.

UI screen recording / screenshots:

Not applicable.

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • My PR is linked to a GitHub issue via Fixes #<issue-number> above.
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: I updated the migration scripts or explained why it is not needed.
  • For UI changes: I attached a screen recording and/or screenshots above.
  • I have added tests (unit / integration / Playwright as applicable) and listed them above.
  • I have added a test that covers the exact scenario we are fixing. For complex issues, comment the issue number in the test for future reference.

Automatic Fixes PRs can be configured here.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

✅ Playwright Results — workflow succeeded

Validated commit fcdd0c9c7d65ae1668f7bfef8c3ae020b971c382 in Playwright run 36970432094, attempt 1.

✅ 4685 passed · ❌ 0 failed · 🟡 1 flaky · ⏭️ 1 skipped · 🧰 0 lifecycle flaky

Performance

Blocking targets: ✅ met · Optimization targets: 🟡 in progress

Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting.

🕒 Full workflow signal wall (to summary) 1h 55m 59s

⏱️ Max setup 4m 40s · max shard execution 19m 22s · max shard-job elapsed before upload 25m 4s · reporting 19s

🌐 222.53 requests/attempt · 2.20 app boots/UI scenario · 40.53% common-shard skew

Optimization targets still in progress:

  • Common shard skew was 40.53% (convergence target: at most 15%).
  • Browser traffic was 222.53 requests per attempt (convergence target: fewer than 200).
  • Application boot ratio was 2.2 per UI scenario (10950 boots / 4973 scenarios; convergence target: at most 1).
Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky
✅ Shard advanced-search-01 65 0 0 0 0 0
✅ Shard advanced-search-02 65 0 0 0 0 0
✅ Shard chromium-01 148 0 0 0 0 0
✅ Shard chromium-02 128 0 0 0 0 0
✅ Shard chromium-03 145 0 0 0 0 0
✅ Shard chromium-04 147 0 0 0 0 0
✅ Shard chromium-05 177 0 0 0 0 0
✅ Shard chromium-06 186 0 0 0 0 0
✅ Shard chromium-07 131 0 0 0 0 0
✅ Shard chromium-08 173 0 0 0 0 0
✅ Shard chromium-09 142 0 0 0 0 0
✅ Shard chromium-10 171 0 0 0 0 0
✅ Shard chromium-11 137 0 0 0 0 0
✅ Shard chromium-12 227 0 0 0 0 0
✅ Shard chromium-13 142 0 0 0 0 0
✅ Shard chromium-14 164 0 0 0 0 0
✅ Shard chromium-15 179 0 0 0 0 0
🟡 Shard chromium-16 161 0 1 0 0 0
✅ Shard chromium-17 147 0 0 0 0 0
✅ Shard chromium-18 159 0 0 0 0 0
✅ Shard chromium-19 164 0 0 0 0 0
✅ Shard chromium-20 146 0 0 0 0 0
✅ Shard chromium-21 136 0 0 0 0 0
✅ Shard chromium-22 156 0 0 0 0 0
✅ Shard chromium-23 156 0 0 1 0 0
✅ Shard chromium-24 177 0 0 0 0 0
✅ Shard chromium-25 156 0 0 0 0 0
✅ Shard chromium-26 153 0 0 0 0 0
✅ Shard data-asset-rules-01 65 0 0 0 0 0
✅ Shard domain-isolation-01 16 0 0 0 0 0
✅ Shard global-state-01 34 0 0 0 0 0
✅ Shard import-export-01 84 0 0 0 0 0
✅ Shard import-export-02 68 0 0 0 0 0
✅ Shard ingestion-01 41 0 0 0 0 0
✅ Shard ingestion-02 52 0 0 0 0 0
✅ Shard reindex-01 41 0 0 0 0 0
✅ Shard search-01 17 0 0 0 0 0
✅ Shard search-rbac-01 29 0 0 0 0 0
🟡 1 flaky test(s) (passed on retry)
  • Pages/CustomProperties.spec.ts › String (shard chromium-16, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

✅ SSO Login Nightly — PASSED

View workflow run · Commit 45c2a60

Provider Status Pass Fail Flaky Skip Duration
basic ✅ pass 23 0 0 0 6m 38s
ldap ✅ pass 7 0 0 0 1m 06s
keycloak-oidc-confidential ✅ pass 12 0 0 0 1m 33s
keycloak-oidc-public ✅ pass 11 0 0 0 1m 39s
msal-mock ✅ pass 7 0 0 0 0m 49s
auth0-mock ✅ pass 6 0 0 0 0m 44s
okta ⏩ skipped - - - - -
keycloak-azure-saml ✅ pass 18 0 0 0 5m 52s
keycloak-azure-saml-crosssite ⏩ skipped - - - - -

Totals: 84 passed · 0 failed · 0 flaky · 0 skipped · duration 18m 24s

@shah-harshit

Copy link
Copy Markdown
Contributor

Superseded by #35537, which combines this change with other queued fixes.

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a manual request Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚦 Removed from the merge queue — manual (2026-10-15T12:27:03Z)

The entry left the queue before it was built, so no checks ran against it.

timothybrush pushed a commit to timothybrush/OpenMetadata that referenced this pull request Oct 16, 2026
…, SAML tenant GUIDs, dead-code removals (open-metadata#35537)

* Fixes open-metadata#35106: gate certification tag strip on supportsCertification in BundleWarmupBatcher (open-metadata#35167)

* chore(searchIndex): remove unused ReindexingMetrics methods (open-metadata#35392)

* chore: remove unused TeamsMessage Fact/Action model classes (open-metadata#35386)

* chore: remove unused awaitVectorCompletionWithDetails and VectorCompletionResult (open-metadata#35389)

* Fixes open-metadata#35078: authorize VIEW_BASIC on lineage edge-details read endpoints (open-metadata#35140)

* Fixes open-metadata#34464: Accept upper/mixed-case Azure AD tenant GUIDs in SAML validation (open-metadata#34522)

---------

Co-authored-by: mohitdeuex <mohit.y@deuexsolutions.com>

This branch was previously deployed

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

Labels

safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Detail Bug] SAML SSO: Azure AD tenant GUID validation rejects uppercase/mixed-case GUIDs

2 participants