From 6ddd132b0f791eb1956b3183e9a490c0bdd22d80 Mon Sep 17 00:00:00 2001 From: erinlewis-keeper Date: Tue, 3 Mar 2026 16:20:59 -0800 Subject: [PATCH 1/3] feat(DR-1208): add idp uid field to pam config --- keepercommander/commands/discoveryrotation.py | 23 +++++++++++++++---- keepercommander/commands/pam_import/base.py | 4 ++++ keepercommander/commands/pam_import/edit.py | 2 ++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/keepercommander/commands/discoveryrotation.py b/keepercommander/commands/discoveryrotation.py index 627099419..e083721e1 100644 --- a/keepercommander/commands/discoveryrotation.py +++ b/keepercommander/commands/discoveryrotation.py @@ -10,6 +10,7 @@ # import argparse import fnmatch +import itertools import json import logging import os.path @@ -1750,8 +1751,8 @@ def print_pam_configuration_details(params, config_uid, is_verbose=False, format "resource_record_uids": facade.resource_ref, "fields": {} } - - for field in configuration.fields: + + for field in itertools.chain(configuration.fields, configuration.custom): if field.type in ('pamResources', 'fileRef'): continue values = list(field.get_external_value()) @@ -1774,7 +1775,7 @@ def print_pam_configuration_details(params, config_uid, is_verbose=False, format table.append(['Gateway UID', facade.controller_uid]) table.append(['Resource Record UIDs', facade.resource_ref]) - for field in configuration.fields: + for field in itertools.chain(configuration.fields, configuration.custom): if field.type in ('pamResources', 'fileRef'): continue values = list(field.get_external_value()) @@ -1826,7 +1827,7 @@ def print_root_rotation_setting(params, is_verbose=False, format_type='table'): if is_verbose: fields = {} - for field in c.fields: + for field in itertools.chain(c.fields, c.custom): if field.type in ('pamResources', 'fileRef'): continue value = ', '.join(field.get_external_value()) @@ -1841,7 +1842,7 @@ def print_root_rotation_setting(params, is_verbose=False, format_type='table'): if is_verbose: fields = [] - for field in c.fields: + for field in itertools.chain(c.fields, c.custom): if field.type in ('pamResources', 'fileRef'): continue value = ', '.join(field.get_external_value()) @@ -1875,6 +1876,8 @@ def print_root_rotation_setting(params, is_verbose=False, format_type='table'): 'which the gateway has access to.') common_parser.add_argument('--schedule', '-sc', dest='default_schedule', action='store', help='Default Schedule: Use CRON syntax') common_parser.add_argument('--port-mapping', '-pm', dest='port_mapping', action='append', help='Port Mapping') +common_parser.add_argument('--identity-provider', '-idp', dest='identity_provider_uid', + action='store', help='Identity Provider UID') network_group = common_parser.add_argument_group('network', 'Local network configuration') network_group.add_argument('--network-id', dest='network_id', action='store', help='Network ID') network_group.add_argument('--network-cidr', dest='network_cidr', action='store', help='Network CIDR') @@ -2041,6 +2044,10 @@ def parse_properties(self, params, record, **kwargs): # type: (KeeperParams, va else: extra_properties.append('schedule.defaultRotationSchedule=On-Demand') + identity_provider_uid = kwargs.get('identity_provider_uid') + if identity_provider_uid: + extra_properties.append(f'text.identityProviderUid={identity_provider_uid}') + if record.record_type == 'pamNetworkConfiguration': network_id = kwargs.get('network_id') if network_id: @@ -2230,6 +2237,7 @@ def execute(self, params, **kwargs): rt_fields = RecordEditMixin.get_record_type_fields(params, record.record_type) if rt_fields: + rt_fields.append({"$ref": "text", "label": "identityProviderUid"}) RecordEditMixin.adjust_typed_record_fields(record, rt_fields) # resolve folder path to UID @@ -2375,6 +2383,11 @@ def execute(self, params, **kwargs): if rt_fields: RecordEditMixin.adjust_typed_record_fields(configuration, rt_fields) + rt_fields = RecordEditMixin.get_record_type_fields(params, configuration.record_type) + if rt_fields: + rt_fields.append({"$ref": "text", "label": "identityProviderUid"}) + RecordEditMixin.adjust_typed_record_fields(configuration, rt_fields) + title = kwargs.get('title') if title: configuration.title = title diff --git a/keepercommander/commands/pam_import/base.py b/keepercommander/commands/pam_import/base.py index 9bd9ab8d8..d954b3ca9 100644 --- a/keepercommander/commands/pam_import/base.py +++ b/keepercommander/commands/pam_import/base.py @@ -125,6 +125,7 @@ def _initialize(self): self.attachments = None # PamAttachmentsObject # common settings (shared across all config types) + self.identity_provider_uid: str = "" # optional, text:identityProviderUid self.pam_resources = {} # {"folderUid": "", "controllerUid": ""} - "resourceRef": unused/legacy # Local environment: pamNetworkConfiguration @@ -245,6 +246,9 @@ def __init__(self, environment_type:str, settings:dict, controller_uid:str, fold self.scripts = PamScriptsObject.load(settings.get("scripts", None)) self.attachments = PamAttachmentsObject.load(settings.get("attachments", None)) + val = settings.get("identity_provider_uid", None) + if isinstance(val, str): self.identity_provider_uid = val + # Local Network if environment_type == "local": val = settings.get("network_id", None) diff --git a/keepercommander/commands/pam_import/edit.py b/keepercommander/commands/pam_import/edit.py index 881887c56..2a6524266 100644 --- a/keepercommander/commands/pam_import/edit.py +++ b/keepercommander/commands/pam_import/edit.py @@ -451,6 +451,8 @@ def process_pam_config(self, params, project: dict) -> dict: "ai_terminate_session_on_detection": pce.ai_terminate_session_on_detection }) + if pce.identity_provider_uid: args["identity_provider_uid"] = pce.identity_provider_uid + if pce.environment == "local": if pce.network_cidr: args["network_cidr"] = pce.network_cidr if pce.network_id: args["network_id"] = pce.network_id From de14d7e1ae0abb78735dc1d9b4319a89cad293a5 Mon Sep 17 00:00:00 2001 From: erinlewis-keeper Date: Wed, 4 Mar 2026 10:14:04 -0800 Subject: [PATCH 2/3] remove custom field append --- keepercommander/commands/discoveryrotation.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/keepercommander/commands/discoveryrotation.py b/keepercommander/commands/discoveryrotation.py index e083721e1..9f1ac842d 100644 --- a/keepercommander/commands/discoveryrotation.py +++ b/keepercommander/commands/discoveryrotation.py @@ -2237,7 +2237,6 @@ def execute(self, params, **kwargs): rt_fields = RecordEditMixin.get_record_type_fields(params, record.record_type) if rt_fields: - rt_fields.append({"$ref": "text", "label": "identityProviderUid"}) RecordEditMixin.adjust_typed_record_fields(record, rt_fields) # resolve folder path to UID @@ -2385,7 +2384,6 @@ def execute(self, params, **kwargs): rt_fields = RecordEditMixin.get_record_type_fields(params, configuration.record_type) if rt_fields: - rt_fields.append({"$ref": "text", "label": "identityProviderUid"}) RecordEditMixin.adjust_typed_record_fields(configuration, rt_fields) title = kwargs.get('title') From c1554c404d2c7c026c74b4de6e7bc70512e1c2cf Mon Sep 17 00:00:00 2001 From: erinlewis-keeper Date: Mon, 9 Mar 2026 09:15:49 -0700 Subject: [PATCH 3/3] fix supershell issue --- keepercommander/commands/supershell/app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keepercommander/commands/supershell/app.py b/keepercommander/commands/supershell/app.py index 42f7a3f93..11a7a051a 100644 --- a/keepercommander/commands/supershell/app.py +++ b/keepercommander/commands/supershell/app.py @@ -2642,7 +2642,8 @@ def _display_secrets_manager_app(self, app_uid: str): try: from ...proto import APIRequest_pb2, enterprise_pb2 - from .. import api, utils + from keepercommander import api + from keepercommander.commands import utils import json record = self.records[app_uid]