Password Management with "pass"


commit 7bc712f8955f9c1bde81a12f0c3d27b3c120d1fa
Author: Thomas Preissler <[email protected]>
Date:   Thu Aug 6 18:52:55 2015 +0100

    Add current contents of password store.

This is how it all started when I migrated from KeePass (keepassx on Linux to be precise) to pass. It was a good move, I am not looking back. Advantages I have gained:

  • Supports multiple devices - without using a cloudservice/website to store passwords
  • Good integration on desktop computers, tablets or mobile devices without risking the security of your passwords
  • Unique passwords for all my sites/accounts/logins (it seems I have 317 different ones right now)
  • Strong passwords (the majority are >20 characters long and absolutely random.)
  • I don't remember any passwords anymore - I simply can't.


This software is storing in PGP encrypted textfiles inside a folder structure of your choosing. The only requirement is that the first line in those files should be the password.



On Windows the client is called QtPass. It is a prerequisite to install Gpg4win as well.


On Android you can use Password Store. Its can only use PGP keys provided by OpenKeychain, APG is not supported (but you can export them from APG and import them into OpenKeychain).

PGP setup notes

PGP (and all the other incarnations) have many options, the important ones to be aware of are the following:

  • Use a strong 4096 bit RSA key
  • Use a dedicated key for your passwords/accounts/confidential data
  • Do not upload the key to a keyserver - please be careful with OpenKeychain, as this is ticked by default
  • Don't provide a comment on the key's use. Just your first name, surname and your regular email address.
  • PGP Key password strength: Really long, complicated and unique password. might be of help here.


The client here is called "pass", it should be in your preferred repository.


"pass" requires PGP. So you should setup it up securely as this site describes:

The .gnupg/gpg.conf should look like this:

# when outputting certificates, view user IDs distinctly from keys:
# long keyids are more collision-resistant than short keyids (it's trivial to make a key with any desired short keyid)
keyid-format 0xlong
# when multiple digests are supported by all recipients, choose the strongest one:
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
# preferences chosen for new keys should prioritize stronger algorithms:
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 BZIP2 ZLIB ZIP Uncompressed
# If you use a graphical environment (and even if you don't) you should be using an agent:
# (similar arguments as
# You should always know at a glance which User IDs gpg thinks are legitimately bound to the keys in your keyring:
verify-options show-uid-validity
list-options show-uid-validity
# when making an OpenPGP certification, use a stronger digest than the default SHA1:
cert-digest-algo SHA256
# prevent version string from appearing in your signatures/public keys

Then create a 4096 RSA key to be used by pass. Please choose a good password for the key. Remember: This password is the key to all your accounts.

Last but not least set the configured preferences with "gpg --edit-key FINGERPRINT // setpref // save" and you are ready to roll with "pass" by initializing the store.

If you need to migrate another password store, there are some migration tools on the "pass" website, have a look.

Full disclaimer: "pass" has the option to store everything inside a local Git repository. This has the benefit that you cannot loose any entries by accidentally deleting them. I used "pass" straightaway with Git. Its use of Git is transparent and won't get in the way when using "pass", Git is just used for keeping a log and historical records.

Integration into "awesome" windowmanager

Download pass_c

function get_password(path)
    -- we need to cut off the basedir and .gpg at the end
    local p = string.match( path, homepath .. "/*).gpg$" )
    naughty.notify( { title = "Password Store " .. p } )
    -- this command inserts the password directly, just waiting for enter
    awful.util.spawn(homepath .. "/bin/pass_c " .. p)
    -- thinking we might want to just insert into the clipboard
    -- or not. takes some getting used to, but is amazing

function password_store_dirtree(dir)
    local submenu = {} 

    for entry in lfs.dir(dir) do
        if entry ~= "." and entry ~= ".." and entry ~= ".git" and entry ~= ".gitattributes" and entry ~= ".gpg-id" then 
            entry = dir .. "/" .. entry
            local attr = lfs.attributes(entry)
            -- get the actual filename (basename) only
            local name = entry:match( "([^/]+)$" )
            if attr.mode == "directory" then 
                table.insert(submenu, { entry:match( "([^/]+)$" ), password_store_dirtree(entry) } )
                -- cut off the .gpg at the end
                table.insert(submenu, { name:match( "(.*).gpg$" ), function()
                end } )
            -- we need to sort the "table of tables" by its first element, which is in both cases the name
            table.sort(submenu, function(a, b)
                return a[1] < b[1] 

    return submenu

passwordstoremenu = password_store_dirtree(homepath .. "/.password-store")

mymainmenu = { items = { 
    { "Password Store", passwordstoremenu },
} } )

Alternative: Overlay menu with dmenu

dmenu is a dynamic menu for X. To display pass' entries, you can download

Integration into the "awesome" windowmanager can be done via

awful.key( { modkey }, "p",                  function() awful.util.spawn(homepath .. "/bin/my_passmenu --type") end, "Password Store"),

Multiple devices

To access your password store from different devices it is a prerequisite that it is stored inside a Git repository. Then just point your devices to this Git repository.

I was never happy with storing passwords in the "cloud"/internet. The solution for me was quite simple: Setup a Git server on a Raspberry Pi running Raspbian on the local LAN and all devices having Password-Store/pass installed just go there for updates.

Alternatively you could potentially also just use a Github/Gitlab repository. Review for yourself whether you need your password store publicly accessible, Gitlab for what I can tell does allow private repositories without an additional charge.

The beauty of "pass"

I personally like be simplicity of "pass". It just stores everything in PGP encrypted text files. Using Git transparently is really awesome, as you can setup replication over multiple devices super easy and quick. Git here also gives you the advantage that "pass" automatically generates a log and any changes can be fairly easy undone. The security just comes with it automatically, as you just replicate PGP encrypted textfiles.

Final considerations

Last but not least please be aware of the following items to use "pass" in a secure way:

  • PGP Key strength: Minimum 4096 bits, RSA keys.
  • PGP Key password strength: Really long, complicated and unique password. might be of help here.
  • Don't disclose usernames within your folder structure or entries in "pass".
  • Make sure you don't loose the PGP keypair, or you are stuffed.
Show Comments