Add Pam project generator v2#1824
Add Pam project generator v2#1824lthievenaz-keeper wants to merge 16 commits intoKeeper-Security:masterfrom
Conversation
…1806) * Fixed search functions and completed pending supershell refactoring - Fix lsf command returning "No shared folders found" by making search_shared_folders() return all items when search string is empty - Apply same fix to search_teams() for consistency - Fix cc and ls commands to use regex search (use_regex=True) to restore previous behavior broken by token-based search default change * Fixed unit test
… Prevent PAM records for One-Time Shares (Keeper-Security#1798) (Keeper-Security#1805)
Change List: - Add --keeper-db-proxy (-kdbp) to pam tunnel edit for pamDatabase records - Add launch credential check when enabling DB proxy (--keeper-db-proxy=on) - Add --launch-user (-lu) flag to pam connection edit for setting launch credentials - Add check_if_resource_has_launch_credential() to TunnelDAG - Add is_launch_credential support to link_user/link_user_to_resource in TunnelDAG - Validate --launch-user record is pamUser type
* Merged with upstream changes (incl. refactoring into base.py) extend.py still WIP * Initial implementation of pam project extend command * Fixed RBI handlers (RBI has no JIT nor AI settings)
…eeper-Security#1814) * KC-1142 Per-user cache invalidation for filtered compliance reports Add granular per-user cache invalidation so filtered compliance reports (--username, --team) only fetch stale users from the API instead of the entire enterprise. Adds last_refreshed timestamp per StorageUser and a selective upsert method that preserves cached data for other users. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * KC-1142 Address PR review feedback - Early error for invalid --username in aging-report - Fix team resolution fall-through in compliance filter - Warn when username/team filters match no enterprise users - Always update shared_records_only flag in per-user cache path - Update global prelim timestamp on selective user refresh - Guard against NULL last_refreshed from schema migration * KC-1142 Fix type annotations for user_filter parameter * KC-1142 Fix misleading warning message for unmatched user filters * KC-1142 Fix --username and --team filters to use OR instead of AND Previously, --username filtered first, then --team filtered the result, meaning an invalid username with a valid team returned no records. Now both are unioned before applying other filters. * KC-1142 Replace loops with dict lookups for user/team resolution * KC-1142 Always refresh compliance data when user_filter is set The global last_compliance_data_update timestamp caused filtered reports for different users to skip the compliance sync after the first user's run had already set it. * KC-1142 Revert global timestamp update in per-user prelim sync Setting set_prelim_data_updated() after a partial user sync caused subsequent unfiltered runs to skip the full sync, showing only previously-cached users. Per-user timestamps on StorageUser are sufficient for the per-user path. * KC-1142 Only refresh compliance data when prelim had stale users Unconditionally forcing compliance sync for filtered runs caused re-fetches on warm cache. Now tracks whether get_prelim_data found stale users and only triggers compliance sync when it did. * KC-1142 Add per-user compliance cache with last_compliance_refreshed Replace _had_stale_users hack with proper per-user compliance timestamp on StorageUser. Prelim and compliance caches are now independently tracked per user, so aging-report warming prelim cache won't incorrectly gate compliance freshness. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
) * KC-1143 Add --aging flag to main compliance report Extract aging fetch/cache functions to module level and wire aging data support into ComplianceReportCommand with per-user cache invalidation. Remove last_pw_change fallback to created date. * KC-1143 Compliance report enhancements: aging, filters, incremental sync - Add --aging flag to compliance report with record aging data (created, last_modified, last_rotation, last_pw_change) - KC-1146: filter false-positive event 80 (record_password_change) by occurrence count — first-set events are discarded, only 2+ occurrences count as real password changes - Union last_pw_change with PAM rotation events (250/252) - Add --username and --team filters to all compliance subcommands - Add --resolve-teams flag to sfr and team-report for expanding team filter to include individual team members in shared folder matching - Implement incremental compliance data sync using per-user/per-record staleness checks (last_refreshed, last_compliance_refreshed) - Dynamic chunking with probe timeouts for preliminary data fetching - Client-side request timeouts to prevent indefinite hangs - Suppress throttling log messages from clobbering spinner output - Add portable compliance test suite with auto-discovery from vault
- Fix report_data.index(fmt_row) bug that could map aging columns to wrong records when rows have identical content — use enumerate instead - Scope staleness check to filtered users' records when user_filter is set, preventing full enterprise sync_down on filtered queries - Fix team discovery in test script: use 'name' key (not 'team_name') matching actual enterprise-info JSON output
| print(f"{prefix} ✓ {path}") | ||
| print(f"{prefix} - Bad paths: {len(bad_paths)}") | ||
| for path, reason in bad_paths: | ||
| print(f"{prefix} ✗ {path}: {reason}") |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
|
|
||
| existing_msg = f"{x_count} existing folders (skipped)" if x_count else "0 existing folders" | ||
| if dry_run: | ||
| print(f"[DRY RUN] {existing_msg}, {y_count} new folders to be created") |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
| if dry_run: | ||
| print(f"[DRY RUN] {existing_msg}, {y_count} new folders to be created") | ||
| else: | ||
| print(f"{existing_msg}, {y_count} new folders created") |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
| if logging.getLogger().getEffectiveLevel() <= logging.DEBUG: | ||
| for path, _ in good_paths: | ||
| tag = "existing" if path in existing_paths_set else "new" | ||
| print(f" [DEBUG] [{tag}] {path}") |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
| rt = str(machine.get("type", "")).strip() if isinstance(machine, dict) else "" | ||
| if rt.lower() not in (x.lower() for x in PAM_RESOURCES_RECORD_TYPES): | ||
| title = str(machine.get("title", "")).strip() if isinstance(machine, dict) else "" | ||
| logging.error(f"Incorrect record type \"{rt}\" - should be one of {PAM_RESOURCES_RECORD_TYPES}, \"{title}\" record skipped.") |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
| ) | ||
| if logging.getLogger().getEffectiveLevel() <= logging.DEBUG: | ||
| for t in autogenerated_titles: | ||
| print(f" [DEBUG] autogenerated title: {t}") |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
pam_import_generator.pytopam_import_generator_v1.pypam_import_generator_v2.pythat improves on the CSV generation program.Changes:
Docs on docs.keeper.io to be updated inline with these changes