Skip to content

Conversation

@sk-keeper
Copy link
Collaborator

No description provided.

jwalstra-keeper and others added 24 commits January 7, 2026 11:10
Allow configuration UID to be selected for gateways used by multiple
PAM configuration records on commands.
… `--file-plan` command for 1TB/10TB storage (#1755) (#1756)

* Added msp-update --name parameter

* KC-1066 fix file storage
* Establish ssh sessions with ssh key creds only

* Added check for CLI mode support on gateway/guacd (using timeout on STDOUT pipe)

* resolved conflicts with upstream
* service-docker-setup and slack-app-setup initial commit

* Update unit-test cases

* Update and refactor code based on PR comments

* Add validation checks for each prompt in service configuration via docker

* Update slack-app-setup model, yaml label and service config prompts

* Update record type to login instead of server

---------

Co-authored-by: pvagare-ks <pvagare@keepersecurity.com>
Co-authored-by: Micah Roberts <mroberts@keepersecurity.com>
* Update __init__.py

fixed bug in batching of requests for both records and users

* Fix chunk processing logic in batching requests for user IDs and problem IDs, removed inefficiency
Currently running enterprise role in text format yields cascade permissions and node privileges:
`er -v 'Keeper Administrator' --format text`
This isn't included in the JSON output:
`er -v 'Keeper Administrator' --format json`

This commit adds the same logic as the text format (ignoring hidden privileges or MSP privileges if user is not MSP), and shows the result in the following format:
```
"managed_nodes": [
        {
            "node_id": 1067368092532738,
            "node_name": "Demo Node",
            "cascade": true,
            "privileges": [
                "manage_user",
                "manage_nodes",
                "manage_roles",
                "manage_teams",
                "transfer_account",
                "run_reports",
                "manage_bridge",
                "manage_record_types",
                "approve_device",
                "run_compliance_reports",
                "sharing_administrator"
            ]
        }
    ],
```
Allow the user to select configuration UID if gateway has multiple
configurations for `pam action service` commands.
* Rename user_create.py to user_onboarding__create_and_push.py

* Create user_onboarding__create_and_login.py

Added script that is similar to the create_and_push one, however in this one you can *login as* the created users in commander and run any commands from the SDK in their vault directly - yielding more capabilities than the enterprise-push command.
…figuration (#1772) (#1775)

* Add tunnelling to setup commands and adv. security configuration in streamline service-create

* Update Readme and unit-tests

* Remove -enc flag and update default KSM app name

* Fix review comments, pentest port expose issue, remove tls from setup commands, remove api-key from docker and UI print messages
…#1773) (#1774)

* Streamline enterprise node, role, and team management bug fix (#1773)

* updated status code

* added status code 207
@socket-security
Copy link

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

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpytest@​9.0.287100100100100

View full report

@sk-keeper sk-keeper merged commit 99a65cc into master Jan 22, 2026
5 checks passed
# Docker mode: redact API key and show vault record UID
if record_uid:
redacted_key = f"****{api_key[-4:]}" if len(api_key) >= 4 else "****"
print(f'Generated API key: {redacted_key} (stored in vault record: {record_uid})')

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 4 days ago

In general, to fix clear-text logging of sensitive information, avoid printing or logging secrets (API keys, passwords, tokens) altogether. If user feedback is necessary, only log non-sensitive metadata (e.g., that a key was created, associated record UID) or, at most, a non-identifying marker that cannot be used to reconstruct or brute-force the secret.

For this specific code, the minimal functional change is:

  • Stop including the API key (even redacted) in the print output.
  • Continue to inform the user that an API key was generated and, when applicable, which vault record UID it was stored in.

Concretely:

  • In RecordHandler.create_record:
    • Replace the two print calls:
      • Line 46: print(f'Generated API key: {redacted_key} (stored in vault record: {record_uid})')
      • Line 48: print(f'Generated API key: {api_key}')
    • With messages that do not contain the key, e.g.:
      • When record_uid is present: "API key generated and stored in vault record: {record_uid}"
      • When record_uid is absent: a generic note that an API key was generated and stored in the config record, without printing the key.

No new imports or helper methods are required; this is a straight substitution of the printed strings inside create_record. The rest of the function behavior (record creation, expiration handling, and return value) remains unchanged.

Suggested changeset 1
keepercommander/service/config/record_handler.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/keepercommander/service/config/record_handler.py b/keepercommander/service/config/record_handler.py
--- a/keepercommander/service/config/record_handler.py
+++ b/keepercommander/service/config/record_handler.py
@@ -40,12 +40,11 @@
             logger.debug("Adding expiration to record (advanced security enabled)")
             self._add_expiration_to_record(record)
             
-        # Docker mode: redact API key and show vault record UID
+        # Inform user that an API key was generated, without revealing the key value
         if record_uid:
-            redacted_key = f"****{api_key[-4:]}" if len(api_key) >= 4 else "****"
-            print(f'Generated API key: {redacted_key} (stored in vault record: {record_uid})')
+            print(f'API key generated and stored in vault record: {record_uid}')
         else:
-            print(f'Generated API key: {api_key}')
+            print('API key generated and stored in the configuration record.')
         return record
 
     def update_or_add_record(self, params: KeeperParams, title: str, config_path: Path) -> None:
EOF
@@ -40,12 +40,11 @@
logger.debug("Adding expiration to record (advanced security enabled)")
self._add_expiration_to_record(record)

# Docker mode: redact API key and show vault record UID
# Inform user that an API key was generated, without revealing the key value
if record_uid:
redacted_key = f"****{api_key[-4:]}" if len(api_key) >= 4 else "****"
print(f'Generated API key: {redacted_key} (stored in vault record: {record_uid})')
print(f'API key generated and stored in vault record: {record_uid}')
else:
print(f'Generated API key: {api_key}')
print('API key generated and stored in the configuration record.')
return record

def update_or_add_record(self, params: KeeperParams, title: str, config_path: Path) -> None:
Copilot is powered by AI and may make mistakes. Always verify output.
redacted_key = f"****{api_key[-4:]}" if len(api_key) >= 4 else "****"
print(f'Generated API key: {redacted_key} (stored in vault record: {record_uid})')
else:
print(f'Generated API key: {api_key}')

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 4 days ago

In general, the fix is to ensure that sensitive secrets such as API keys are never written to logs or general output in clear text. Instead, show only a redacted form (e.g., last 4 characters) or omit the value entirely, while still preserving necessary functionality such as telling the user that a key was generated and where it is stored.

In this specific case, we already have safe behavior in the if record_uid: branch (lines 44–46), where the key is redacted: ****{api_key[-4:]}. The unsafe behavior is in the else: branch on line 48 that prints the entire api_key. To fix this without changing overall functionality, we should also redact the key in the else branch, using the same masking logic. That way, users still receive confirmation that an API key was generated, but the full key is not exposed in clear text on stdout/logs. Concretely, in keepercommander/service/config/record_handler.py, within RecordHandler.create_record, we will replace line 48’s print(f'Generated API key: {api_key}') with a print that only shows a redacted version of the key, e.g. print(f'Generated API key: ****{api_key[-4:]}' if len(api_key) >= 4 else "****"). No new imports or helper methods are required.

Suggested changeset 1
keepercommander/service/config/record_handler.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/keepercommander/service/config/record_handler.py b/keepercommander/service/config/record_handler.py
--- a/keepercommander/service/config/record_handler.py
+++ b/keepercommander/service/config/record_handler.py
@@ -45,7 +45,8 @@
             redacted_key = f"****{api_key[-4:]}" if len(api_key) >= 4 else "****"
             print(f'Generated API key: {redacted_key} (stored in vault record: {record_uid})')
         else:
-            print(f'Generated API key: {api_key}')
+            redacted_key = f"****{api_key[-4:]}" if len(api_key) >= 4 else "****"
+            print(f'Generated API key: {redacted_key}')
         return record
 
     def update_or_add_record(self, params: KeeperParams, title: str, config_path: Path) -> None:
EOF
@@ -45,7 +45,8 @@
redacted_key = f"****{api_key[-4:]}" if len(api_key) >= 4 else "****"
print(f'Generated API key: {redacted_key} (stored in vault record: {record_uid})')
else:
print(f'Generated API key: {api_key}')
redacted_key = f"****{api_key[-4:]}" if len(api_key) >= 4 else "****"
print(f'Generated API key: {redacted_key}')
return record

def update_or_add_record(self, params: KeeperParams, title: str, config_path: Path) -> None:
Copilot is powered by AI and may make mistakes. Always verify output.
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.

9 participants