feat: SSO identity provider config get/update + signing certificate rotation (REQ-1612) - #994
Open
atlan-owen wants to merge 1 commit into
Open
feat: SSO identity provider config get/update + signing certificate rotation (REQ-1612)#994atlan-owen wants to merge 1 commit into
atlan-owen wants to merge 1 commit into
Conversation
…otation (REQ-1612)
Adds SSOClient methods (sync, async, and pyatlan_v9 equivalents) to read
and update a tenant's SSO identity provider configuration, wrapping the
existing heracles GET /api/service/idp and POST /api/service/idp/{alias}
endpoints:
- get_all_identity_providers() / get_identity_provider(sso_alias)
- update_identity_provider(provider) - full-object replacement; re-reads
after write (endpoint returns an empty body)
- update_signing_certificate(sso_alias, certificate) - get-then-merge
cert swap; accepts PEM or raw base64 and normalizes to the single-line
form the config requires
Design notes:
- SSOProvider (pydantic) uses Extra.allow + an untyped config dict so
unknown Keycloak fields round-trip; the update endpoint treats the
payload as a full replacement, and omitted fields may be silently
reset (see SHA-497, BLDX-634). The msgspec (v9) model cannot capture
unknown top-level fields - limitation pinned in its docstring/tests.
- /idp endpoints require admin workspace permissions
(READ_TENANT_IDP / UPDATE_TENANT_IDP); documented in docstrings.
Validated live on an internal tenant (fs3): list/get, unchanged
round-trip, marker-update-and-revert, PEM-input cert rotation
(DER-identical result), NotFoundError on unknown alias.
Co-Authored-By: Claude Fable 5 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a supported SDK path to read and update a tenant's SSO identity provider configuration, wrapping the existing heracles
GET /api/service/idpandPOST /api/service/idp/{alias}endpoints. Four methods onclient.sso, in sync + async form, in bothpyatlan/andpyatlan_v9/:get_all_identity_providers()/get_identity_provider(sso_alias)update_identity_provider(provider)- full-object replacement; re-reads after write (the endpoint returns an empty body)update_signing_certificate(sso_alias, certificate)- get-then-merge certificate rotation; accepts PEM or single-line base64 and stores the single-line form the config expects; rejects multi-cert bundles, empty, and non-base64 input (newErrorCode.INVALID_CERTIFICATE, ATLAN-PYTHON-400-080;IDP_NOT_FOUND_BY_ALIAS, ATLAN-PYTHON-404-031)Origin: REQ-1612 / ZD-127486 - a customer with an expired SAML signing cert had no supported programmatic way to rotate it (
SSOClientonly wrapped group mappings).Design notes
SSOProviderusesExtra.allow+ an untypedconfigdict so unknown Keycloak fields round-trip; a unit test pins this, including that__atlan_extra__never leaks into payloads.IdentityProviderRepresentationfield set, and pinned as a documented limitation for maintainer input.READ_TENANT_IDP/UPDATE_TENANT_IDP); personas are not an axis here (heracles role resolution excludes persona-tagged roles).get_identity_providerdeliberately stays list+filter rather thanGET /idp/{alias}: probing the dedicated route with an unknown alias returns a generic 400 (code 1000, "Please check your request parameters"), so list+filter keeps clean NotFound semantics; IdP lists are 1-2 entries.Validation
GET /idp,GET /idp/default, andPOST /idp/{alias}- the token path works while interactive logins are gated (enforcement was reverted immediately after).qa-checksgreen: ruff format, ruff check, mypy.GET /idp/{alias}switch, rejected with the probe evidence above.Open questions for maintainers
tests/integration/test_sso_client.pyif you want it in the harness (needs a live tenant with a configured IdP).🤖 Generated with Claude Code