A simple password manager with synchronization
Project description
Passmate — A simple, secure password manager with multi-device synchronization
Passmate is a command-line password manager that keeps your passwords encrypted and synchronized across multiple devices using a shared folder (like Syncthing, Dropbox or any cloud storage).
✨ Features | 📦 Installation | 🚀 Quick Start | 📖 Usage | 🔧 Configuration | 🔄 Multi-Device Synchronization | 🔐 Security | 🔨 Development | 🔗 Links
Features
- 🔒 Strong Encryption: All databases encrypted with scrypt. By using a single-file database, metadata leakage is minimzed.
- 🔄 Automatic Sync: Conflict-free synchronization across devices
- 💻 Interactive Shell: User-friendly command-line interface with tab completion
- 🌳 Hierarchical Organization: Organize passwords in folder-like paths
- 🎲 Password Generator: Built-in cryptographically strong password generator
- 🔍 Smart Search: Case-insensitive filtering across all records
Installation
Using pip:
pip install passmate
From source:
git clone https://github.com/TobiasKaiser/passmate.git
cd passmate
pip3 install .
Quick Start
Simply run:
passmate
If this is your first time, passmate will automatically create a new encrypted database at ~/.local/share/passmate/local.pmdb and prompt you to set a master passphrase.
For subsequent uses, just run passmate again and enter your passphrase.
Usage
Interactive Shell Commands
Once in the shell, you can use these commands:
Managing Records
new work/email/gmail Create a new record
open work/email/gmail Open an existing record
rename work/email/google Rename current record
del Delete current record
close Close current record
Editing Fields
set username Set a field value
set password Set password field
gen password Generate secure password
unset password Remove a field
show Display all fields
Navigation & Organization
ls List all records
ls gmail Search for records matching "gmail"
Synchronization
sync Sync with other devices
change_passphrase Change master passphrase
Other
exit Exit passmate
Example Session
passmate> new work/email/gmail
Record "work/email/gmail" created.
passmate:work/email/gmail> set username
Value: myemail@gmail.com
passmate:work/email/gmail> gen password
Template: Aaaaaaaaaaaaaa5
Settings: 15 characters including a-z, A-Z, 0-9
Generated password: xK9mPqR2nFwLyJa
passmate:work/email/gmail> show
username: myemail@gmail.com
password: xK9mPqR2nFwLyJa
passmate:work/email/gmail> close
passmate> exit
Configuration
Default configuration file: ~/.local/share/passmate/config.toml
primary_db = "~/.local/share/passmate/local.pmdb"
shared_folder = "~/.local/share/passmate/sync/"
host_id = "laptop"
template_preset = "Aaaaaaaaaaaaaa5"
Configuration Options
- primary_db: Path to your encrypted password database
- shared_folder: Path to folder for synchronization (e.g., Dropbox folder)
- host_id: Unique identifier for this device (defaults to hostname)
- template_preset: Default template used by
genfor new fields
Default Paths
Under Linux, passmate uses the following default paths:
| Path | Purpose | How to change |
|---|---|---|
~/.local/share/passmate/config.toml |
Configuration file | Pass custom path as command line argument |
~/.local/share/passmate/local.pmdb |
Primary database | Change primary_db in config file |
~/.local/share/passmate/sync/ |
Shared folder for sync | Change shared_folder in config file |
Multi-Device Synchronization
Passmate uses a conflict-free synchronization strategy based on timestamps (Last-Write-Wins strategy). To synchronize your database across multiple systems, use a file/folder synchronization tool of your choice to sync the shared folder.
Synchronization Tools
Passmate works with any file synchronization mechanism. Popular options include:
- Syncthing - Decentralized file synchronization
- Unison - File synchronization tool
- Network filesystems - NFS, SMB, sshfs
- Cloud services - Dropbox, NextCloud/WebDAV, or similar
Setup Instructions
-
On Device 1:
passmate
-
Configure shared folder (edit
~/.local/share/passmate/config.toml):shared_folder = "~/Dropbox/passmate/" host_id = "laptop"
-
In the shell, run sync:
passmate> sync -
On Device 2:
Copy the configuration and set a different host_id:
shared_folder = "~/Dropbox/passmate/" host_id = "desktop"
-
On Device 2, start passmate:
passmate
It will create a new database, then sync to pull data from Device 1.
Master passphrase in multi-device setup: If you use the same master passphrase on all devices, synchronization will be seamless. If different passphrases are used on different hosts, you will be prompted to enter the remote host's passphrase during synchronization. When changing your passphrase, you must do so on each device individually.
How Sync Works
- Each device writes a sync copy to the shared folder.
- When you run
sync, passmate reads all sync copies and merges changes. - Conflicts are resolved automatically using modification timestamps.
- All changes are encrypted with your master passphrase.
Security
- All databases are encrypted using the scrypt key derivation function (N=2^17, r=8, p=1).
- Data is padded to 4KB increments to reduce metadata leakage.
- Password generation uses Python's
secretsmodule (CSPRNG).
Development
There are some rudimentary tests:
pytest-3 .
To build the package's .whl and .tar.gz files, run:
python3 -m build
Database Format
Passmate stores password data as a JSON object encrypted using scrypt's container format. The container uses AES256-CTR encryption and HMAC-SHA256 for integrity verification.
Data Model:
- Each password record contains metadata fields (currently just "path") and user data fields (e.g., "password", "username")
- Records are identified by random unique IDs (not exposed to users)
- Each field is stored as a tuple:
[domain, field_name, field_value, modification_time] - The database keeps a complete modification history using UNIX timestamps
Example JSON Structure:
{
"version": 2,
"purpose": "primary",
"records": {
"a1b2c3d4e5f6": [
["meta", "path", "work/email/gmail", 1234567890],
["user", "username", "user@example.com", 1234567891],
["user", "password", "SecurePass123", 1234567892]
]
}
}
In this example:
versionmust be 2 (current format version)purposeis either "primary" or "sync_copy"recordscontains all password entries, keyed by random record IDs- Each field tuple has: domain ("meta" or "user"), field name, field value, and UNIX timestamp
Conflict Resolution:
- When databases from different devices are merged, field tuples are combined using set union
- The most recent modification (by timestamp) determines the current value for each field
- This enables automatic conflict-free merging across devices
File Locking:
- Primary database files use fcntl.lockf to prevent concurrent access
- A separate lock file ensures only one process can open the database at a time
Database Purposes:
primary: The main database file that can be directly opened and modifiedsync_copy: Read-only synchronization copies written to the shared folder for other devices to merge
Links
- Source Code: https://github.com/TobiasKaiser/passmate
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file passmate-0.4.1.tar.gz.
File metadata
- Download URL: passmate-0.4.1.tar.gz
- Upload date:
- Size: 40.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e5e52a2dc96338104858b327d66d05c417becd9e8da17799f1f6c7c7e887c74
|
|
| MD5 |
d8d0f9b7632b7b141768cb7ca756895d
|
|
| BLAKE2b-256 |
610b1b5f4b15303252c0e7f44696ec3c3b31b28c2ecf26b1ff9231fae4d7e5b3
|
File details
Details for the file passmate-0.4.1-py3-none-any.whl.
File metadata
- Download URL: passmate-0.4.1-py3-none-any.whl
- Upload date:
- Size: 32.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
99e23f25fcb2bf939424a820a474512aedeb1eab4f355ddf8698cd0517f64749
|
|
| MD5 |
4ea6d0a916b1358d212c8475be6a828f
|
|
| BLAKE2b-256 |
4732dfaacd7d7a51d855ca51b2b1635723b8631151cd8a981f9efb54f85f5154
|