Skip to content

Release KSM CLI v1.3.0#917

Open
stas-schaller wants to merge 1 commit intomasterfrom
release/tool/cli/v1.3.0
Open

Release KSM CLI v1.3.0#917
stas-schaller wants to merge 1 commit intomasterfrom
release/tool/cli/v1.3.0

Conversation

@stas-schaller
Copy link
Contributor

@stas-schaller stas-schaller commented Jan 21, 2026

Summary

Release branch for CLI v1.3.0 — adds OS-native keyring storage as the default credential store, with security hardening and dependency fixes.

Changes

New Features

  • OS-native keyring storage (KSM-800): new profiles stored in macOS Keychain, Windows Credential Manager, or Linux keyring by default; keyring is an optional install (pip install keeper-secrets-manager-cli[keyring]); --ini-file flag opts into explicit file-based storage
  • Profile delete command (KSM-810): new ksm profile delete <name> subcommand; completes the recovery path referenced by KsmCliIntegrityException

Bug Fixes

  • --ini-file flag respected by all subcommands (KSM-814): all profile and config subcommands now correctly use the --ini-file path — profile list, profile active, profile export, profile import, profile init, profile setup; config show, config color, config cache, config record-type-dir, config editor
  • Keyring integrity verification (KSM-805): SHA-256 hash now persisted as a separate Keychain entry and verified on every load; tampered entries raise KsmCliIntegrityException with a ksm profile delete recovery hint; backward-compatible (existing entries bootstrap silently on next save)
  • Active profile clearing on delete (KSM-810): delete_profile() now clears active_profile in the common config when the active profile is deleted, preventing a broken-keychain state on subsequent invocations
  • Upgrade-path warning (KSM-804): warn on stderr when keyring is active but empty and a legacy keeper.ini exists, with a --ini-file recovery hint; fixed duplicate warnings from redundant Profile instantiation in command handlers
  • INI file permissions (KSM-691): keeper.ini created atomically at 0600 via os.open() (eliminates TOCTOU window on Unix); set_config_mode always runs on every write so Windows ACLs (icacls) are applied to new files and pre-existing bad permissions are corrected on re-save
  • Env var config reload: _reload_config() now correctly re-applies KSM_CONFIG and KSM_CONFIG_BASE64_* environment variable configs on reload instead of falling through to disk discovery
  • CVE-2026-23949 (KSM-761): upgraded jaraco.context to >=6.1.0 (path traversal; build-time dependency only)
  • Record create payload (KSM-702): custom: [] now always included when creating records with no custom fields; previously the key was silently omitted, causing schema inconsistency with Vault and Commander
  • Profile name validation before OTT redemption (KSM-815): profile name is validated before the one-time token is redeemed; names containing whitespace or exceeding 64 characters are rejected immediately, preventing the token from being consumed on a failed init
  • Profile name strict validation (KSM-829): early profile name check now uses the same [a-zA-Z0-9_-]{1,64} pattern as keyring storage; previously path-traversal characters and special characters passed the early check, consuming the one-time token before the stricter validator fired
  • Shell crash with click>=8.2 (KSM-818): ksm shell crashed on any command when click-repl==0.3.0 was resolved alongside click>=8.2 (protected_args became read-only in Click 8.2); pinned click-repl to <0.3.0
  • JSON output key for custom fields (KSM-820): ksm secret get --json now outputs custom fields under "custom" (was "custom_fields"), matching the canonical V3 record format used by Commander and the Keeper Vault
  • Test keyring isolation (KSM-828): unit tests no longer write mock data to the real system keyring; added KeyringConfigStorage.is_available mock to all 19 Profile.init() call sites used as test scaffolding in secret_test.py, exec_test.py, and secret_inflate_test.py
  • boto3 import for non-AWS --ini-file profiles (KSM-831): AwsConfigProvider import deferred to inside the elif storage == "aws": branch; users without [aws] extra no longer hit Missing import dependencies: boto3 when loading any non-AWS profile via --ini-file
  • lkru utility removed (KSM-832): removed the lkru utility integration and KSM_CONFIG_KEYRING_UTILITY_PATH environment variable; lkru requires the same D-Bus Secret Service daemon as the Python keyring library and is not a headless alternative; is_available() now correctly returns False when keyring is not installed or no Secret Service daemon is running, falling back to keeper.ini file storage in both cases

Maintenance

  • Updated prompt-toolkit from ~=2.0 to >=3.0 (fixes pip dependency resolution conflicts)
  • Updated keeper-secrets-manager-core to >=17.2.0, keeper-secrets-manager-helper to >=1.1.0
  • Keyring integration tests (KSM-830): Docker-based integration tests against a real Secret Service backend (dbus + gnome-keyring); new test-cli-keyring CI job across Python 3.10–3.13; test.cli.yml path-filtered to CLI and Python SDK paths

Breaking Changes

  • Python 3.7–3.9 dropped (KSM-799, KSM-817): minimum supported version is now Python 3.10
  • boto3 now optional (KSM-817): boto3 moved out of the base install; AWS sync users must install the [aws] extra: pip install keeper-secrets-manager-cli[aws]

Related Issues

@socket-security
Copy link

socket-security bot commented Jan 21, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedpypi/​prompt-toolkit@​2.0.10 ⏵ 3.0.5290 +1100100100100
Addedpypi/​keyring@​25.7.0100100100100100
Updatedpypi/​click-repl@​0.3.0 ⏵ 0.2.0100100100100100
Addedpypi/​click-help-colors@​0.2100100100100100

View full report

@stas-schaller stas-schaller force-pushed the release/tool/cli/v1.3.0 branch 2 times, most recently from acffcd5 to 31e606c Compare January 23, 2026 18:33
@stas-schaller stas-schaller force-pushed the release/tool/cli/v1.3.0 branch from de67025 to fd8c787 Compare February 24, 2026 20:33
Comment on lines +72 to +129
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install system deps (dbus + gnome-keyring)
run: sudo apt-get install -y gnome-keyring dbus-x11

########## KSM Python SDK (from source)

- name: Install SDK dependencies
working-directory: ./sdk/python/core
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools
python3 -m pip install -r requirements.txt
python3 -m pip install -e .

- name: Install SDK for integrations
working-directory: ./sdk/python/core
run: |
python3 setup.py build install

########## KSM Python Helper (from source)

- name: Install SDK Helper dependencies
working-directory: ./sdk/python/helper
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
python3 -m pip install -e .

- name: Install SDK Helper for integrations
working-directory: ./sdk/python/helper
run: |
python3 setup.py build install

########## CLI with keyring extra

- name: Install CLI with keyring extra
working-directory: ./integration/keeper_secrets_manager_cli
run: pip install -e ".[keyring]" pytest

- name: Run keyring integration tests
working-directory: ./integration/keeper_secrets_manager_cli
run: |
dbus-run-session -- bash -c "
echo '' | gnome-keyring-daemon --unlock --components=secrets,keyring
KSM_KEYRING_INTEGRATION=1 python -m pytest tests/keyring_integration_test.py -v --tb=short
"

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 17 days ago

To fix the problem, explicitly define a permissions block that limits GITHUB_TOKEN to the minimal required rights. In this workflow, the jobs only need to check out code and run Python tests, so read access to repository contents is sufficient; no write or PR/issue permissions are needed.

The best minimal change is to add a workflow-level permissions block near the top of .github/workflows/test.cli.yml, just after the name (or before on:). This block will apply to both test-cli and test-cli-keyring since they do not define their own permissions. We’ll set contents: read, which is the recommended minimal baseline and matches CodeQL’s suggested starting point.

Concretely:

  • Edit .github/workflows/test.cli.yml.
  • Insert:
permissions:
  contents: read
  • Place it between line 2 and line 3 (after name: Test-CLI and the blank line), keeping indentation at the root level.
  • No imports, methods, or other definitions are needed because this is a YAML configuration change only.
Suggested changeset 1
.github/workflows/test.cli.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/test.cli.yml b/.github/workflows/test.cli.yml
--- a/.github/workflows/test.cli.yml
+++ b/.github/workflows/test.cli.yml
@@ -1,5 +1,8 @@
 name: Test-CLI
 
+permissions:
+  contents: read
+
 on:
   pull_request:
     branches: [ master ]
EOF
@@ -1,5 +1,8 @@
name: Test-CLI

permissions:
contents: read

on:
pull_request:
branches: [ master ]
Copilot is powered by AI and may make mistakes. Always verify output.
Add OS-native keyring storage, profile delete command, and multiple
bug fixes for ini-file handling, custom fields, and dependency updates.

Features:
- KSM-800: add OS-native keyring secure storage for CLI configuration
- KSM-810: add profile delete command and fix active profile clearing
- KSM-805: add SHA-256 cross-session integrity verification for keyring config
- KSM-804: warn on stderr when keyring empty and legacy keeper.ini found
- KSM-830: add Docker keyring integration tests against real Secret Service backend

Bug fixes:
- KSM-832: remove lkru utility integration from CLI keyring storage
- KSM-831: defer AwsConfigProvider import to aws storage branch in _load_config
- KSM-829: fix profile name validation to reject path-traversal and special characters
- KSM-828: prevent unit tests from writing mock data to real system keyring
- KSM-820: fix JSON output key custom_fields → custom for interoperability
- KSM-818: pin click-repl<0.3.0 to fix shell crash with click>=8.2
- KSM-817: raise CLI minimum Python to 3.10 and make boto3 optional
- KSM-815: validate profile name before redeeming one-time token
- KSM-814: fix --ini-file ignored by profile setup, config, export, and init subcommands
- KSM-799: drop importlib_metadata backport, use stdlib importlib.metadata
- KSM-702: fix JSON output key custom_fields → custom and ensure custom:[] in record create payload

Maintenance:
- upgrade Python SDK dependency to v17.2.0
- address CVE-2026-23949 via dependency update
@stas-schaller stas-schaller force-pushed the release/tool/cli/v1.3.0 branch from 276fffe to c756510 Compare March 20, 2026 02:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants