Release Python SDK v17.2.2#1007
Open
stas-schaller wants to merge 11 commits into
Open
Conversation
Three-layer mechanism for injecting a custom EC public key at runtime, allowing IL5 (key_id=20) and other isolated deployments to connect without adding environment-specific keys to the hardcoded map. Layer 1 (core): generate_transmission_key() accepts custom_public_key_b64; key rotation handler retries instead of raising when a custom key is set. Layer 2 (OTT): 4-segment IL5 token (IL5:clientKey:keyId:b64Key) writes key material to config at init time so Layer 1 picks it up automatically. Layer 3 (API): SecretsManager() accepts server_public_key and server_public_key_id constructor params for code-first initialization. Also fixes the long-standing missing 'raise' in generate_transmission_key and prevents __init__ from silently resetting a non-standard key_id to the default when a custom key is present. Tests: 5 new tests (one per layer + raise fix + end-to-end retry flow), all 64 tests pass.
KSM-901 is the JavaScript IL5 ticket; the Python IL5 dynamic-key work is tracked under KSM-932.
…mic-key KSM-932: Python IL5 custom server public key support
…ser hardening, docstrings, tests, README
- Populate empty LICENSE files in core, helper, cli, and storage packages
with the root MIT text. PyPI was about to publish packages declaring
license=MIT with zero license text.
- Update core.py runtime Python version guard from <3.6 to <3.9 to match
setup.py python_requires and the 3.9 floor announced in v17.2.0.
- Harden the 4-segment IL5 OTT parser: raise ValueError on wrong segment
count, empty keyId/serverPublicKey segments, or invalid base64 in the
serverPublicKey segment. Previously these silently degraded to
default-key behavior; a credential-handling code path should fail loud.
- Add docstrings to SecretsManager.__init__'s new server_public_key /
server_public_key_id params and generate_transmission_key's new
custom_public_key_b64 param. Document precedence between provisioning
paths. Generic wording for isolated deployments.
- Add 8 new tests (72/72 passing):
- Layer 1 config-file path supplies custom key
- Layer precedence: programmatic > token > config
- Token > config when no programmatic params
- 4 parser-negative cases (3 segments, 5+ segments, empty segments,
invalid base64)
- Non-IL5 prefix with extra segments stays backwards-compatible
- Add a short "Custom Server Public Key (Isolated Deployments)" section
to the core README pointing at the new constructor params and OTT
format. Generic language; deployment-specific details deferred to the
official docs.
…owup KSM-932: Python SDK v17.2.2 follow-up — LICENSE, Python 3.9 guard, parser hardening, docs
There was a problem hiding this comment.
An organization admin can view or raise the cap at claude.ai/admin-settings/claude-code. The cap resets at the start of the next billing period.
Once the cap resets or is raised, push a new commit or reopen this pull request to trigger a review.
idimov-keeper
previously approved these changes
May 22, 2026
Raise KeeperError with actionable messages instead of cryptic TypeError
when None reaches the base64/url-safe decoders from an incomplete config
or empty server response field.
Utility-level guards (utils.py, crypto.py): base64_to_bytes,
url_safe_str_to_bytes, base64_to_string, CryptoUtils.url_safe_str_to_bytes.
base64_to_string also gains a binascii.Error handler for parity.
Per-call-site guards in core.py at the three unguarded config.get sites
(lines 814, 863, 874) name the specific missing ConfigKey ('appKey',
'clientKey') and direct the user to reinitialize with a fresh OTT.
Adds 7 regression tests in tests/config_error_test.py. Full core suite
(79 tests) green.
CHANGELOG and README updated.
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
Python Core SDK v17.2.2 and Python Helper v1.1.2. The release adds opt-in support for callers that need to supply a custom server public key (KSM-932) for isolated deployments where the server public key is not shipped with the SDK, and fixes a customer-reported bug where the config-decoding utilities raised cryptic
TypeErrorinstead of an actionableKeeperErrorwhen passedNonefrom an incomplete config (KSM-808). Default behaviour is unchanged for all standard Keeper deployments.Changes
New Features
serverPublicKeyfield in storage, a 4-segment one-time-token extension (REGION:clientKey:keyId:serverPublicKeyBase64), and newserver_public_key/server_public_key_idparameters onSecretsManager. Also fixes a long-standing missingraiseingenerate_transmission_keyand prevents__init__from silently resetting a non-standardkey_idback to the default when a custom key is configured.Bug Fixes
TypeErroronNone-valued config keys (KSM-808): config-decoding utilities (base64_to_bytes,url_safe_str_to_bytes,base64_to_string,CryptoUtils.url_safe_str_to_bytes) now raiseKeeperErrorwith actionable messages instead ofTypeErrorwhen passedNone. Per-call-site guards incore.py(lines 814, 863, 874) name the specific missingConfigKey(appKey,clientKey) and direct the user to reinitialize with a fresh One-Time Token. 7 new regression tests intests/config_error_test.py. Customer-reported.setup.py— legal/compliance gap that would publish to PyPI as license-claim-without-text.core.pyruntime check raised on< 3.6whilesetup.pypython_requiresand classifiers required>= 3.9(announced in v17.2.0). Updated guard to match.keyIdorserverPublicKeysegments, invalid base64) now raiseValueErrorat construction. Previously these silently degraded to default-key behavior — wrong fail-mode for a credential-handling code path.Maintenance
>=17.2.2. Helper version pairs 1:1 with core.keeper_globals.pyand smoke test assertions.SecretsManager.__init__'s new constructor params andgenerate_transmission_key's new arg, including precedence documentation.Breaking Changes
None. The new field, parameter, and 4-segment token format are opt-in. The new parser errors only fire on inputs that previously silently degraded — no caller relying on documented v17.2.1 behavior is affected. Default behaviour is unchanged for all standard Keeper deployments.
Related Issues