Instructions for developers working with Keeper Commander
The Python-based Keeper Commander CLI provides integration capabilities for Python projects, offering full access to vault and admin console functionalities.
In November 2025, we released an all new Keeper Python SDK which is a modern Python library. Keeper's engineering team is maintaining the existing Commander CLI codebase in addition to the new Python SDK for backwards compatibility.
There are two methods of building Python applications with Keeper Commander:
The New Keeper Python SDK
Using the Commander CLI Codebase
The all new Keeper Python SDK is a modern Python library offering programmatic access to the Keeper Vault and Admin capabilities. This is a refactor of the Commander CLI codebase to make it easy for developers to build custom functionality, such as:
Building custom integrations and applications
Managing enterprise structure, users, roles, teams, configuration
Performing Vault and PAM operations such as record creation, update, and deletion
For detailed setup instructions, visit the new Keeper SDK Setup Guide.
You can explore sample scripts showcasing the SDK's usage here.
The Keeper Commander CLI is the production command-line application for integrating with the Keeper Vault and Enterprise environment. It functions as a standalone command-line tool or can be imported as a library in scripts. This is the codebase which builds the Commander CLI binary installers for Windows, macOS and Linux.
Find comprehensive setup instructions here.
Explore standalone scripts for various operations like searching records, creating teams, and sharing folders here.
Setup instructions for the Commander SDK for Python
The new Python SDK enables full integration with the Keeper platform, including Enterprise, Vault, and Admin operations, through the keepersdk library available on PyPI.
This SDK provides fully executable functions that can be accessed directly from Python, eliminating the need for any command-line wrappers or the Commander CLI itself.
The system should have Python version 3.10 or newer
Create and Activate Virtual Environment
python3 -m venv venv
source venv/bin/activatepython -m venv venv
.\venv\Scripts\activatepip install keepersdkSource Code - Clone the source code from the Github repository
git clone https://github.com/Keeper-Security/keeper-sdk-python.git
cd keeper-sdk-pythonThe "master" branch will mirror the production release. The "release" branch references the upcoming release. To optionally switch to the release branch:
git checkout releasecd keepersdk-packagepip install -r requirements.txtpip install setuptools.pypython setup.py installIf you are accessing keepersdk from a new device, you need to ensure that there is a config.json file present. This ensures that the client source doesn't contain any hardcoded credentials.
Create the config.json file in the .keeper folder of the current user.
A sample showing the structure of the config.json needed is shown below:
{
"users": [
{
"user": "[email protected]",
"password":"yourpassword",
"server": "keepersecurity.com",
"last_device": {
"device_token": ""
}
}
],
"servers": [
{
"server": "keepersecurity.com",
"server_key_id": 10
}
],
"devices": [
{
"device_token": "",
"private_key": "",
"server_info": [
{
"server": "keepersecurity.com",
"clone_code": ""
}
]
}
],
"last_login": "[email protected]",
"last_server": "keepersecurity.com"
}Create a .py file to act as a client to access the keepersdk and execute the vault and admin functions.
Sample code to list records has been shown below:
import sqlite3
import getpass
from keepersdk.authentication import login_auth, configuration, endpoint
from keepersdk.vault import sqlite_storage, vault_online, vault_record
# Initialize configuration and authentication context
config = configuration.JsonConfigurationStorage()
keeper_endpoint = endpoint.KeeperEndpoint(config)
login_auth_context = login_auth.LoginAuth(keeper_endpoint)
# Authenticate user
login_auth_context.login(config.get().users()[0].username, config.get().users()[0].password)
while not login_auth_context.login_step.is_final():
if isinstance(login_auth_context.login_step, login_auth.LoginStepDeviceApproval):
login_auth_context.login_step.send_push(login_auth.DeviceApprovalChannel.KeeperPush)
print("Device approval request sent. Login to existing vault/console or ask admin to approve this device and then press return/enter to resume")
input()
elif isinstance(login_auth_context.login_step, login_auth.LoginStepPassword):
password = getpass.getpass('Enter password: ')
login_auth_context.login_step.verify_password(password)
elif isinstance(login_auth_context.login_step, login_auth.LoginStepTwoFactor):
channel = login_auth_context.login_step.get_channels()[0]
code = getpass.getpass(f'Enter 2FA code for {channel.channel_name}: ')
login_auth_context.login_step.send_code(channel.channel_uid, code)
else:
raise NotImplementedError()
# Check if login was successful
if isinstance(login_auth_context.login_step, login_auth.LoginStepConnected):
# Obtain authenticated session
keeper_auth = login_auth_context.login_step.take_keeper_auth()
# Set up vault storage (using SQLite in-memory database)
conn = sqlite3.Connection('file::memory:', uri=True)
vault_storage = sqlite_storage.SqliteVaultStorage(
lambda: conn,
vault_owner=bytes(keeper_auth.auth_context.username, 'utf-8')
)
# Initialize vault and synchronize with Keeper servers
vault = vault_online.VaultOnline(keeper_auth, vault_storage)
vault.sync_down()
# Access and display vault records
print("Vault Records:")
print("-" * 50)
for record in vault.vault_data.records():
print(f'Title: {record.title}')
# Handle legacy (v2) records
if record.version == 2:
legacy_record = vault.vault_data.load_record(record.record_uid)
if isinstance(legacy_record, vault_record.PasswordRecord):
print(f'Username: {legacy_record.login}')
print(f'URL: {legacy_record.link}')
# Handle modern (v3+) records
elif record.version >= 3:
print(f'Record Type: {record.record_type}')
print("-" * 50)
vault.close()
keeper_auth.close()The full Commander SDK documentation and references are below:
Github Code with Example Usage
This page describes the usage of Keeper Commander CLI as a library for Python Developers
Follow the instructions below to develop or test Keeper Commander from source code, using a Python virtual environment to isolate dependencies. The Commander CLI can be used as a library or you can modify the CLI source code to fit your needs.
Clone the GitHub repository to your local machine: https://github.com/Keeper-Security/Commander
git clone https://github.com/Keeper-Security/Commander
cd CommanderThe "master" branch will mirror the production release. The "release" branch references the upcoming release. To optionally switch to the release branch:
git checkout releaseInstall the most recent Python3 installation from python.org.
python3 -m venv venv
source venv/bin/activatepython -m venv venv
.\venv\Scripts\activatepip install -r requirements.txt
pip install -e .For full email provider support (OAuth, SendGrid, AWS SES), install optional dependencies:
pip install -e '.[email]'You can now launch the Commander CLI:
keeper shellSee the Logging in section to understand the authentication process. Explore all of the Commands available.
To sign into Keeper Commander with the SDK, there are two main methods:
Manual authentication
This method requires a username, then prints out the login prompts from Commander so the user can authenticate before the program continues.
from keepercommander.params import KeeperParams
from keepercommander import api
params = KeeperParams()
params.user = input('User email: ')
api.login(params) # Initiates login prompts
api.sync_down(params)Automatic authentication
This method uses the config.json file generated when creating Persistent Login configurations. If the configuration file is valid, the program will sign into Commander without any prompts. If the configuration file is not valid or expired, the program will fall back to login prompts.
from keepercommander.__main__ import get_params_from_config
params = get_params_from_config("{{path_to_config_file}}")To run bash-formatted CLI commands directly from a python script, you can import the cli package from the keepercommander library and run its do_command function:
from keepercommander.__main__ import get_params_from_config
from keepercommander import cli
# Login
params = get_params_from_config("{{path_to_config_file}}")
# Execute command
cli.do_command(params, "{{cli_command}}")The do_command function is useful for executing standalone CLI commands. It can also be run without using api.login() or api.sync_down(). It will however not return any content - e.g. you cannot leverage it to retrieve objects directly in Python.
Functions which yield python responses can be found in various directories of the keepercommander module, and will require api.login() and api.sync_down() to be ran initially. Incidentally, many useful functions can be found in the api.py package, some of which are demonstrated in the next example:
from keepercommander.__main__ import get_params_from_config
from keepercommander import api
# Login
params = get_params_from_config("{{path_to_config_file}}")
api.login(params)
api.sync_down(params)
# Search shared folder
shared_folder_name = 'Example Shared Folder'
folder_search = api.search_shared_folders(params, shared_folder_name)
# Get full record dictionaries if folder exists
keeper_folder = None
if folder_search:
keeper_folder = folder_search[0]
for record in keeper_folder.records:
record_obj = api.get_record(params, record["record_uid"])
print(record_obj.to_dictionary())
else:
print('No folder found')Functions which access enterprise data will not retrieve any content unless the params.enterprise object is populated, which can be achieved with the api.query_enterprise() function. The following program retrieves the JSON output of an audit-report command directly in Python:
from keepercommander.__main__ import get_params_from_config
from keepercommander import api
from keepercommander.commands.aram import AuditReportCommand
from json import loads
# Login
params = get_params_from_config("{{path_to_config_file}}")
api.login(params)
api.sync_down(params)
api.query_enterprise(params) # Populate enterprise
# Get JSON report directly in Python
kwargs = {
'report_type':'raw',
'format':'json',
'limit':-1,
'aggregate':['occurences']
}
command_class = AuditReportCommand()
command_run = command_class.execute(params, **kwargs)
report = loads(command_run)You can leverage the full scope of the Commander CLI by using its internal classes and functions. Several standalone python scripts can be found here, with examples for searching records, creating teams and sharing folders, and more.