Creating a REST API with Keeper Commander Service Mode
The Service Mode module for Keeper Commander enables REST API integration by providing a secure, configurable API server that can be deployed with minimal setup. This module allows users to execute Commander CLI commands through a REST API interface while maintaining security and configuration flexibility. The service can be run locally and it can optionally be integrated with Ngrok for creating a routable address in your existing Ngrok network.
API Server: Flask-based REST API server for executing Commander CLI commands
Service Management: Complete lifecycle management for the API service
Configuration Management: Flexible configuration system with both interactive and streamlined setup options
Security Controls: Comprehensive security features including API key management, access controls, rate limiting and IP allow/deny.
Flexible Hosting Options: Run on-prem, Docker container or in the cloud with integrated Ngrok agent.
service-create
Initialize and configure the service with customizable settings
service-start
Start the service with existing configuration
service-stop
Gracefully stop the running service
service-status
Display current service status
service-config-add
Add new API configuration and command access settings
API key authentication
Configurable token expiration (minutes/hours/days)
Optional AES-256 GCM encryption for API responses
TLS support with provided certificate (.pem)
Rate limiting
IP Allowed / IP deny list management
Request validation and policy enforcement
Local service config JSON or YAML file will be encrypted using private key.
The Keeper Commander Service Mode feature is a self-hosted middleware that wraps an existing Commander session with a REST API. This feature is suited to environments where high speed requests and simple HTTPS-based APIs are desired.
To ensure the most secure use of this feature, we recommend the following:
Limit the scope of the Command access controls to only those commands which are required based on the use case.
Apply IP allowlist for accessing the REST API endpoint
Protect access to the machine running the Commander service
Use different API tokens for different commands and use cases
Start Keeper Commander:
keeper shell
Log in with your Keeper credentials when prompted
Create and configure the service with interactive prompts:
service-create
You'll be prompted to configure:
Config format (yaml/json)
Port number
Ngrok auth token (optional)
TLS certificate path (optional)
Security settings (optional)
Command access controls
Example:
My Vault> service-create
Enter Port No:9090
Enable Ngrok Tunneling? (y/n):y
Enter Ngrok Auth Token:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Enter Ngrok Custom Domain:myname
Enable TLS Certificate (y/n): n
Enable Advanced Security? (y/n):n
List of supported commands, Enter comma separated:whoami,record-add,tree,ls
Generated API key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Uploading service_config.yaml ...
2025-03-26 11:47:46 [INFO] keeper_service - Route initialization completed
Route initialization completed successfully
Keeper Commander Service initialization complete
Commander Service starting on http://localhost:9090
Process ID: 34291
Generated ngrok URL: https://myname.ngrok.io
* Serving Flask app 'keepercommander.service.app'
* Debug mode: off
Configure the service with a single command:
service-create -p 9090 -c 'record-add,whoami'
Starting the service with Ngrok auth token and custom domain:
service-create -p 9090 -c 'record-add,whoami' -ng xxxx -cd myname
Parameters:
-p, --port
: Port number for the service
-c, --commands
: Comma-separated list of allowed commands
-ng, --ngrok
: Ngrok authentication token for cloud managed URL access (Optional)
-cd
: Ngrok custom domain, just subdomain portion (Optional)
-aip
: allowed IP list (Optional)
-dip
: denied IP list (Optional)
-crtf, --certfile
: SSL certificate file path, accepts .crt
, .pem
or .key
(Optional)
-crtp, --certpassword
: SSL certificate password (Optional)
After the initial configuration, Commander will create a record in the vault with the title of "Commander Service Mode". This record will contain a YAML file called service_config.yaml
.
Subsequent startups of the service simply require the service-create
command, with no parameters. The configuration will be loaded from the vault and started up.
Check service status:
service-status
Add additional configuration:
service-config-add
Start the service:
service-start
Stop the service:
service-stop
Using the REST API is very simple and only requires the supplied API key and Commander command, exactly as you would type it into the CLI.
curl --location 'http://localhost:<port>/api/v1/executecommand' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{
"command": "tree"
}'
If you're using Ngrok, the Curl command will be:
curl --location 'http://<your-ngrok-url>/api/v1/executecommand' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{
"command": "tree"
}'
You can send requests through the Postman app. Just ensure that the Content-Type header and api-key header is provided. Example screenshot below:
All responses use this basic format:
{ "command": "<command_name>", "data": <command_specific_data> , "status": "success"}
Some commands have been modified to return formatted JSON. Other commands will return data exactly as they normally do through the Commander CLI version.
Examples of modified output:
{ "status": "success", "command": "ls", "data": { "folders": [ { "number": 1, "uid": "folder_uid_string", "name": "My Folder", "flags": "RW" } ], "records": [ { "number": 1, "uid": "record_uid_string", "type": "login", "title": "My Login", "description": "Optional description" } ] } }
{ "status": "success", "command": "tree", "data": [ { "level": 0, "name": "Root Folder", "path": "Root Folder" }, { "level": 1, "name": "Subfolder", "path": "Root Folder/Subfolder" } ] }
{ "status": "success", "command": "mkdir", "data": { "folder_uid": "new_folder_uid_string" } }
{ "status": "success", "command": "record-add", "data": { "record_uid": "new_record_uid_string" } }
{ "status": "success", "command": "search record", "data": [ { "number": 1, "uid": "record_uid_string", "type": "login", "title": "Matching Record", "description": "Optional description" } ] }
{ "status": "success", "command": "search folder", "data": [ { "number": 1, "uid": "folder_uid_string", "name": "Matching Folder" } ] }
{ "command": "get", "data": { "attachments": "service_config.yaml 537b ID: XYZ", "last_modified": "2025-01-18 15:35:21", "share_admins": "xyz@email.com", "shared": "False", "shared_users": "xyz@email.com (Owner)", "title": "Commander Service Mode", "type": "", "uid": "folder_uid_string" }, "status": "success" }
{ "status": "success", "command": "audit-report", "data": [ { "audit_event_type": "open_record", "created": "2025-02-18T10:30:45+00:00", "geo_location": "New York, NY, US", "ip_address": "192.168.1.100", "keeper_version": "Commander 16.11.0", "message": "User john.doe@example.com opened record UID ABCD1234EFGH5678", "username": "john.doe@example.com" } ] }
To use Commander Service Mode with Ngrok, sign up on ngrok.com and generate an Auth token from https://dashboard.ngrok.com/authtokens
If you are using a custom domain, set this up under: https://dashboard.ngrok.com/domains and specify the custom subdomain when starting the Commander service mode.
Using Ngrok has security implications. Follow this guidance:
Ensure that the Keeper service account is running with minimal permissions and access. We recommend limiting the scope of the service account to only the least amount of privilege.
Protect access to the service through Ngrok's IP policies
Limit the scope of supported commands. For example, if you only need to add records through the API, then only allow the record-add
command. See the Command List section.
Defines maximum API requests allowed within a specified time frame.
Input Format: X/[minute|hour|day]
or X per [minute|hour|day]
Valid Examples: "100/minute
", "50/hour
", "1000 per day
"
Note: Case insensitive
Controls access based on IP addresses or IP network ranges.
Input Format: Comma-separated list of IP addresses or CIDR blocks
Validation Rules: Each IP must be valid IPv4 address or CIDR block
Valid Examples: "192.168.1.1, 10.0.0.0/24
"
Notes: Empty list is allowed (skips validation)
Optional layer of AES-256 (GCM) encryption for all REST API responses
Input Format: y
or n
Private Key Validation Rules:
Exactly 32 characters long
Allowed characters: alphanumeric and special characters (@#$%^&+=)
Cannot be empty
Note: The Key is required for API response decryption.
Configures the REST API token lifespan.
Input Format: Xm, Xh, or Xd where X is a positive number and time units represent m for minutes, h for hours and d for days.
Validation Rules:
Value must be a positive number
Unit must be one of m, h or d
Valid Examples: "30m
", "24h
", "7d
".
Note: Empty input will set the token to never expire.
Specify the list of commands to be exposed via the API
Input Format: Comma-separated list of valid Keeper Commander commands
Validation Rules:
Must be a comma-separated list of valid Keeper Commander commands (can be seen by executing help in Commander CLI or entering some wrong command).
Cannot be empty
No spaces in individual commands.
Valid Example: "whoami,tree,list
"
Input Format: Select between 'json' or 'yaml'
Validation Rules: Must be either 'json' or 'yaml' (case insensitive)
The service_config.yaml
file stored in the vault contains the service properties. In the file there is a section called "records". This allows you to define an API key with specific commands and token expiration.
encryption: ''
encryption_private_key: ''
ip_allowed_list: 0.0.0.0/0
ip_denied_list: ''
is_advanced_security_enabled: n
ngrok: y
ngrok_auth_token: XXXXXXXXXX
ngrok_custom_domain: myname
ngrok_public_url: ''
tls_certificate: n
certfile: ''
certpassword: ''
port: 9090
rate_limiting: ''
records:
- api-key: XXXXXXXX
command_list: tree,record-add
expiration_timestamp: '9999-12-31T23:59:59'
- api-key: XXXXXXXX
command_list: get
expiration_timestamp: '9999-12-31T23:59:59'
Install Docker.
Clone the repository git clone.
Build docker image using command docker build -t keeper-commander .
Verify docker image created. docker images
Set two environment variables in your terminal window:
KEEPER_USERNAME
- This is the username that will login to Keeper Commander
KEEPER_PASSWORD
- This is the master password for the above user
Run the keeper-commander docker image using command
docker run -d -p <port>:<port> keeper-commander \
service-create -p <port> -f <file-format-YAML-or-JSON> -c '<comma separated commands like tree,ls>' \
-ng <ngrok-auth-token> -cd <ngrok-custom-domain> \
-aip <allowed-ip-list> -dip <denied-ip-list> \
--user $KEEPER_USERNAME \
--password $KEEPER_PASSWORD
Verify keeper-commander image is started using command docker ps
Check the logs using command
docker logs <docker container name or ID>
and get the API key from logs. The API key will show up like this:
Generated API key: <API-KEY>
curl --location 'http://localhost:<port>/api/v1/executecommand' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{
"command": "<command>"
}'
Keeper Commander supports persistent login mode (e.g. "Stay Logged In"), which keeps the session active for a specific amount of time. To activate persistent login mode on an account, type the following:
this-device persistent-login on
this-device register
If persistent login is enabled, you won't be prompted to authenticate the next time you run Commander. Persistent login is required to ensure uninterrupted background execution of the Service Mode APIs, allowing seamless authentication without repeated login prompts.
Learn more about persistent login sessions.
The service includes a comprehensive logging system that tracks:
Service startup/shutdown events
Configuration changes
API execution
Security events
Error conditions
Configuration:
Once service mode started the logging_config.yaml
is generated at default path(~.keeper) with default level INFO
User can disable logging by setting enabled: false
or can change log level (INFO, DEBUG, ERROR) by setting level value.
logging:
enabled: true
level: INFO
For support or feature requests, please contact:
Email: commander@keepersecurity.com
If you would like to request additional features or setup guides for Commander Service Mode, please reach out.