As more of our lives move online, the number of passwords we need to manage keeps growing, and it quickly becomes impractical to rely on memory alone. This is especially because good passwords should have high entropy and be randomly generated, something that humans are not particularly good at. As a result, people often cope by creating weak passwords or reusing a single password across multiple services. Unfortunately, weak passwords make it feasible for attackers to crack the password directly, particularly in offline attacks where rate limiting does not apply, while password reuse enables attackers to take credentials leaked from one breach and apply them to other services in credential-stuffing attacks. (Reusing a strong password may still be preferable to using weak ones in some contexts, though.) Having an external system to keep track of credentials makes it far more practical to use unique, strong passwords for every service. This article evaluates different options for managing passwords and describes how I ended up using pass in the hope that it will be helpful for others. However, I am not a cybersecurity expert, and you should make your own decision about what best fits your needs based on your own research.
Before evaluating the various options, it is necessary to define a realistic threat model. A threat model identifies what you are trying to protect, what you are trying to protect it from, how severe the consequences would be if those protections fail and how much effort and inconvenience you are realistically willing to accept to reduce those risks. In this case, the assets to be protected are the credentials used to access online services that are integral to everyday life, such as email, cloud storage, social media, online shopping and financial services. These accounts may contain sensitive personal data, private communications or direct access to funds. Potential adversaries can be broadly categorized into opportunistic and targeted attackers. The former includes cybercriminals, who seek to steal money directly from linked from linked bank accounts or payment details, lock users out of their accounts or files to demand a ransom, harvest personal information to sell on illicit online marketplaces, impersonate victims to commit fraud or simply to wreak havoc for amusement. In contrast, the latter includes personally motivated attackers like stalkers, abusers or rivals seeking to cause direct physical or emotional harm to the victim or advanced actors who want to exploit an individual’s privileged access within an affiliated organization to infiltrate high-value targets.
The risk posed by different scenarios can be determined by weighing its impact against its likelihood. The consequences of a compromise can range from being unable to access essential services or files to losing your life savings or even having your identity stolen. Whilst almost everyone is susceptible to opportunistic attacks, the likelihood of facing a target attack depends on personal factors like your wealth, profession, political activity, public visibility and personal relationships. The are a number of attack vectors used by these groups to obtain to login credentials. In addition to the methods already discussed, these include social engineering, whether by phising or pretexting, malware placed on the user’s computer such as keyloggers, infostealers and rootkits, intercepting the password in use through wiretapping, man-in-the-middle attacks or shoulder surfing or straight-up theft of devices. Attackers may also exploit vulnerabilities in the service itself to bypass authentication entirely, although this is unfortunately mostly outside the user’s control. Apart from deliberate attacks by malicious actors, simply forgetting a password is incredibly common, potentially resulting in account lockout if the password reset process fails or does not exist.
Password managers offer a highly convenient way to use strong and unique passwords without relying on human memory, but they also concentrate multiple credentials in a single place. Consequently, a breach of the password manager itself or loss of access to it can jeopardize the security of the entire set of accounts. Even so, this is probably a worthwhile trade-off considering that weak or stolen passwords account for a large proportion of breaches. At the same time, a system for managing passwords must uphold the confidentiality, integrity and availability of the account credentials to be secure. This means that the system must prevent your passwords from falling into the wrong hands, ensure they have not been tampered with or corrupted and guarantee that you can always access them whenever you need to log in. Against this background, we can evaluate some of the available options.
One option is to write passwords down onto paper. Despite the widely circulated advice against writing down passwords, this approach may be sensible for some users in specific contexts. In comparison to other approaches, using pen and paper to store passwords is simple to understand and does not require any specialized tools or technical knowledge, which makes it more accessible to a wider range of users. This can take many forms, such as a notebook, index cards, a Rolodex or a PasswordCard that you keep with you in a wallet. Since paper records are kept entirely offline, the main risk arises from physical threats. This might happen, for example, due to a thief stealing the papers, a nosy housemate searching through your files or a visitor casually spotting a password accidentally left visible on your desk. Similarly, if you do not shred old pages before throwing them away when changing passwords, the discarded text can be recovered from the rubbish. Because it is highly impractical to manually encrypt handwritten text, these credentials exist in cleartext, meaning that if an adversary locates the papers, every account is immediately compromised. It is possible to add a pepper to each password before writing it down, so that the information recorded on paper alone is insufficient for authentication. The protection this provides, however, depends entirely on the strength of the unwritten secret, which must be reliably remembered by the user. Keeping the papers locked away when not in use can further reduce risk, but this could become inconvenient if credentials are needed frequently throughout the day.
Note that, even if the passwords are stored on paper, you still have to input the passwords onto the computer to use them. This means that even storing your passwords offline will not necessarily protect you against remote attacks. If you type your password into a fake phishing website or if your device is infected with malware like a keylogger or a remote access trojan, your account will still be hacked. Aside from the need to type passwords manually, paper-based storage introduces additional usability issues. As the number of accounts grows, locating the correct password becomes increasingly cumbersome. Misreading due to unclear handwriting or mistyping characters can cause repeated login failures, after which services may lock the account. There is also no built-in mechanism for generating strong random passwords, meaning that users must rely on an additional system, such as dice-generated passphrases or a web-hosted password generator. Over time, this added friction may cause users to adopt shorter or more predictable passwords, thereby undermining the main benefit of writing passwords down in the first place.
Moreover, it is essential to create regular backups of the credentials in the event that the original paper records are lost. You should have at least two backups with at least one of these stored off-site to mitigate risks affecting the on-site location, such as fire, flooding or other natural disasters. Unfortunately, backing up an analogue system is not as straightforward as a digital one, where copying can be performed quickly and easily. You must either manually transcribe each password individually, which is time-consuming and carries the risk of introducing errors, or place the papers into a copier one at a time. In the latter case, care must be taken if the scanner or copier is network-connected or stores intermediate digital copies, which may unintentionally expose credentials. Since keeping these backups up to date relies on high manual effort and sustained discipline, updates can easily drift out of sync, leading to unusable or missing data at the point of recovery.
The digital equivalent of the paper option is to keep secrets in a file on the computer. This approach has some precedent in existing Unix conventions such as the netrc file and Emacs’ authinfo file. Compared to paper, a local digital file is far more convenient to search, update and use frequently, but it is also susceptible to remote compromise, given that the machine is connected to the network. To prevent permanent loss of the credentials in the event of disk failure, system corruption or accidental deletion, the file must also be backed up properly. However, care must be taken to ensure that any copies are equally well protected as the original, since they all contain the same sensitive material. This is particular a concern if copies are synced to the cloud, as it expands the potential attack surface should the cloud service be breached.
When the file is kept locally on a trusted machine protected by disk encryption, exposure is limited in the event of device theft or loss while the computer is powered down. This protection is not absolute, however, as attacks such as cold boot attacks can in some circumstances recover encryption keys by extracting the contents of RAM shortly after an abrupt reboot or power loss. As an extra layer of protection, the file can be encrypted (for example, with GnuPG) to prevent other local processes and users on the same computer from trivially reading passwords from the file. Encrypting the file with a key stored on a security token is preferable to encrypting with a password alone, since the password could potentially be captured by a keylogger when typed, whereas the key material on the token is never exposed to the host system. These measures, however, only protect credentials at rest. Once a password is decrypted to be passed to a login interface, sophisticated malware may still be able to extract secrets at this stage through techniques such as keylogging, clipboard sniffing, session token theft or memory scraping.
Another option is the system credential store. This is conceptually similar to keeping them in a file, in that credentials are still stored locally in an encrypted database, but with tighter integration into the system. On Linux, this role is typically filled by the GNOME Keyring or KDE Wallet, whilst the Secret Service API provides a standardized interface through which applications can store and retrieve secrets (for example, the secret-tool command-line utility). An issue is that the keyring is typically unlocked automatically at login using the password for the user’s account, meaning that any process running under the same user account may be able to access stored secrets through D-Bus while the keyring remains unlocked for the session. You can set up another keyring with a separate password that will not be unlocked automatically. It is unfortunately not possible at the moment to use a security token to encrypt the keyring.
On Windows and macOS, similar functionality is provided by the Windows Credential Manager and Apple Keychain, respectively. Unless you have chosen to opt out, the passwords stored here will be synchronized to your Microsoft or Apple account by default, which increases the attack surface of the keyring. Although this is convenient, consider whether you really trust these companies to handle your passwords securely.
For logins to websites, the browser’s built-in password manager is very convenient, as it can automatically fill credentials. This also provides a limited degree of phishing resistance, since credentials are only auto-filled when the domain matches what is stored, provided the user is not then tricked into entering the password manually. Similar to the system keyring, the passwords are kept in an encrypted database. Unfortunately, the encryption keys are often kept right next to database with no password set by default, meaning that anyone or any program with access to the user profile files on disk can easily recover saved credentials. In Firefox, for example, the option to set a primary password needs to be enabled manually by the user. Most major browser vendors also offer the option to log in with an account to synchronize the passwords between devices. Whilst this means the passwords will be available across all devices logged into the account with the web browser, the same warning applies here as mentioned earlier. Not only does this create new attack vectors, it also makes you dependent on the security of the browser vendor’s infrastructure. Note as well that browsers can only store credentials for websites, since entries must be tied to a URL, which makes them unsuitable for storing other kinds of secrets.
There are no shortage of applications out there offering to manage your passwords for you. Cloud-based password managers store encrypted password databases on servers controlled by the provider and can be accessed through a client on any device. As already discussed, this model significantly increases the attack surface, as you are reliant not only on your own device security, but also on the vendor’s cloud infrastructure. In particular, if the server is compromised, attackers can exploit architectural flaws to bypass encryted database, allowing them to view or manipulate stored credentials. In many cases, these online password managers are themselves web applications and are therefore vulnerable to common web security issues such as cross-site scripting (XSS), cross-stie request forgery (CSRF), insecure JavaScript design patterns and phishing attacks. Moreover, unlike the browser’s built-in password manager, browser extensions used by password managers need to run trusted user interface elements injected into potentially hostile websites and communicate with the password manager backend using web APIs. These can be abused by malicious websites to steal or modify credentials even when the database is encrypted. Furthermore, like all web services, password managers using cloud storage are susceptible to outages or service disruptions, which could leave you temporarily unable to access your passwords when you need them.
In contrast, other password managers store the passwords locally in an encrypted database (often called the password vault), accessed through a piece of software that must be installed on the user’s machine. Logic errors in the software can result in vulnerabilities that leak secrets, meaning that you need to trust the vendor to implement the software correctly. This is unfortunately not always the case. Password manager clients are especially attractive targets for supply-chain attacks due to the valuable secrets they contain; if an attacker compromises the build process, software dependencies or update infrastructure, malicious code can be distributed directly to users, as illustrated by the XZ Utils backdoor incident. Without built-in syncing capabilities, users are responsible for copying the password database between multiple devices and resolving any conflicts due to concurrent changes. Improper access or merging can corrupt the password database, making reliable backups essential, as with all password management approaches discussed previously.
A popular cross-platform password manager that operates entirely offline is KeePassXC. It is open-source, meaning that the source code of the software is available for you and others to review, and has undergone a third-party security audit. Since it uses the standard KeePass database format KDBX, it is interoperable with other tools that share this format. KeePassXC is primarily designed to be used through its graphical user interface, which allows you to create, modify and view entries the password vault. A typical workflow involves launching the application once logged into the computer and leaving the password manager window open for extended periods, ideally locking the database when not in use. While KeePassXC provides a command-line interface, it is somewhat clunky to use and not intended as a full replacement for the GUI. The application also supports autofill for websites via its browser extension (though note the problems with browser extensions mentioned above).
To support a broad user base, KeePassXC includes extra functionality other than simple password storage such as password generation, time-based one-time passwords (TOTP), passkeys, file attachments, favicon downloads, Secret Service integration, SSH agent integration, auto-typing, password diagnosis and password sharing. While these features improve usability, they also increase code complexity. There is also no simple way to remove these features without compiling the application from source with certain build options. One particularly useful security feature is support for unlocking the password database using a security token, such as a YubiKey, which you should consider to further protect the database against compromise.
The software pass, which bills itself as the standard Unix password manager, stores each secret as a separate GPG-encrypted file inside a simple directory tree and is built on top of existing Unix tools. In contrast to password managers that keep all credentials in a single encrypted database file, this design allows passwords to be decrypted independently, reducing the amount of sensitive data that must be present in memory at any one time. Additionally, it can be set up to integrate with Git, which can be used to version passwords and to easily distribute these among multiple machines. (Again, be careful of the additional attack surface introduced by storing the passwords on a server exposed to the Internet.)
A drawback of this approach is that metadata may remain unencrypted, since the file name and directory structure can leak sensitive information such as service names or usernames, even when the passwords themselves are encrypted. This can be mitigated by placing the password store inside an additional encrypted container using tools like LUKS, VeraCrypt or CryFS. If you do decide to push the password store to a remote Git repository, git-remote-gcrypt can encrypt the repository contents before they are stored on the remote, reducing metadata exposure to the hosting provider.
Since the software mostly consists of a short bash script with less
than 1000 lines of code, it is quite straightforward to understand.
The simplicity is achieved by outsourcing the cryptographic work to
GnuPG, which is a widely used and mature piece of software that has
been around since 1997. This design also enables the use of security
tokens for key storage and encryption. It exposes a well-designed and
well-documented command-line interface and can be extended through
Bash scripts, allowing integration with other tools and workflows.
For example, it can be combined with a dynamic menu such as dmenu so
that passwords can be retrieved from within the window manager.
Browserpass is a browser extension that connects to pass and can
autofill on websites. However, the security concerns associated with
browser extensions described earlier still apply.
Because of its simplicity and extensibility, this is the software that
I am using to manage passwords at the moment. The default location
for the password store is $HOME/.password-store/, which I organize
into a small number of categories based on the type and scope of the
secret as follows.
~/.password-store/
auth/
local/
remote/
crypt/
disk/
file/
memo/
otpauth/
The auth/ directory contains authentication credentials for user
accounts. It is subdivided into local/ and remote/ to distinguish
credentials for systems under my direct control (e.g., user accounts,
self-hosted services or internal infrastructure) from credentials used
to authenticate against external services. Its internal structure
follows the conventions expected by Emacs auth-source library, where
the hostname each service is represented by a directory and individual
account entries are stored as separate files named after the
corresponding username. (The reason for choosing this over encoding
the username as a prefix before the hostname is to make tab completion
easier.) The crypt/ directory stores passphrases used to protect
encrypted data rather than logins. The disk/ sub-directory contains
passphrases for full-disk or block-device encryption, while file/
contains passwords used for file- or container-level encryption (e.g.,
encrypted archives or individually encrypted files). The memo/
directory is used for miscellaneous secrets and sensitive notes that
do not naturally fit anywhere else. Finally, the otpauth/ directory
contains shared secrets used for TOTPs. These entries are structured
separately because they function differently from static passwords.
The handling and security implications of TOTP secrets are discussed
in the next section.
This layout also allows the passwords to be nested arbitrarily deep, which makes it possible to group related services from the same provider under a common parent, as in the following example.
~/.password-store/
auth/remote/
example.com/
ftp.example.com/
admin
login.example.com/
alice
bob
mail.example.com/
alice@example.com
The actual content of each entry in the password store follows the
format recommended by the author of pass. The first line contains the
secret itself, allowing it to be copied easily using the --clip
option. The remainder of the file consists of structured metadata
encoded as simple key–value pairs, following the conventions used by
GNU recutils. This makes it possible to process the metadata
programmatically by removing the first line and operating on the
remainder as a recfile. For web-based logins, each entry includes at
minimum a Url field containing a direct link to the login page.
When logging in, I always navigate using this stored URL and never
follow links from emails or messages, which helps reduce the risk of
phishing by ensuring that credentials are only entered on known and
verified web pages. See the following for an example.
correct-horse-battery-staple Url: https://login.example.com/signin Id: 123456 Email: alice@example.com Note: Main web login for example.com services.
To generate passwords, I use pwgen with the command pwgen -s 6 3,
which produces three random alphanumeric strings of length six. I
then join them with hyphens. This format is inspired by the one used
by Apple for automatically generated passwords. Restricting the
character set to alphanumeric characters plus hyphens makes the result
easier to read and manually type when necessary and satisfies the
password requirements on most sites. From a security perspective,
password length matters far more than character complexity. The
choice of password length is because many websites impose maximum
password length limits around 20 characters due to technical
constraints. Using three segments of six randomly generated
alphanumeric characters yields 18 characters drawn from an alphabet of
62 symbols, which corresponds to approximately 107 bits of entropy.
Nowadays, many websites offer or even require multi-factor authentication, where authentication relies on a combination of factors commonly categorized as something you know, something you have and something you are. When correctly implemented, MFA mitigates several common attacks involving a compromised password alone, including brute-force and credential-stuffing attacks, by ensuring that the password is insufficient for successful authentication. However, SMS-based MFA can be targeted by SIM swapping (although it is still better than no MFA), and all MFA processes depending on a shared secret between the client and server are vulnerable to phishing, since a malicious site can simply immediately relay both factors to the legitimate service. Out of the current MFA methods, only passkeys provides protection against phising, which we will talk about more in the next section. TOTP is another MFA method defined in RFC 6238, which requires inputting a short numeric code derived from a shared secret and the current time, usually in 30-second intervals. The short-lived time window in which the code is valid provides limited resistance against replay attacks and impractical to brute force.
In principle, TOTP primarily protects largely against the same threats as a password manager. When strong, unique passwords are already generated and stored securely, the extra security benefit of TOTP is marginal. Nevertheless, in specific scenarios where the attacker could not authenticate in real-time, such as shoulder surfing or harvested credentials meant to be attempted later, would make the TOTP unusable and stop the attack. Note that activating MFA now means that the other factors now become necessary to log into the account, and that customer service may not necessarily be able to help you recover your account in the event of loss of the additional factors.
Since many password managers also function as TOTP authenticator applications, a frequently asked question is whether to store the TOTP secret in the password manger alongside the corresponding credentials. The common argument against this is that puting both the TOTP code and the password in the same place does not create two separate factors and increases the concentration risk, such that a breach of the password manager would result in a compromise of both. However, this risk is less clear-cut in practice, as an attacker that is capable of compromising your password store likely has other means to access your accounts, such as by installing a keylogger or hijacking your browser session. On the other hand, there is a serious risk of being locked out due to losing the device on which TOTP is stored. Keeping the TOTP secret in the password manager makes it more convenient to use and to back up, and is still preferrable to not using TOTP at all.
For pass, the extension pass-otp provides additional sub-commands for inserting an OTP secret, generating a six-digit code and copying it to the clipboard. The secret is stored as an otpauth URI either in a separate file or together with the corresponding password.
Recently, more and more websites are beginning to support passkeys, which use asymmetric cryptography rather than shared secrets. In this model, the user’s device generates a key pair, where the public key is registered with the server and the private key is stored locally inside an authenticator, which can be either a platform-based credential manager integrated into the operating system, a password manager application or a security key. Unlike passwords and OTPs, passkeys are also designed to be resistant to phishing. This is because logging in with a passkey requires signing a server-generated challenge with the private key, and the browser only allows this for the website where the passkey was originally registered.
Many websites present passkeys as an alternative authentication option alongside the traditional username and password rather than as an additional factor. After initially registering the passkey, you can choose to log into the account with it. Depending on the type of authenticator in use, the authenticator will confirm require a verification step such as a PIN, tap or biometrics. This could reduce the cognitive burden associated with authentication on websites, since you no longer need to create, remember and type passwords and instead delegate the login process to the authenticator. That is, if everything works as intended. As a fairly new technology, different websites and authenticators handle the process inconsistently or can have technical issues that prevent successful authentication.
Nonetheless, it should also be considered that password managers already automate much of the login process and can mitigate the risk of phishing when autofill is available or when the login portal is accessed through the URL field in a stored entry. One notable benefit of passkeys stored on a security key is that they can be used across different machines without needing a local copy of a password database, making them more portable in environments where you cannot install or synchronize a password manager. However, passkeys are primarily designed for authentication in web applications using the Web Authentication API. This means that in practice you will still need to manage passwords that are not for web applications or for web applications that do not yet support the interface.
Whilst passkeys are for the most part quite seamless to use, backup and recovery still remains a weak point. Since the private key is normally tied to a single device, losing that device means losing access to the account, unless you have an alternative login or recovery method. You could register multiple passkeys for each account, but this then means purchasing and safeguarding multiple security tokens, which can become burdensome. This issue has led to the adoption of synced passkeys, where the passkeys are automatically replicated across a user’s devices through an account with a platform provider. Whilst this improves the situation somewhat in that you could use any logged-in device for recovery, it also means the passkeys are no longer strictly device-bound, allowing an attacker to either copy them from a compromised device or obtain them by compromising the cloud infrastructure. This exposes a larger attack surface and shifts the trust onto the platform provider to protect the passkeys properly. Moreover, transferring passkeys between authenticators is not always straightforward, and in some cases you may need to register new passkeys across multiple services to do this. This increases switching costs and contributes to vendor lock-in within the provider’s walled garden.
Out of the options evaluated, I would avoid a cloud-based password manager and not fall for the marketing claims of “military-grade security”. The large attack surface resulting from keeping the passwords stored online, combined with the fact that these companies are likely to be attractive targets for attackers, simply makes it a matter of time before there is a breach, which you may not even learn about until it is too late. Despite being frequently dismissed, I do think that a paper-based solution is a reasonable choice for those without the technical skills to manage their passwords digitally, so long as the papers are stored away in a safe location and a salt is added to prevent immediate compromise of the passwords if they are stolen. One could argue that such users would not be using a computer anyways, but in today’s world where more and more daily administration tasks are moving online, most people will inevitable have at least a few online accounts.
I also think that the browser’s in-built password manager is another option if all you need to store are logins for websites, given that you set a primary password. If you need more functionality, the application KeePassXC has a good track-record, but you may want to consider whether the convenience afforded by the browser extension is worth the additional risks it entails. Finally, for technically savvy computer users who are willing to take a more hands-on approach to managing their passwords, storing passwords in one or more encrypted files is a simple way to keep these protected whilst remaining practical to use. For convenience, the pass program provides a nice command-line interface to access these encrypted files.
In the end, each approach comes with its own trade-offs. You may want to consider a mixture of approaches, depending on your threat model: for example, memorizing your online banking password and saving a few unimportant accounts (each with their own unique password, of course) within the browser for convenient access, whilst storing the rest in a dedicated password manager application. Where supported, passkeys can be used for more sensitive accounts with a fallback method, since they are convenient to use and mitigate phishing risks.
As for myself, I use the Nitro Passkey to manage passkeys, as both the hardware and the firmware are Open Source, as well as pass for storing passwords and OTP codes. I find this setup fits my requirements well.