Detailed documentation for record-add and record-update commands
This document provides comprehensive examples for creating records using the record-add
command in Keeper Commander. The command supports dot notation for field specification and $JSON: syntax for complex field types.
Note: Keeper Commander supports line continuation using backslash (
\
) at the end of lines, allowing you to split long commands across multiple lines for better readability.Important: Do not put spaces after the backslash (
\
) character. The line should end immediately with\
with no trailing spaces, otherwise empty arguments will be created and cause parsing errors.
record-add --title "Record Title" --record-type "RECORD_TYPE" [OPTIONS] [FIELDS...]
--title
/ -t
: Record title (required)
--record-type
/ -rt
: Record type (required)
--notes
/ -n
: Record notes (optional)
--folder
: Folder path or UID to store the record (optional)
--force
/ -f
: Ignore warnings (optional)
--syntax-help
: Display field syntax help
Dot Notation Format:
[FIELD_SET.][FIELD_TYPE][.FIELD_LABEL]=FIELD_VALUE
Components:
FIELD_SET
: Optional. f
(fields) or c
(custom)
FIELD_TYPE
: Field type (e.g., login, password, url, etc.)
FIELD_LABEL
: Optional field label
FIELD_VALUE
: The field value
Special Value Syntax:
$JSON:{"key": "value"}
- For complex object fields
$GEN
- Generate passwords, TOTP codes, or key pairs
file=@filename
- File attachments
Keeper Commander supports two types of records:
Typed Records - Structured records with predefined schemas (login, bankAccount, contact, etc.)
Legacy Records - General records (use -rt legacy
or -rt general
)
login
- Username/login field
password
- Password field (masked)
url
- Website URL
email
- Email address
text
- Plain text
multiline
- Multi-line text
secret
- Masked text field
note
- Masked multiline text
oneTimeCode
- TOTP/2FA codes
date
- Unix epoch time or date strings
phone
- Phone number with region/type
name
- Person's name (first, middle, last)
address
- Physical address
paymentCard
- Credit card details
bankAccount
- Bank account details
securityQuestion
- Security Q&A pairs
host
- Hostname/port combinations
keyPair
- SSH key pairs
Single-line version (safest for copy-paste):
record-add -t "Gmail Account" -rt login login=john.doe@gmail.com password=SecurePass123 url=https://accounts.google.com
Multi-line version (type manually, don't copy-paste):
record-add -t "Gmail Account" -rt login \
login=john.doe@gmail.com \
password=SecurePass123 \
url=https://accounts.google.com
record-add -t "John Smith" -rt contact \
name='$JSON:{"first": "John", "middle": "Michael", "last": "Smith"}' \
email=john.smith@email.com \
phone.Mobile='$JSON:{"number": "(555) 555-1234", "type": "Mobile"}'
Keeper Commander allows scripting through run-batch
or run
commands. The easiest way to get the record JSON template is to create one record in web vault then in Keeper Commander run get UID --format=json
that gives the exact format to use for complex object fields in the form $JSON:{"key": "value"}
Then you can generate the batch script and run it.
# my_script.txt
record-add -t "Gmail Account" -rt login login=john.doe@gmail.com
record-add -t "Yahoo Account" -rt login login=john.doe@yahoo.com
# run batch
keeper shell run-batch my_script.txt
# Basic login
record-add -t "Gmail Account" -rt login \
login=john.doe@gmail.com \
password=SecurePass123 \
url=https://accounts.google.com
# Login with generated password
record-add -t "Work Account" -rt login \
login=john.doe \
password='$GEN:rand,16' \
url=https://company.com
# Login with TOTP
record-add -t "Banking Login" -rt login \
login=john.doe \
password=MySecurePassword \
url=https://mybank.com \
oneTimeCode='$GEN'
# Login with security questions
record-add -t "Investment Account" -rt login \
login=john.doe \
password=InvestPass123 \
url=https://investment.com \
securityQuestion.Mother='$JSON:[{"question": "What is your mother'\''s maiden name?", "answer": "Smith"}]'
# Login with custom fields
record-add -t "Work VPN" -rt login \
login=john.doe \
password=VpnPass123 \
url=https://vpn.company.com \
c.text.Department="IT Security" \
c.text.Employee_ID="EMP001"
# Basic bank account
record-add -t "Chase Checking" -rt bankAccount \
bankAccount='$JSON:{"accountType": "Checking", "routingNumber": "021000021", "accountNumber": "123456789"}' \
name='$JSON:{"first": "John", "last": "Doe"}' \
login=john.doe \
password=BankPass123
# Bank account with online banking
record-add -t "Wells Fargo Savings" -rt bankAccount \
bankAccount='$JSON:{"accountType": "Savings", "routingNumber": "121042882", "accountNumber": "987654321"}' \
name='$JSON:{"first": "Jane", "last": "Smith"}' \
login=jane.smith \
password=SavePass456 \
url=https://wellsfargo.com \
--notes "High yield savings account"
# Credit card
record-add -t "Chase Sapphire Preferred" -rt bankCard \
paymentCard='$JSON:{"cardNumber": "4111111111111111", "cardExpirationDate": "12/2025", "cardSecurityCode": "123"}' \
text.cardholderName="John Doe" \
pinCode=1234 \
login=john.doe \
password=CardPass123
# Debit card
record-add -t "Bank of America Debit" -rt bankCard \
paymentCard='$JSON:{"cardNumber": "5555555555554444", "cardExpirationDate": "08/2026", "cardSecurityCode": "456"}' \
text.cardholderName="Jane Smith" \
pinCode=5678
# Personal contact
record-add -t "John Smith" -rt contact \
name='$JSON:{"first": "John", "middle": "Michael", "last": "Smith"}' \
email=john.smith@email.com \
phone.Mobile='$JSON:{"number": "(555) 555-1234", "type": "Mobile"}' \
text.company="ABC Corporation"
# Business contact with multiple phone numbers
record-add -t "Dr. Sarah Johnson" -rt contact \
name='$JSON:{"first": "Sarah", "last": "Johnson"}' \
email=sarah.johnson@medical.com \
phone.Work='$JSON:{"number": "(555) 987-6543", "type": "Work"}' \
phone.Mobile='$JSON:{"number": "(555) 123-4567", "type": "Mobile"}' \
text.company="Medical Associates" \
c.text.Title="Chief Medical Officer"
# Home address
record-add -t "Home Address" -rt address \
address='$JSON:{"street1": "123 Main St", "street2": "Apt 4B", "city": "New York", "state": "NY", "zip": "10001", "country": "US"}'
# Work address
record-add -t "Office Address" -rt address \
address='$JSON:{"street1": "456 Business Ave", "city": "San Francisco", "state": "CA", "zip": "94105", "country": "US"}' \
--notes "Main office location"
# Web server
record-add -t "Production Web Server" -rt serverCredentials \
host='$JSON:{"hostName": "web.company.com", "port": "22"}' \
login=admin \
password='$GEN:rand,20' \
c.text.Environment="Production" \
c.text.Purpose="Web Server"
# Database server
record-add -t "MySQL Database" -rt databaseCredentials \
host='$JSON:{"hostName": "db.company.com", "port": "3306"}' \
login=dbadmin \
password=DbSecure123 \
text.database="production_db"
# SSH key pair
record-add -t "Production SSH Key" -rt sshKeys \
keyPair='$GEN:ed25519,enc' \
host='$JSON:{"hostName": "prod.company.com", "port": "22"}' \
login=deploy \
c.text.Purpose="Production deployment"
# Existing SSH key
record-add -t "GitHub SSH Key" -rt sshKeys \
keyPair='$JSON:{"privateKey": "-----BEGIN OPENSSH PRIVATE KEY-----\n...", "publicKey": "ssh-ed25519 AAAAC3..."}' \
host='$JSON:{"hostName": "github.com", "port": "22"}' \
login=git
# Software license
record-add -t "Microsoft Office" -rt softwareLicense \
licenseNumber="XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" \
c.text.Product_Version="Office 365" \
c.text.Licensed_To="John Doe" \
c.date.Purchase_Date="2023-01-15" \
c.date.Expiration_Date="2024-01-15"
# WiFi network
record-add -t "Home WiFi" -rt wifiCredentials \
text.ssid="MyHomeNetwork" \
password=WiFiPassword123 \
c.text.Security_Type="WPA2" \
c.text.Frequency="5GHz"
# Basic secure note
record-add -t "Important Information" -rt encryptedNotes \
note="This is confidential information that needs to be encrypted." \
date="2024-01-15"
# Secure note with custom fields
record-add -t "Recovery Codes" -rt encryptedNotes \
note="Backup codes for two-factor authentication" \
c.text.Service="Google Authenticator" \
c.multiline.Codes="123456\n789012\n345678"
# PostgreSQL database
record-add -t "Production PostgreSQL" -rt databaseCredentials \
host='$JSON:{"hostName": "db.company.com", "port": "5432"}' \
login=postgres \
password='$GEN:rand,24' \
text.database="production_db" \
c.text.Environment="Production" \
c.text.SSL_Mode="require"
# MongoDB database
record-add -t "Analytics MongoDB" -rt databaseCredentials \
host='$JSON:{"hostName": "mongo.company.com", "port": "27017"}' \
login=admin \
password=MongoPass456 \
text.database="analytics" \
c.text.Replica_Set="rs0"
# Driver's license
record-add -t "Driver's License" -rt driverLicense \
accountNumber=DL123456789 \
name='$JSON:{"first": "John", "last": "Doe"}' \
birthDate="1990-01-15" \
expirationDate="2025-01-15" \
address='$JSON:{"street1": "123 Main St", "city": "New York", "state": "NY", "zip": "10001", "country": "US"}' \
c.text.License_Class="Class C"
# Commercial driver's license
record-add -t "CDL License" -rt driverLicense \
accountNumber=CDL987654321 \
name='$JSON:{"first": "Jane", "last": "Smith"}' \
birthDate="1985-05-20" \
expirationDate="2024-05-20" \
c.text.License_Class="Class A" \
c.text.Endorsements="Hazmat, Passenger"
# US Passport
record-add -t "US Passport" -rt passport \
accountNumber=123456789 \
name='$JSON:{"first": "John", "last": "Doe"}' \
birthDate="1990-01-15" \
expirationDate="2030-01-15" \
date="2020-01-15" \
address='$JSON:{"street1": "123 Main St", "city": "New York", "state": "NY", "zip": "10001", "country": "US"}' \
c.text.Place_of_Birth="New York, NY" \
c.text.Nationality="US"
# Health insurance
record-add -t "Blue Cross Blue Shield" -rt healthInsurance \
accountNumber=12345678901 \
name='$JSON:{"first": "John", "last": "Doe"}' \
login=john.doe \
password=HealthPass123 \
url=https://bcbs.com \
c.text.Plan_Type="PPO" \
c.text.Group_Number="12345" \
c.text.Deductible="$2000"
# Gym membership
record-add -t "Gold's Gym" -rt membership \
accountNumber=GYM123456 \
name='$JSON:{"first": "John", "last": "Doe"}' \
password=GymPass123 \
c.text.Membership_Type="Premium" \
c.date.Expiration_Date="2024-12-31"
# Professional membership
record-add -t "IEEE Membership" -rt membership \
accountNumber=IEEE987654 \
name='$JSON:{"first": "Jane", "last": "Smith"}' \
password=IEEEPass456 \
c.text.Membership_Grade="Senior Member" \
c.text.Specialization="Computer Science"
# Birth certificate
record-add -t "Birth Certificate" -rt birthCertificate \
name='$JSON:{"first": "John", "middle": "Michael", "last": "Doe"}' \
birthDate="1990-01-15" \
address='$JSON:{"street1": "Hospital Address", "city": "New York", "state": "NY", "country": "US"}' \
c.text.Certificate_Number="BC123456789" \
c.text.Place_of_Birth="New York General Hospital" \
c.text.Parents_Names="Jane Doe, Robert Doe"
# SSN card
record-add -t "Social Security Card" -rt ssnCard \
accountNumber=123-45-6789 \
name='$JSON:{"first": "John", "middle": "Michael", "last": "Doe"}' \
c.text.Issue_Date="2008-01-15" \
c.text.Issue_State="New York"
# Photo record
record-add -t "Profile Photo" -rt photo \
file='@/path/to/profile.jpg' \
c.text.Description="Professional headshot" \
c.date.Date_Taken="2024-01-15"
# Record with file attachment
record-add -t "Important Document" -rt file \
file='@/path/to/document.pdf' \
--notes "Legal documents"
# Multiple file attachments
record-add -t "Project Files" -rt file \
file='@/path/to/project.zip' \
file='@/path/to/readme.txt' \
c.text.Project_Name="Alpha Release"
PAM records require additional commands to set them up for rotation, connections, tunneling etc. see the example below this section.
PAM Configuration types are created using pam config command.
# PAM Database configuration
record-add -t "Production Oracle DB" -rt pamDatabase \
pamHostname='$JSON:{"hostName": "oracle.company.com", "port": "1521"}' \
login=system \
password='$GEN:rand,20' \
text.database="PROD" \
c.text.Instance_Name="ORCL" \
c.text.Service_Name="prod.company.com"
# Active Directory PAM
record-add -t "Corporate Active Directory" -rt pamDirectory \
pamHostname='$JSON:{"hostName": "dc.company.com", "port": "389"}' \
login=administrator \
password='$GEN:rand,24' \
c.text.Domain="company.com" \
c.text.Base_DN="dc=company,dc=com" \
c.text.Security_Protocol="LDAPS"
# Production server PAM
record-add -t "Production Web Server" -rt pamMachine \
pamHostname='$JSON:{"hostName": "web01.company.com", "port": "22"}' \
login=root \
password='$GEN:rand,20' \
c.text.OS="Ubuntu 20.04" \
c.text.Environment="Production" \
c.text.Purpose="Web Application Server"
# Privileged user account
record-add -t "Database Admin User" -rt pamUser \
login=dbadmin \
password='$GEN:rand,24' \
name='$JSON:{"first": "Database", "last": "Administrator"}' \
c.text.Department="IT Operations" \
c.text.Access_Level="Full Database Admin" \
c.date.Account_Expiry="2024-12-31"
# Remote browser session
record-add -t "Salesforce Admin Session" -rt pamRemoteBrowser \
url=https://company.salesforce.com \
login=admin@company.com \
password='$GEN:rand,16' \
c.text.Session_Type="Administrative" \
c.text.Browser_Profile="Chrome Enterprise"
Each PAM Record belongs to a PAM Configuration which references a Keeper Gateway usually installed in your local network or in a place that provides access to the PAM resources. The following is a good starting point for configuring a new PAM Environment.
# Create shared folder
mkdir gwapp -sf -a
# Create Secrets Manager Application
secrets-manager app create gwapp1
# Add newly created shared folder to the new App
secrets-manager share add --app=gwapp1 --secret=SHARED_FOLDER_UID --editable
# Create new PAM Gateway - output: base64 config for docker
pam gateway new --name=gateway1 --application=gwapp1 --config-init=b64 --return_value
# Create new PAM Configuration using the new Gateway
pam config new --environment=local \
--title=config1 \
--gateway=gateway1 \
-sf=SHARED_FOLDER_UID \
--connections=on --tunneling=on --rotation=on --remote-browser-isolation=on
# Create PAM resource records and users: 1 machine with admin and rotation user(s)
record-add --folder=SHARED_FOLDER_UID --title=admin1 -rt=pamUser \
login=admin1 password="$GEN:rand,16"
record-add --folder=SHARED_FOLDER_UID --title=user1 -rt=pamUser \
login=user1 password="$GEN:rand,16"
record-add --folder=SHARED_FOLDER_UID --title=machine1 -rt=pamMachine \
pamHostname="$JSON:{\"hostName\": \"127.0.0.1\", \"port\": \"22\"}"
# Setup PAM Machine for connections and tunnelling
pam tunnel edit PAM_MACHINE_UID --configuration=PAM_CONFIG_UID --enable-tunneling
pam connection edit PAM_MACHINE_UID --configuration=PAM_CONFIG_UID \
--connections=on \
--protocol=ssh \
--admin-user=ADMIN_USER_UID
# Setup PAM User for rotation on the machine (resource)
# --force switches to non-interactive mode
pam rotation edit --config=PAM_CONFIG_UID \
--record=PAM_USER_UID \
--resource=PAM_MACHINE_UID \
--admin-user=ADMIN_USER_UID \
--on-demand --enable --force
# After installing the Gateway you can test the setup
pam tunnel start PAM_MACHINE_UID
# pam tunnel stop ENDPOINT_UID
pam action rotate --record-uid=PAM_USER_UID
# Random password (default)
password='$GEN'
password='$GEN:rand,16' # 16 characters
# Diceware password
password='$GEN:dice,5' # 5 words
# Crypto password
password='$GEN:crypto'
# Generate TOTP secret
oneTimeCode='$GEN'
# Existing TOTP URL
oneTimeCode='otpauth://totp/Example:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Example'
# Generate RSA key pair
keyPair='$GEN:rsa'
# Generate EC key pair
keyPair='$GEN:ec'
# Generate Ed25519 key pair (recommended)
keyPair='$GEN:ed25519'
# Generate encrypted key pair
keyPair='$GEN:ed25519,enc'
# Custom text field
c.text.Department="Engineering"
# Custom multiline field
c.multiline.Notes="Line 1\nLine 2\nLine 3"
# Custom secret field (masked)
c.secret.API_Key="secret-api-key-here"
# Custom date field
c.date.Expiration="2024-12-31"
# Unix timestamp
date=1668639533
# ISO format
date="2022-11-16T10:58:53Z"
# Simple date
date="2022-11-16"
phone.Work='$JSON:{"region": "US", "number": "(555) 555-1234", "ext": "123", "type": "Work"}'
phone.Mobile='$JSON:{"number": "(555) 555-1234", "type": "Mobile"}'
name='$JSON:{"first": "John", "middle": "Michael", "last": "Doe"}'
name='$JSON:{"first": "Jane", "last": "Smith"}'
address='$JSON:{"street1": "123 Main St", "street2": "Apt 4B", "city": "New York", "state": "NY", "zip": "10001", "country": "US"}'
securityQuestion.Mother='$JSON:[{"question": "What is your mother'\''s maiden name?", "answer": "Smith"}]'
securityQuestion.Pet='$JSON:[{"question": "What was your first pet'\''s name?", "answer": "Fluffy"}]'
The --self-destruct
option creates temporary records that automatically delete themselves after being accessed. This is perfect for sharing sensitive information that should only be viewed once.
Creates a temporary shareable URL that expires after your specified time
Record stays in your vault until someone opens the share URL
Auto-deletes from your vault 5 minutes after the URL is first accessed
Maximum duration is 6 months
--self-destruct <NUMBER>[(m)inutes|(h)ours|(d)ays]
Time Units:
m
or minutes
- Minutes (default if no unit specified)
h
or hours
- Hours
d
or days
- Days
Share temporary password (expires in 1 hour):
record-add -t "Temporary Server Access" -rt login \
login=admin \
password='$GEN:rand,16' \
url=https://server.company.com \
--self-destruct 1h \
--notes "Emergency access for John Doe"
One-time WiFi credentials (expires in 30 minutes):
record-add -t "Guest WiFi Access" -rt wifiCredentials \
text.ssid="Company-Guest" \
password=TempPass123 \
--self-destruct 30m \
--notes "Visitor access for meeting"
Temporary file share (expires in 24 hours):
record-add -t "Confidential Document" -rt file \
file='@/path/to/sensitive-doc.pdf' \
--self-destruct 1d \
--notes "Contract for review - auto-deletes after viewing"
Emergency contact info (expires in 2 hours):
record-add -t "Emergency Contact" -rt contact \
name='$JSON:{"first": "Emergency", "last": "Contact"}' \
phone.Mobile='$JSON:{"number": "(555) 911-0000", "type": "Emergency"}' \
--self-destruct 2h
When using --self-destruct
, the command returns a shareable URL instead of a record UID:
$ record-add -t "Temp Password" -rt login login=user password=pass123 --self-destruct 1h
https://keepersecurity.com/vault/share/AbCdEf123456...
⚠️ Security Considerations:
URL is the key - Anyone with the URL can access the record
No authentication required - Share URLs bypass login requirements
One-time access - Record deletes 5 minutes after first view
Cannot be recovered - Once deleted, the record is gone forever
⚠️ Limitations:
Maximum 6 months expiration time
Cannot update self-destructing records
No preview - You can't see the record again after creation
Immediate sharing - URL is active immediately upon creation
Copy the URL immediately - You won't be able to retrieve it later
Use short expiration times for maximum security (minutes/hours vs days)
Include context in notes about why the record was created
Share URL through secure channels (encrypted messaging, in person)
Generate strong passwords using $GEN
for temporary access
Verify recipient received URL before the expiration time
Emergency access credentials for system administrators
Temporary passwords for contractors or consultants
One-time document sharing for sensitive files
Guest network credentials for visitors
Secure information handoffs between team members
Time-sensitive shared secrets for automated systems
Use single-line commands for copy-paste to avoid trailing space issues
Quote JSON values to prevent shell interpretation
Use $GEN for passwords instead of hardcoding them
Test with simple records first before creating complex ones
Use custom fields (c.) for non-standard data
Organize records in folders using the --folder
parameter
Add meaningful notes with --notes
for context
"Expected: =, got: ; Missing =
"
Remove trailing spaces after backslashes in multi-line commands
Use single-line format for copy-paste
"Field type not supported"
Check available field types with record-add --syntax-help
Use custom fields with c.
prefix for non-standard fields
JSON parsing errors
Ensure JSON is properly quoted
Escape single quotes in JSON: '\''
Use double quotes inside JSON objects
File attachment errors
Use @
prefix: file=@/path/to/file.txt
Ensure file path is accessible
Use absolute paths to avoid confusion
While record-add
creates new records, record-update
modifies existing records. Here's how they compare:
Purpose
Creates new records
Modifies existing records
Record identifier
Not required
Required (-r
or --record
)
Record type
Required (-rt
)
Optional (can change type)
Field behavior
Sets all fields
Updates only specified fields
Notes behavior
Sets notes
Appends with +
prefix, overwrites without
record-update --record "RECORD_TITLE_OR_UID" [OPTIONS] [FIELDS...]
Key Arguments:
--record
/ -r
: Record title or UID (required)
--title
/ -t
: Update record title
--record-type
/ -rt
: Change record type
--notes
/ -n
: Update notes (+text
appends, text
overwrites)
--force
/ -f
: Ignore warnings
Update password and URL:
record-update -r "Gmail Account" \
password='$GEN:rand,20' \
url=https://accounts.google.com/new-login
Add a phone number to existing contact:
record-update -r "John Smith" \
phone.Work='$JSON:{"number": "(555) 987-6543", "type": "Work"}'
Append to notes (notice the + prefix):
record-update -r "Server Credentials" \
--notes "+Updated password on 2024-01-15"
Update title and add custom field:
record-update -r "Old Server Name" \
--title "Production Web Server" \
c.text.Environment="Production" \
c.text.Last_Updated="2024-01-15"
Change record type (converts structure):
record-update -r "Simple Login" \
--record-type contact \
name='$JSON:{"first": "John", "last": "Doe"}' \
email=john.doe@example.com
Use record-add
when:
Creating a completely new record
You want to specify all fields from scratch
Setting up initial record structure
Use record-update
when:
Modifying existing records
Adding new fields to existing records
Updating passwords or other credentials
Appending information to notes
Converting between record types
Important Notes:
record-update
only changes the fields you specify
Existing fields not mentioned remain unchanged
Use field=
(empty value) to clear a field
Notes with +
prefix append, without +
they replace
# View all available record types
record-type-info
# View fields for a specific record type
record-type-info --list-record login
# View field information
record-type-info --list-field phone
# View field syntax help
record-add --syntax-help
# View record-update syntax help
record-update --help