Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions .github/workflows/publish.pypi.helper.yml

This file was deleted.

86 changes: 40 additions & 46 deletions .github/workflows/publish.pypi.sdk.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
name: Publish to PyPI (Python SDK & Helper)
on:
workflow_dispatch:
inputs:
publish:
description: 'Publish to PyPI (uncheck to build and scan SBOM only)'
required: false
default: 'true'
type: boolean

jobs:
# Extract versions for both SDK and Helper
Expand All @@ -10,23 +16,23 @@ jobs:
sdk-version: ${{ steps.extract-sdk-version.outputs.version }}
helper-version: ${{ steps.extract-helper-version.outputs.version }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6.0.2

- name: Extract SDK version
id: extract-sdk-version
working-directory: ./sdk/python/core
run: |
VERSION=$(python3 setup.py --version 2>/dev/null || grep -Po 'version\s*=\s*["\x27]\K[^\x27"]*' setup.py)
echo "SDK Version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "SDK Version: ${VERSION}"
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"

- name: Extract Helper version
id: extract-helper-version
working-directory: ./sdk/python/helper
run: |
VERSION=$(python3 setup.py --version 2>/dev/null || grep -Po 'version\s*=\s*["\x27]\K[^\x27"]*' setup.py)
echo "Helper Version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Helper Version: ${VERSION}"
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"

# Fail fast if either version is already on PyPI - before SBOM generation
# and before the release manager is asked to approve anything.
Expand Down Expand Up @@ -64,10 +70,10 @@ jobs:
needs: [get-versions, validate-versions]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6.0.2

- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v6.2.0
with:
python-version: '3.11'

Expand Down Expand Up @@ -112,11 +118,11 @@ jobs:
--label=ksm,sdk,python,security

- name: Archive SDK SBOM
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7.0.1
with:
name: sbom-sdk-${{ needs.get-versions.outputs.sdk-version }}
path: sdk-sbom.json
retention-days: 90
retention-days: 10

# Generate and publish SBOM for Helper.
# Installs core from source first so this job has no dependency on core
Expand All @@ -128,10 +134,10 @@ jobs:
needs: [get-versions, validate-versions]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6.0.2

- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v6.2.0
with:
python-version: '3.11'

Expand Down Expand Up @@ -179,71 +185,59 @@ jobs:
--label=ksm,helper,python,security

- name: Archive Helper SBOM
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7.0.1
with:
name: sbom-helper-${{ needs.get-versions.outputs.helper-version }}
path: helper-sbom.json
retention-days: 90
retention-days: 10

# Single publish job - both SDK and Helper publish under one environment: prod
# gate so the release manager only presses the button once.
# Both SBOM jobs must complete (and be verified by Manifest Cyber) before
# this job runs.
# Uses PyPI Trusted Publishing (OIDC) — no long-lived API tokens required.
publish:
name: Publish KSM Python SDK and Helper to PyPI
needs: [generate-sdk-sbom, generate-helper-sbom, get-versions]
if: ${{ github.event.inputs.publish == 'true' }}
environment: prod
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
id-token: write

steps:
- name: Get the source code
uses: actions/checkout@v3
uses: actions/checkout@v6.0.2

- name: Set up Python 3.9
uses: actions/setup-python@v4
uses: actions/setup-python@v6.2.0
with:
python-version: '3.9'

- name: Install build tools
run: |
python3 -m pip install --upgrade pip setuptools
python3 -m pip install build twine 'wheel>=0.46.3' # wheel pin: CVE-2026-24049
python3 -m pip install build 'wheel>=0.46.3' # wheel pin: CVE-2026-24049

# ── SDK ────────────────────────────────────────────────────────────────

- name: Retrieve PyPI token from KSM (SDK)
id: ksmsecrets-sdk
uses: Keeper-Security/ksm-action@master
with:
keeper-secret-config: ${{ secrets.KSM_PYPI_PUBLISHER_PYPI_SDK_CONFIG }}
secrets: |
-aBWi3-yU_qvatNh0Eaqew/field/password > PYPI_API_TOKEN

- name: Build and publish SDK
- name: Build SDK
working-directory: ./sdk/python/core
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ steps.ksmsecrets-sdk.outputs.PYPI_API_TOKEN }}
run: |
python3 -m build --no-isolation
python3 -m twine upload --verbose dist/*

# ── Helper ─────────────────────────────────────────────────────────────
run: python3 -m build --no-isolation

- name: Retrieve PyPI token from KSM (Helper)
id: ksmsecrets-helper
uses: Keeper-Security/ksm-action@master
- name: Publish SDK to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
keeper-secret-config: ${{ secrets.KSM_PYPI_PUBLISHER_PYPI_SDK_CONFIG }}
secrets: |
-aBWi3-yU_qvatNh0Eaqew/field/password > PYPI_API_TOKEN
packages-dir: sdk/python/core/dist/

- name: Build and publish Helper
# ── Helper ─────────────────────────────────────────────────────────────

- name: Build Helper
working-directory: ./sdk/python/helper
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ steps.ksmsecrets-helper.outputs.PYPI_API_TOKEN }}
run: |
python3 -m build --no-isolation
python3 -m twine upload --verbose dist/*
run: python3 -m build --no-isolation

- name: Publish Helper to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: sdk/python/helper/dist/
6 changes: 5 additions & 1 deletion .github/workflows/test.python.helper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ name: Test-Python-Helper
on:
pull_request:
branches: [ master ]
paths:
- 'sdk/python/helper/**'
- 'sdk/python/core/**'
- '.github/workflows/test.python.helper.yml'

jobs:
test-cli:
Expand All @@ -14,7 +18,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v6.2.0
with:
python-version: ${{ matrix.python-version }}

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/test.python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: Test-Python
on:
pull_request:
branches: [ master ]
paths:
- 'sdk/python/core/**'
- '.github/workflows/test.python.yml'

jobs:
test-python:
Expand All @@ -17,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v6.2.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
112 changes: 112 additions & 0 deletions sdk/python/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Change Log

## 17.2.1
* KSM-900 - Added IL5 (DoD Impact Level 5) region support — token prefix `IL5` resolves to `il5.keepersecurity.us`

## 17.2.0
* **Breaking**: Minimum Python version raised from 3.6 to 3.9
- Python 3.6-3.8 users: pip will automatically install v17.1.x (no action needed)
- Security/bug fixes backported to v17.1.x until August 2026 via `legacy/sdk/python/core/v17.1.x` branch
* **Security**: KSM-777 - Raised dependency floors to resolve multiple CVEs
- `cryptography>=46.0.5` (was >=39.0.1, resolves CVE-2026-26007 elliptic curve vulnerability)
- `urllib3>=2.6.3` unconditionally (was split between urllib3 1.x/2.x, resolves CVE-2026-21441, CVE-2025-66471, CVE-2025-66418, CVE-2025-50181, CVE-2025-50182)
- `requests>=2.32.4` (resolves CVE-2024-47081 .netrc credentials leak)
* Removed `importlib_metadata` dependency (stdlib `importlib.metadata` available since Python 3.8)
* Added Python 3.13 support and CI testing

## 17.1.0
* **Security**: KSM-760 - Fixed CVE-2026-23949 (jaraco.context path traversal) in SBOM generation workflow
- Upgraded jaraco.context to >= 6.1.0 in SBOM build environment
- Build-time dependency only, does not affect runtime or published packages
* **Security**: Added version-specific urllib3 dependency to address CVE-2025-66418 and CVE-2025-66471 (HIGH severity)
- Python 3.10+: Uses urllib3>=2.6.0 (latest security fixes)
- Python 3.6-3.9: Uses urllib3>=1.26.0,<1.27 (compatible with boto3/AWS storage)
* **Security**: KSM-695 - Fixed file permissions for client-config.json (created with 0600 permissions)
* KSM-763 - Fixed file upload/download operations failing when using proxy with verify_ssl_certs=False
- Added verify_ssl_certs and proxy_url parameters to file upload/download functions
- Previously these settings were ignored, causing SSL verification errors when using proxies
* KSM-749 - Fixed client version detection to prevent stale .dist-info metadata causing "invalid client version id" errors
- Introduced single source of truth for version via _version.py
- Client version now prioritizes package __version__ attribute over importlib_metadata
- Fixes issue where package upgrades left stale metadata causing backend authentication failures
* KSM-740 - Added transmission public key #18 for Gov Cloud Dev support
* KSM-732 - Fixed notation lookup when record shortcuts exist (duplicate UID handling)
* KSM-650 - Improved error messages for malformed configuration files
* KSM-628 - Added GraphSync links support

## 17.0.0
* KSM-566 - Added parsing for KSM tokens with prefix
* KSM-631 - Added links2Remove parameter for files removal
* KSM-635 - HTTPError should include response object

## 16.6.6
* KSM-552 - Stop generating UIDs that start with "-"

## 16.6.5
* KSM-529 - Handle broken encryption in records and files

## 16.6.4
* KSM-488 - Remove unused package dependencies

## 16.6.3
* KSM-479 - Remove dependency on `distutils` due to Python 3.12 removing it

## 16.6.2
* KSM-463 - Python SDK - Fix a bug when fields is null
* KSM-458 - Python SDK - Remove core's dependency on the helper module. Fixes [issue 488](https://github.com/Keeper-Security/secrets-manager/issues/488)

## 16.6.1
* KSM 444 - Python - Added folderUid and innerFolderUid to Record

## 16.6.0
* KSM-413 - Added support for Folders
* KSM-434 - Improved Passkey field type support

## 16.5.4
* KSM-405 - Added new script field type and oneTimeCode to PAM record types
* KSM-410 - New field type: Passkey
* KSM-394 - Ability to load configuration from AWS Secrets Manager using AWS AIM role in EC2 instance or AWS IAM user
* KSM-416 - Fix OS detection bug
* KSM-400 - Unpinned few dependencies

## 16.5.3
* KSM-393 - Fix file permissions on localized Windows OS

## 16.5.2
* KSM-375 - Make HTTPError to be more informative
* KSM-376 - Support for PAM record types
* KSM-381 - Transactions
* Fixed [Issue 441](https://github.com/Keeper-Security/secrets-manager/issues/441) - Bug caused by space in username

## 16.5.1
* KSM-371 - Fix Windows Config file permissions issue
* KSM-370 - Upgrade to latest cryptography>=39.0.1 library

## 16.5.0
* KSM-313 - Improved Keeper Notations. New parser, new escape characters, Notation URI, search records by title and other meta data values in the record
* KSM-319 - `KEY_CLIENT_KEY` in configurations is missing in certain situations
* KSM-356 - Ability to create of the new custom field

## 16.4.2
* Fix to support dynamic client version

## 16.4.1
* Upgrading and pinning `cryptography` dependency to 38.0.3

## 16.4.0
* Record deletion
* KSM-305 - Support for Canada and Japan data centers
* KSM-308 - Improve password generation entropy
* KSM-240 - Config file permission checking (Create new client-config.json with locked down permission/ACL mode. Print STDERR warning if client-config.json ACL mode is too
open. To disable ACL mode checking and setting, set environmental variable `KSM_CONFIG_SKIP_MODE` to `TRUE`. To prevent
warnings of the client-config.json being too open, set environmental variable `KSM_CONFIG_SKIP_MODE_WARNING` to `TRUE`.
For Unix, `client-config.json` is set to `0600` mode. For Windows, `client-config.json` has only the user that created
the `client-config.json` and the **Administrator** group.)

## 16.3.5
* Removed non-ASCII characters from source code. Added Python comment flag to allow non-ASCII to source code, just in case.
* Allow `enforceGeneration`, `privacyScreen`, and `complexity` in record fields when creating a record.
* Record creation validation. Making sure that only legitimate record field types, notes section, and title of the record can be saved

## 16.3.4
* Provide better exception messages when the config JSON file is not utf-8 encoded.
Loading
Loading