PAM Project KCM Import
pam project kcm-import reads connections, users and groups directly from a Keeper Connection Manager (a.k.a. Apache Guacamole) database, maps the 150+ KCM connection parameters to KeeperPAM equivalents via kcm_mappings.json, then delegates to pam project import (new project) or pam project extend (existing project) under the hood. You never write the import JSON by hand.
Synopsis
pam project kcm-import
( --db-host=HOST [--db-port=PORT] [--db-name=DB] [--db-user=USER]
[--db-password-record=UID] [--db-ssl]
| --docker-detect [--docker-container=NAME] )
[--db-type=mysql|postgresql]
[--name=PROJECT | --config=UID_OR_TITLE]
[--gateway=UID_OR_NAME]
[--folder-mode=ksm|exact|flat]
[--output=FILE | --dry-run]
[--skip-users]
[--include-disabled]Either --db-host or --docker-detect is required. Everything else has a default.
Prerequisites
Authenticated Commander session — run
keeper loginfirst.Network access to the KCM database from wherever you're running Commander.
Database driver installed in the same Python that runs Commander:
MySQL →
pymysql(preferred) ormysql-connector-python. Install:pip3 install pymysqlPostgreSQL →
psycopg2-binary. Install:pip3 install psycopg2-binary
dockerCLI onPATHif using--docker-detect.A Keeper role with permission to create PAM projects, gateways and shared folders.
kcm_mappings.jsonpresent atkeepercommander/commands/pam_import/kcm_mappings.json.
Command Line Options
Either --db-host or --docker-detect is required; everything else has a default.
Source: where to read KCM from
--db-host→ KCM database hostname or IP. Required unless--docker-detectis used.--docker-detect→ Auto-detect host/port/db/user/password by readingMYSQL_*/POSTGRES_*env vars from a Docker container viadocker inspect. Required unless--db-hostis used.--docker-container→ Container name to inspect when--docker-detectis set. Default:guacamole.--db-type→ Database engine. Choices:mysql,postgresql. Default:mysql.--db-port→ TCP port for the DB. Default:3306for mysql,5432for postgresql.--db-name→ Database name. Default:guacamole_db.--db-user→ DB username. Default:guacamole_user. Read-onlySELECTis enough.--db-password-record→ Keeper record UID containing the DB password. Without this and without--docker-detect, the command prompts for the password via hiddengetpass. Never accepts a password as a CLI argument.--db-ssl→ Require TLS for the DB connection. The command emits a warning if you connect to a non-local/non-RFC1918 host without it.
Destination: where the data lands in Keeper
--name,-n→ Project name for a brand-new import. Default:KCM-Import-<YYYYMMDD-HHMMSS>. Mutually exclusive with--config.--config,-c→ Existing PAM Configuration UID or title. Switches to extend mode. Mutually exclusive with--name.--gateway,-g→ Existing gateway UID or name. Without it an interactive picker lists online gateways. Ignored in--configmode.--folder-mode→ How KCM connection groups map to Keeper shared folders. Choices:ksm,exact,flat. Default:ksm.
Output mode
These three are mutually exclusive. Default (no flag) imports into the vault.
--dry-run,-d→ Print the assembledpam_dataJSON to stdout with sensitive fields replaced by[REDACTED]. No vault writes.--output,-o→ Write the full JSON (cleartext passwords) to a0600file. No vault writes.(no flag) → Default. Delegates to
pam project import(new project) orpam project extend(existing config).
Filtering
--skip-users→ Skip generatingpamUserrecords.--include-disabled→ Include KCM connections marked disabled (max_connections == 0).
Quick Start
Always run with
--dry-runfirst, then drop it to actually create the project.
Three Ways to Give It Database Credentials
Docker auto-detect (
--docker-detect [--docker-container=NAME]) → KCM running in Docker on the same host as Commander.Vault record (
--db-host=H --db-password-record=<UID>) → Repeatable runs / scripted migrations.Interactive prompt (
--db-host=Hwith no record) → One-off run. Hiddengetpassprompt. Never pass the password as a CLI argument.
Database Privileges Needed
The DB user needs SELECT on these Guacamole tables (read-only; the command never writes to the source DB):
guacamole_connectionguacamole_connection_parameterguacamole_connection_attributeguacamole_connection_groupguacamole_connection_permissionguacamole_entityinformation_schema.tables
PostgreSQL — minimal read-only role:
MySQL — minimal read-only role:
Folder Layout — --folder-mode
--folder-modeKCM organises connections in a tree of "connection groups". This flag controls how that tree maps to Keeper shared folders. Resources land under KCM Resources - <root> and users under KCM Users - <root> regardless of mode.
ksm(default) → Groups marked with a KSM config become roots; descendants stay nested under them.exact→ Mirrors the full KCM group hierarchy 1:1.flat→ Every group becomes a top-level shared folder (no nesting).
Group names are sanitised —
/,\and..are replaced with_to prevent path traversal.
Protocol → Record-Type Mapping
ssh
pamMachine
SFTP sub-resources auto-extracted
rdp
pamMachine
RDP options mapped via kcm_mappings.json
vnc
pamMachine
telnet
pamMachine
Login regex parameters carry over
kubernetes
pamMachine
Namespace/pod/container/cert fields carry over
mysql
pamDatabase
database_type = "mysql"
postgres
pamDatabase
KCM uses postgres, KeeperPAM uses postgresql
sql-server
pamDatabase
http
pamRemoteBrowser
RBI only
anything else
pamMachine
Unknown protocols fall back
Each non-disabled KCM connection produces one resource record, one pamUser record wired as launch_credentials, and (SSH with SFTP) an extra SFTP resource + user pair.
What Gets Created in the Vault
Running without --dry-run / --output produces (in order):
Top-level project folder named after
--name.Two shared folders per group root —
KCM Resources - <root>andKCM Users - <root>.A PAM Configuration record (skipped in extend mode).
A gateway — reused if
--gatewayis given, otherwise interactive picker with[N] Create new.Resource records (
pamMachine/pamDatabase/pamRemoteBrowser).User records (
pamUser) wired to their resource'slaunch_credentials.SFTP sub-resources and sub-users for SSH connections with SFTP configured.
Gateway Selection
--gateway=<UID|name>→ reuse that existing gateway (must be online).No
--gatewayflag → interactive prompt; pick a number to reuse orNto provision a new one.No online gateways available → falls through to "create new" without prompting.
--configmode → gateway flag is ignored.
Output Mode Details
Re-Running and Cleanup
Re-running with the same --name — pam project import matches records by title and skips existing ones. New connections are added; changes to existing connections are not picked up automatically.
To add new KCM connections to an existing project — use --config=<UID_OR_TITLE> instead of --name.
Rolling back an import:
Right-click the project folder in the vault → Delete folder.
Delete the gateway separately via Admin Console → Privileged Access → Gateways (if needed).
Best practice: always do
--dry-runfirst, then--output=/tmp/kcm-preview.jsonto inspect with cleartext values, then the real import.
Examples
Common Pitfalls
Either --db-host or --docker-detect is required→ you forgot both; one is mandatory.No PAM configuration found for gateway "X"→ the gateway doesn't have a PAM config yet. Runpam config createfirst.Database connection failed: <ErrorType>→ Commander hides the underlying message to avoid leaking credentials. Re-run with debug logging (-dat shell-launch) to see the full exception.Connecting to a remote DB without
--db-ssl→ you'll get aWARNING; credentials transit in cleartext. Always set--db-sslfor non-local hosts.Docker auto-detect with the wrong container name → default is
guacamole; Compose deployments often use<project>-guacamole-1. Rundocker ps --format '{{.Names}}'to check.pam project importcomplains aboutkcm_mappings.jsonmissing → the file ships with Commander. Verify withgit ls-files keepercommander/commands/pam_import/kcm_mappings.json; if missing, fetch from upstreamrelease.
Last updated
Was this helpful?

