-
Notifications
You must be signed in to change notification settings - Fork 57
Release KSM CLI v1.3.0 #917
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| # Keyring Storage for CLI Configuration | ||
|
|
||
| Starting in v1.3.0, KSM CLI stores profile configuration in the OS-native keyring by default instead of a plaintext `keeper.ini` file. | ||
|
|
||
| ## Why This Change | ||
|
|
||
| Prior to v1.3.0, CLI profiles were stored in `keeper.ini` on disk. This file was created with world-readable permissions by default on Linux and macOS, meaning other users and processes on the same system could read your KSM credentials. | ||
|
|
||
| Keyring storage uses the OS credential manager, which enforces access control at the OS level — other users cannot read entries that don't belong to them. | ||
|
|
||
| ## Platform Support | ||
|
|
||
| | Platform | Keyring Backend | | ||
| |----------|----------------| | ||
| | macOS | Keychain | | ||
| | Windows | Credential Manager | | ||
| | Linux | Secret Service API (e.g. GNOME Keyring, KWallet) | | ||
|
|
||
| Linux requires a running Secret Service daemon (GNOME Keyring, KWallet). See [Linux Setup](#linux-setup). | ||
|
|
||
| ## How It Works | ||
|
|
||
| **New profiles** are stored in the keyring automatically — no `keeper.ini` is created. | ||
|
|
||
| **Existing profiles** in `keeper.ini` continue to work without any migration. The CLI detects which storage backend a profile uses and reads from the correct location. | ||
|
|
||
| ### Using File-Based Storage | ||
|
|
||
| If you need an explicit `keeper.ini` file (e.g. Docker containers, CI/CD pipelines, or shared service accounts), use the `--ini-file` flag: | ||
|
|
||
| ```bash | ||
| # Initialize a profile using file storage | ||
| ksm profile init --ini-file /path/to/keeper.ini | ||
|
|
||
| # Use a specific ini file for a command | ||
| ksm secret list --ini-file /path/to/keeper.ini | ||
| ``` | ||
|
|
||
| File-based profiles created with `--ini-file` are now written with `0600` permissions (owner read/write only). | ||
|
|
||
| ## Linux Setup | ||
|
|
||
| Linux requires a running Secret Service-compatible keyring daemon (e.g. GNOME Keyring or KWallet). | ||
|
|
||
| `keyring` is an optional dependency. Install it alongside the CLI: | ||
|
|
||
| ```bash | ||
| pip install keeper-secrets-manager-cli[keyring] | ||
| ``` | ||
|
|
||
| If `keyring` is not installed, new profiles fall back to `keeper.ini` file storage (with `0600` permissions). | ||
|
|
||
| ### Headless / Server Environments | ||
|
|
||
| If no Secret Service daemon is running, keyring storage is not available. Use file-based storage instead: | ||
|
|
||
| ```bash | ||
| ksm profile init --ini-file ~/.keeper/keeper.ini | ||
| ``` | ||
|
|
||
| ## CI/CD and Docker | ||
|
|
||
| Keyring storage is not suitable for containerized or ephemeral environments. Use the `KSM_CONFIG` environment variable or `--ini-file` instead. | ||
|
|
||
| ### Using KSM_CONFIG (recommended for CI/CD) | ||
|
|
||
| ```bash | ||
| # Export your profile as a base64 config string | ||
| export KSM_CONFIG=$(ksm profile export --profile-name default) | ||
|
|
||
| # Use in your pipeline — no ini file needed | ||
| ksm secret list | ||
| ``` | ||
|
|
||
| ### Using --ini-file in Docker | ||
|
|
||
| ```dockerfile | ||
| # Copy your keeper.ini into the container | ||
| COPY keeper.ini /app/keeper.ini | ||
|
|
||
| # Use it at runtime | ||
| CMD ["ksm", "secret", "list", "--ini-file", "/app/keeper.ini"] | ||
| ``` | ||
|
|
||
| ## Profile Name Requirements | ||
|
|
||
| Profile names stored in the keyring must be 1–64 characters and contain only letters, numbers, hyphens, and underscores: | ||
|
|
||
| ``` | ||
| ✓ default | ||
| ✓ my-profile | ||
| ✓ prod_api_v2 | ||
| ✗ my profile (spaces not allowed) | ||
| ✗ ../escape (path characters not allowed) | ||
| ``` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Keyring not available | ||
|
|
||
| ``` | ||
| Error: No keyring backend available. Install: pip install keyring | ||
| ``` | ||
|
|
||
| Install the `keyring` library or use `--ini-file` for file-based storage. | ||
|
|
||
| ### Wrong keyring backend on Linux | ||
|
|
||
| If no Secret Service daemon is running, `keyring` returns a `fail.Keyring` backend. The CLI detects this and falls back to file-based storage. To confirm which backend is active: | ||
|
|
||
| ```bash | ||
| python3 -c "import keyring; b = keyring.get_keyring(); print(b.__class__.__module__)" | ||
| ``` | ||
|
|
||
| If the output contains `fail`, start GNOME Keyring or KWallet, or use `--ini-file` for file-based storage. | ||
|
|
||
| ### Integrity check failure | ||
|
|
||
| ``` | ||
| ksm had a problem: Keyring entry for profile '<name>' failed integrity check. | ||
| The entry may have been modified outside of the KSM CLI. | ||
| To recover, delete the profile and re-initialize: | ||
| ksm profile delete <name> | ||
| ksm profile init --token <one-time-token> | ||
| ``` | ||
|
|
||
| This error means the Keychain entry for the named profile was modified outside the CLI (e.g. by another application or a manual edit). The CLI refuses to use the entry to protect against credential substitution attacks. | ||
|
|
||
| **Recovery steps:** | ||
|
|
||
| ```bash | ||
| # 1. Delete the affected profile | ||
| ksm profile delete <name> | ||
|
|
||
| # 2. Re-initialize with a new one-time token from the Keeper Admin Console | ||
| ksm profile init --token <one-time-token> --profile-name <name> | ||
| ``` | ||
|
|
||
| > **Profile name format**: must be 1–64 characters containing only letters, numbers, hyphens, and underscores. The name is validated before the one-time token is redeemed, so a bad name won't consume the token. | ||
|
|
||
| ### Finding entries in the OS keyring | ||
|
|
||
| The CLI stores entries under the application name `KSM-cli`: | ||
| - Common config: key `ksm-cli-common` | ||
| - Per-profile: key `ksm-cli-profile-{profile_name}` | ||
|
|
||
| On macOS you can view these in **Keychain Access**. On Windows, use **Credential Manager** → **Windows Credentials**. | ||
|
|
||
| ### Migrating from keeper.ini to keyring | ||
|
|
||
| No automated migration is provided. To move an existing profile to keyring storage: | ||
|
|
||
| ```bash | ||
| # 1. Export the existing profile | ||
| ksm profile export --profile-name default > token.txt | ||
|
|
||
| # 2. Re-initialize using keyring storage (omit --ini-file) | ||
| ksm profile init --token "$(cat token.txt)" | ||
|
|
||
| # 3. Verify the new profile works | ||
| ksm secret list | ||
|
|
||
| # 4. Remove the old keeper.ini if no longer needed | ||
| ``` | ||
|
|
||
| ## See Also | ||
|
|
||
| - [KSM CLI Documentation](https://docs.keeper.io/secrets-manager/secrets-manager/secrets-manager-command-line-interface) | ||
| - [Profile Management](https://docs.keeper.io/secrets-manager/secrets-manager/secrets-manager-command-line-interface/profile-management) |
Oops, something went wrong.
Oops, something went wrong.
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.
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium test
Copilot Autofix
AI about 1 month ago
In general, you fix this by explicitly adding a
permissionsblock that restricts theGITHUB_TOKENto the minimal scopes needed. For a pure CI/test workflow like this—where the jobs only check out source, install dependencies, and run tests—contents: readis usually sufficient. You can set this either at the workflow root (so it applies to all jobs that don’t override it) or per job. Here, the cleanest solution is to add a single root-levelpermissionsblock after thename:oron:section.Concretely, in
.github/workflows/test.cli.yml, add:at the top level of the workflow (aligned with
name:andon:), e.g. betweenname: Test-CLIandon:. This will apply read-only repository-content permissions to bothtest-cliandtest-cli-keyringjobs, without changing any of the existing steps or functionality. No imports or additional methods are needed because this is a configuration-only change in the workflow YAML.