From 0ff9353e1777ceaf867b00ca996f8b2736576f7e Mon Sep 17 00:00:00 2001 From: lthievenaz-keeper Date: Fri, 12 Jun 2026 09:10:11 +0100 Subject: [PATCH 1/4] Add secret-ids argument for thycotic import Add secret-ids arg to import command, to use for debugging Thycotic secret IDs --- keepercommander/importer/commands.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/keepercommander/importer/commands.py b/keepercommander/importer/commands.py index 8563dd0c4..25a85f743 100644 --- a/keepercommander/importer/commands.py +++ b/keepercommander/importer/commands.py @@ -79,6 +79,8 @@ def register_command_info(aliases, command_info): help='temp directory used to cache encrypted attachment imports') import_parser.add_argument('--show-skipped', dest='show_skipped', action='store_true', help='Display skipped records') +import_parser.add_argument('--secret-ids', dest='secret_ids', action='store', + help='Comma separated list of secret IDs to fetch (Thycotic)') import_parser.add_argument( 'name', type=str, help='file name (json, csv, keepass, 1password), account name (lastpass), or URL (ManageEngine, Thycotic)' ) From 55e4503380d2b327d9aa26abfb9a18d2b767e619 Mon Sep 17 00:00:00 2001 From: lthievenaz-keeper Date: Fri, 12 Jun 2026 09:11:07 +0100 Subject: [PATCH 2/4] Pass secret-ids arg from import command to thycotic import Pass secret-ids arg from import command to thycotic import so it can be handled in the Thycotic import --- keepercommander/importer/imp_exp.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keepercommander/importer/imp_exp.py b/keepercommander/importer/imp_exp.py index 0ccec3cf0..99efb826b 100644 --- a/keepercommander/importer/imp_exp.py +++ b/keepercommander/importer/imp_exp.py @@ -715,6 +715,7 @@ def _import(params, file_format, filename, **kwargs): filter_folder = kwargs.get('filter_folder') dry_run = kwargs.get('dry_run') is True show_skipped = kwargs.get('show_skipped') is True + secret_ids = kwargs.get('secret_ids') import_into = kwargs.get('import_into') or '' if import_into: @@ -732,7 +733,7 @@ def _import(params, file_format, filename, **kwargs): filter_folder_lower = filter_folder.lower() if isinstance(filter_folder, str) else '' for x in importer.execute(filename, params=params, users_only=import_users, filter_folder=filter_folder, - old_domain=old_domain, new_domain=new_domain, tmpdir=tmpdir, dry_run=dry_run): + old_domain=old_domain, new_domain=new_domain, tmpdir=tmpdir, secret_ids=secret_ids, dry_run=dry_run): if isinstance(x, ImportRecord): if filter_folder and not importer.support_folder_filter(): if not x.folders: From f3559f30a4a08fb29e37f8f06752ef66e1902f4f Mon Sep 17 00:00:00 2001 From: lthievenaz-keeper Date: Fri, 12 Jun 2026 09:15:04 +0100 Subject: [PATCH 3/4] Add handling for secret-ids arg in Thycotic import If user sets secret-ids, the import will: - Check if any of those IDs have come up in the lookup and would have been imported. - Import only the secret-ids set This is useful for debugging, because the lookup API may not return all Thycotic secrets - eg if there a security policy on them, but they may still be fetched. Usage: String (comma separated IDs) `import --format thycotic server_name --secret-ids "123, 124,125"` Python List (strings or integers) `secret_ids=[123, 124, 125]` --- keepercommander/importer/thycotic/thycotic.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/keepercommander/importer/thycotic/thycotic.py b/keepercommander/importer/thycotic/thycotic.py index 120480160..8f11b025b 100644 --- a/keepercommander/importer/thycotic/thycotic.py +++ b/keepercommander/importer/thycotic/thycotic.py @@ -341,6 +341,29 @@ def do_import(self, filename, **kwargs): secrets_ids.extend([x['id'] for x in auth.thycotic_search(query)]) else: secrets_ids = [x['id'] for x in auth.thycotic_search(f'/v1/secrets/lookup')] + + # secret_ids arg + debug_ids = kwargs.get('secret_ids') + # Convert CLI string input into list + if isinstance(debug_ids,str): + debug_ids = debug_ids.replace(' ','').split(',') + # Handle secret IDs list + if isinstance(debug_ids,list): + # Deduplicate + debug_ids = list(set(debug_ids)) + # Check whether secrets were found in the lookup + stringified_secrets_ids = [str(x) for x in secrets_ids] + stringified_debug_ids = [str(x) for x in debug_ids] + found_secrets = [x for x in stringified_debug_ids if x in stringified_secrets_ids] + logging.info(f'From the specified {len(debug_ids)} secret IDs, {len(found_secrets)} were found in the secret server lookup.') + logging.info(', '.join(found_secrets)) + + # Replace import list with specified IDs + secrets_ids = debug_ids + else: + # Quit if secret IDs != list + logging.warning('Invalid input for secret IDs, exiting.') + return self._send_keep_alive_if_needed(params) print(f'Loading {len(secrets_ids)} Records ', flush=True, end='') From b8540a80499332fd250741f30e26006602d8c4fe Mon Sep 17 00:00:00 2001 From: lthievenaz-keeper Date: Fri, 12 Jun 2026 13:31:02 +0100 Subject: [PATCH 4/4] Correct secret_ids check Fix conditional logic so import continues if no secret ids are specified --- keepercommander/importer/thycotic/thycotic.py | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/keepercommander/importer/thycotic/thycotic.py b/keepercommander/importer/thycotic/thycotic.py index 8f11b025b..f7409609c 100644 --- a/keepercommander/importer/thycotic/thycotic.py +++ b/keepercommander/importer/thycotic/thycotic.py @@ -344,26 +344,27 @@ def do_import(self, filename, **kwargs): # secret_ids arg debug_ids = kwargs.get('secret_ids') - # Convert CLI string input into list - if isinstance(debug_ids,str): - debug_ids = debug_ids.replace(' ','').split(',') - # Handle secret IDs list - if isinstance(debug_ids,list): - # Deduplicate - debug_ids = list(set(debug_ids)) - # Check whether secrets were found in the lookup - stringified_secrets_ids = [str(x) for x in secrets_ids] - stringified_debug_ids = [str(x) for x in debug_ids] - found_secrets = [x for x in stringified_debug_ids if x in stringified_secrets_ids] - logging.info(f'From the specified {len(debug_ids)} secret IDs, {len(found_secrets)} were found in the secret server lookup.') - logging.info(', '.join(found_secrets)) - - # Replace import list with specified IDs - secrets_ids = debug_ids - else: - # Quit if secret IDs != list - logging.warning('Invalid input for secret IDs, exiting.') - return + if debug_ids is not None: + # Convert CLI string input into list + if isinstance(debug_ids,str): + debug_ids = debug_ids.replace(' ','').split(',') + # Handle secret IDs list + if isinstance(debug_ids,list): + # Deduplicate + debug_ids = list(set(debug_ids)) + # Check whether secrets were found in the lookup + stringified_secrets_ids = [str(x) for x in secrets_ids] + stringified_debug_ids = [str(x) for x in debug_ids] + found_secrets = [x for x in stringified_debug_ids if x in stringified_secrets_ids] + logging.info(f'From the specified {len(debug_ids)} secret IDs, {len(found_secrets)} were found in the secret server lookup.') + logging.info(', '.join(found_secrets)) + + # Replace import list with specified IDs + secrets_ids = debug_ids + else: + # Quit if secret IDs != list + logging.warning('Invalid input for secret IDs, exiting.') + return self._send_keep_alive_if_needed(params) print(f'Loading {len(secrets_ids)} Records ', flush=True, end='')