13 releases
new 0.6.1 | Dec 24, 2024 |
---|---|
0.6.0 | Nov 27, 2024 |
0.5.1 | Apr 29, 2024 |
0.5.0 | Feb 14, 2024 |
0.1.1 | Sep 20, 2021 |
#68 in Cryptography
272 downloads per month
200KB
10K
SLoC
Introduction
Napa is a simple command line password manager written in Rust. Napa should be considered beta-level: it should not be used to store any actual passwords, and the database format may change in the future. At the moment Napa is Linux-only and requires Wayland for clipboard support. Patches for other FOSS operating systems are welcome.
Installation
Statically-linked binaries are published on the releases page.[^1] Alternatively, if you have a Rust toolchain you can build from source using RUSTFLAGS='-C target-cpu=native' cargo install napa
. (Native CPU makes Argon2 run faster.)
Motivation
The most popular command line password manager today is probably pass, which I used happily for several years. However, pass uses GPG to encrypt its secrets, which requires the song-and-dance of maintaining a GPG key just to access your passwords. GPG is also bad, and its aging cryptography means that pass is vulnerable to the database attacks described here. Pass also gives arbitrary programs read/write access to your passwords once your GPG key is unlocked, which made me increasingly nervous in today's age of typosquatting. Thus was born Napa, a much simpler password manager with stronger cryptography for when you don't completely trust your local computer.
Design Goals
In reaction to the enormous complexity of GPG, Napa was designed with the goal of "radical simplicity". I am happy to report that Napa has no configurable user settings. In particular,
- There is no user selection of cryptographic algorithms or parameters; a single secure default is chosen, and if necessary that will be updated in the future with a version number bump.
- There is no user choice of passphrase for the database file. Humans have a terrible habit of reusing passwords (including yours truly), and so the main passphrase is securely generated for you.
Usage
A new database can be initialized using napa init
. This will generate a six word passphrase from the EFF long word list. Remember this passphrase, since it won't be displayed again.
$ napa init my-passwords.napa
The new passphrase for this database file is: creme-customer-squad-persuader-wise-purveyor
Remember this passphrase! It will not be displayed again.
After initialization, the database file can be unlocked using napa open
. This will cache the decryption key in memory and drop you into a REPL-like interface for managing the password entries.
$ napa open my-passwords.napa
Enter the passphrase:
> edit example-entry
# this will open the entry in a built-in editor
The name of each password entry can be arbitrary text, which allows you to group the passwords however you like. Password entries can also contain arbitrary text and have no pre-defined layout. The only exception is for lines starting with the special domain:
, username:
, and password:
prefixes. When present, these prefixes are used when generating a new password or copying it to the clipboard. For example:
domain: www.example.com, www.example.co.uk
username: my-username
password: my-awesome-password
Any extra information down here.
Passwords for websites can be copied to the clipboard using clip <URL>
, e.g. clip https://www.example.com/login
.[^2] To prevent phishing attacks, the domain in the URL must be an exact match for one of the listed domains in the password entry. If you have multiple accounts on the same website, you can also pass an optional username to the end of clip
to find the right entry.
New passwords for accounts can be generated using gen <entry-name>
. By default, this will overwrite the password:
line with a new 25 character password. The length and character set used for the password can be changed if desired, e.g. gen example-entry 10 alnum
.
If you ever accidentally overwrote a password you didn't mean to, log
will show you the history.
Other useful commands include:
list
will list entry namesshow
will print an entry to the terminalmove
will rename an entrydel
will delete an entry and all its history
The complete set of available commands can be seen by running help
in the REPL. Each command also has documentation that can be accessed, e.g. help gen
.
Finally, the passphrase to the database file can be changed with the napa pass
command. This will generate a new passphrase.
$ napa pass my-passwords.napa
Enter the passphrase:
Your new passphrase for this database file is: penalty-cement-legacy-surface-symphonic-confound
Remember this passphrase! It will not be displayed again.
Security
The Napa database file is designed to be immune to specific attacks described in the database document. Once the database is unlocked, Napa makes a best-effort attempt to avoid exposing secret material to any external process. For example, all memory allocated during the program is zeroed on deallocation. Secret information can only be accessed by the rest of the system when copying to the clipboard (somewhat unavoidable, but the clipboard is automatically cleared after a 30 second timeout).
When possible, Napa should be compiled as a statically-linked binary to prevent LD_PRELOAD attacks. Of course, this won't extend to the rest of your system (such as your terminal emulator), so it is recommended to use a sandbox (like Flatpak or Snap) and a mandatory access control system such as SELinux or AppArmor.
Commits and tags that I author are signed with my SSH key. After configuring the key, they can be verified using git verify-commit
and git verify-tag
. Commits prior to 2023-07-01 were signed with my GPG key, but that key has expired and is no longer used.
License
Napa is licensed under the MPL2.
Credits
Napa took inspiration from several other cryptographic programs, including:
[^1]: Each release is built inside a SourceHut build environment, and the authenticity of the binary can be checked by calculating the b2sum
and comparing it to the linked build page.
[^2]: In your browser use Ctrl L to copy the URL, Ctrl Shift V to paste it into Napa, and then Ctrl V to paste the password.
Dependencies
~20–50MB
~801K SLoC