Skip to main content

Secure local password manager CLI with terminal

Project description

pm — Password Manager CLI

A secure, local password manager for developers. Runs entirely on your laptop — no cloud, no sync service, no account required.

Python 3.10 · 3.11 · 3.12 · 3.13


Features

  • 4 entry types: Login, Database, API Credential, Secure Note
  • AES-256-GCM encryption — every secret encrypted individually at rest
  • Folder organisation with typo-safe folder creation
  • Interactive wizard — no flags to memorise
  • Session cachingpm unlock once, skip the password prompt for 15 minutes
  • TOTP / 2FA — store authenticator secrets, live 6-digit codes in pm get
  • Camera-safe display — c copy · t copy TOTP · s reveal · clipboard auto-clears in 45s
  • Password history — last 5 rotations archived per entry (pm history <name>)
  • Vault health report — detects reused/weak passwords, missing 2FA, never-rotated credentials
  • Import from Chrome CSV, Bitwarden CSV, and 1Password 1PUX
  • Custom fields — attach arbitrary key-value pairs to any entry
  • Shell tab completion — pm get git<TAB> completes to entry names
  • --output table | json | raw for scripting and piping
  • Encrypted export/restore for laptop migration

Requirements

  • Python 3.10+
  • macOS / Linux / Windows

Installation

git clone <repo>
cd password-manager
pip install -e .

Verify:

pm --version

Quick Start

pm init                    # create vault (~/.pm/vault.db)
pm unlock                  # cache session (skip password for 15 min)
pm create                  # interactive wizard
pm list                    # list all entries
pm get github              # view entry
pm status                  # vault summary + stale report
pm status --health         # full security audit

Commands

pm init

Initialise a new vault. Run once. Vault is stored at ~/.pm/vault.db.

pm init

pm unlock / pm lock

Cache the master password derivation so subsequent commands skip the prompt.

pm unlock                  # cache for 15 minutes (default)
pm unlock --timeout 60     # cache for 1 hour
pm lock                    # clear the session immediately

Session is stored in the OS keychain (macOS Keychain / Linux SecretService). Each command that prompts for a password also starts a session automatically.


pm create

Interactive wizard. Prompts for entry type then relevant fields.

pm create

→ Type [login/database/api/note]: database
→ Name: prod-postgres
→ Kind [mysql/postgres/redis/mongodb/sqlite/other]: postgres
→ Host: db.example.com
→ Port [5432]:
→ Database: myapp
→ Username: admin
→ Generate Password? [y/n]: y  →  Generated: Xk9#...
→ Notes:
→ Folder [personal]: company-a
  Folder 'company-a' doesn't exist. Existing folders: personal
  Create new folder 'company-a'? [y/n]: y
✓ prod-postgres (Database) saved in folder company-a.

Entry types and their fields:

Type Fields
login username, password, website, TOTP secret, custom fields, notes
database kind, host, port, database, username, password, notes
api service, api key, api secret, endpoint, environment, notes
note title, content

Login entries support optional TOTP secrets and custom fields (e.g. account ID, recovery email).


pm get <name>

View an entry. Secrets are masked by default.

pm get github              # masked
pm get github --show       # reveal secrets
pm get github --copy       # copy primary secret to clipboard silently

Camera-safe interactive mode — after displaying the masked entry:

  ↳ c copy password  t copy totp  s reveal  q/any key to quit
  • c — copies password/api key silently; auto-clears clipboard in 45s
  • t — copies the live TOTP code (only shown when entry has a 2FA secret)
  • s — reveals masked fields inline + warns to clear terminal
  • q / any other key — dismisses

If the entry has markdown notes or long notes, they are rendered below the table with syntax highlighting.


pm edit <name>

Interactive wizard pre-filled with current values.

pm edit github                    # full interactive edit
pm edit github --folder company-a # move to different folder only

pm rename <old> <new>

Rename an entry without recreating it.

pm rename github github-personal

pm duplicate <source> <new-name>

Clone an entry — copies all fields, metadata, TOTP secret, and custom fields.

pm duplicate prod-postgres staging-postgres

pm history <name>

Show the last 5 password rotations for an entry.

pm history github              # masked
pm history github --show       # reveal previous passwords

History is recorded automatically on every pm edit that changes the password.


pm list

List all entries grouped by folder.

pm list                      # all entries
pm list --folder company-a   # one folder
pm list --folders            # folder summary with counts
pm list --search postgres    # search across all folders

pm find <query>

Deep search across all fields including encrypted metadata (host, database name, service, environment, custom fields, etc.).

pm find postgres             # matches name, host, or database name
pm find stripe               # matches service field in api entries
pm find production           # matches environment in api entries
pm find company-a            # matches folder name

pm delete <name>

pm delete github             # prompts for confirmation
pm delete github --yes       # skip confirmation

pm status

Vault summary and stale credential report.

pm status                    # default 90-day threshold
pm status --days 30          # stricter threshold
pm status --health           # full health audit

--health adds:

  • Reused passwords — entries that share the same password
  • Weak passwords — too short or no digits/symbols
  • Never rotated — password has never been changed since creation
  • Missing 2FA — login entries without a TOTP secret

pm import

Import passwords from external password managers.

# Chrome / Edge CSV export
pm import ~/chrome-passwords.csv --format chrome

# Bitwarden unencrypted CSV export
pm import ~/bitwarden-export.csv --format bitwarden

# 1Password 1PUX export
pm import ~/1password-export.1pux --format 1password

# Override destination folder for all imported entries
pm import ~/bitwarden-export.csv --folder work

Format is auto-detected from the file extension and header when --format is omitted. A preview table is shown before import is confirmed.


pm export / pm restore

Portable backup for laptop migration.

# Export (encrypted — safe to store in cloud/USB)
pm export backup.enc

# Export plain JSON (keep secure — contains raw secrets)
pm export backup.json --format json

# Restore on new laptop
pm init
pm restore backup.enc

pm open <name>

Open the saved URL in the default browser.

pm open github

pm generate

Generate a password without saving it.

pm generate                  # 20 chars, letters + digits + symbols
pm generate --length 32
pm generate --no-symbols
pm generate --count 5        # generate 5 options

pm completion

Enable shell tab completion for entry names (pm get git<TAB>).

# Zsh
pm completion --shell zsh
# → follow the printed instructions to add to ~/.zshrc

# Bash
pm completion --shell bash

# Fish
pm completion --shell fish

Entry names complete when a vault session is active (pm unlock first).


Output Formats

All read commands (get, list, find, status) support --output / -o:

Format Description
table Rich terminal display (default)
json Full JSON — secrets masked unless --show
raw Primary secret only, suitable for piping
pm get github -o raw                            # password only
pm get prod-postgres -o raw                     # postgresql://user:pass@host/db
pm get stripe-prod -o raw                       # api key only

pm get github -o json --show                    # full JSON with plaintext secrets
pm list -o json | jq '.[].name'                 # extract names
pm status --days 30 -o json | jq '.stale[].name'
pm find production -o raw                       # one entry name per line

Folders

Entries are grouped by folder (personal by default). Folders are created implicitly — no setup needed. A confirmation prompt protects against typos when a new folder name is used.

pm create                    # wizard asks for folder
pm edit github --folder work # move entry to a different folder
pm list --folders            # see all folders

TOTP / 2FA

Store an authenticator secret alongside any login entry. The live 6-digit code appears automatically in pm get and can be copied with t.

 Name     github
 Password ••••••••
 TOTP     847291  (12s)
  ↳ c copy password  t copy totp  s reveal  q/any key to quit

Add or update via pm create or pm edit — the wizard prompts for a TOTP secret (base32 format, e.g. from a QR code scanner).


Custom Fields

Attach arbitrary key-value pairs to any entry during pm create or pm edit:

Add/edit custom fields? [y/n]: y
Custom field (label=value): Account ID=GH-123456
Custom field (label=value): Recovery email=backup@email.com
Custom field (label=value):          ← empty to finish

Custom fields are encrypted at rest alongside other metadata.


Laptop Migration

# On old laptop
pm export ~/backup.enc       # prompts for a backup password

# Copy backup.enc to new laptop (USB, AirDrop, encrypted cloud, etc.)

# On new laptop
pip install -e .
pm init
pm restore ~/backup.enc      # prompts for the backup password

The backup password is independent of your master password.


Security

Property Detail
Encryption AES-256-GCM per field
Key derivation PBKDF2-HMAC-SHA256, 600 000 iterations
Master password Never stored — derived key verified via token
Storage SQLite at ~/.pm/vault.db
Session cache Derived key stored in OS keychain (macOS Keychain / Linux SecretService)
Clipboard Auto-cleared after 45s; only cleared if clipboard still holds the copied value
Export Re-encrypted with a separate backup password + fresh salt

Override vault location: export PM_VAULT_PATH=/path/to/vault.db Skip password prompt in scripts: export PM_MASTER_PASSWORD=...


Environment Variables

Variable Default Description
PM_VAULT_PATH ~/.pm/vault.db Path to vault file
PM_MASTER_PASSWORD Skip interactive password prompt

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

password_manager_vault-1.0.0.tar.gz (27.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

password_manager_vault-1.0.0-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

Details for the file password_manager_vault-1.0.0.tar.gz.

File metadata

  • Download URL: password_manager_vault-1.0.0.tar.gz
  • Upload date:
  • Size: 27.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for password_manager_vault-1.0.0.tar.gz
Algorithm Hash digest
SHA256 64124b286790854564117b50ff497d0b5e1149a3a6b7d366e60906296b98eabb
MD5 f05506282d634e0d3c6dc6a2e4ff1747
BLAKE2b-256 3c9c09fedcb878a0d970b78957f370a5e4e97245bee1837d148733719559ae2d

See more details on using hashes here.

File details

Details for the file password_manager_vault-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for password_manager_vault-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a803377cae9a218a1b85ee2d0974e49e432170cc9bc91f566a24931094349f09
MD5 bb1b7907a11f6596419ac1b5a531f935
BLAKE2b-256 9be1c5933fda32b8661f380ef92e51c1adf66d7f7610ddb12cd61a55a03fd9c5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page