User authentication

User authentication is among common awkward things about computing: there's a lot of incompatible methods, and every user has to deal with those.

There is plenty of APIs (PAM, SASL, LDAP, GSSAPI, etc), specialised protocols (Kerberos, RADIUS, SRP, etc), protocols that can be used for that (SSH, TLS, IPsec, etc), occasional additional authentication (sudo), various protocol-specific ones, and people keep making custom ones (that's most popular on the web, I guess). It's nice that there is a choice, and a vulnerability in one protocol (or in its commonly used implementation) wouldn't compromise about everything, but it's also quite a mess.

Users can't remember and enter all the passwords all the time (be that for password-based authentication or for encrypted keys), so for them there are netrc and secret service API, with the former taking bits of private data for search (as does that newer pass thing), and the latter being another bloated and awkward dbus-based freedesktop project. There also are ssh-agent and gpg-agent, just encrypted (or plain text in many cases, I guess) files, various password managers (which may or may not use the standard methods), plan 9's factotum, and poor wheel reinvention for websites (in-browser password managers, web-based ones, cookies, etc).

This is without counting distributed systems, access delegation, multi-factor authentication, and use of multiple devices with synchronisation of credentials between them.

Choosing key-based authentication over password-based one whenever possible should be helpful, but in practice it doesn't seem to help that much even for personal use and when you control both server and client: even when protocols support that, software doesn't, or at least it's rather painful to set.

Threat model

The Internet Threat Model (RFC 3552) is implied here, as usual for Internet protocols: the adversaries are scammers/businesses/governments, they can have near complete access to everything but endpoints, and we don't want any of their attacks to be successful.

SCRAM-based and SSH-based authentication

It is generally safer to not have plaintext passwords on a server (not even in memory), and for that there is SCRAM with passwords stored in a hashing scheme specific to an authentication mechanism. For email, it's pretty easy to set with a regular dovecot + postfix setup (where postfix uses dovecot's SASL), similar to dovecot's CRAM-MD5 HowTo. Password database file owner should be set to dovecot, userdb should be set, and hashes could be generated with doveadm pw -s scram-sha-1. E.g.:

auth_mechanisms = scram-sha-1

passdb {
  driver = passwd-file
  args = scheme=scram-sha-1 /etc/dovecot/scram-sha-1.pwd

userdb {
  driver = passwd

But the best emacs's smtpmail library can do is CRAM-MD5, so there's that, or using a local MTA for this, or perhaps hacking smtpmail.el to use sasl.el. In general, as mentioned above, software support for these things is incomplete and awkward. Here's a bit of configuration that I've added into the default postfix configuration on CentOS to relay messages through a remote server (though a password is stored in plain text locally with this setup):

smtp_sasl_auth_enable = yes
smtp_tls_security_level = encrypt
smtp_sasl_tls_security_options = noanonymous
relayhost = []
# Alternative form:
# relayhost = [mail.isp.example]:submission
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

And mbsync supports SCRAM-SHA-1 on its own.

Though a better approach may be to just use doveadm-sync, synchronizing mail over SSH; it appears to drop the SSH_AUTH_SOCK environment variable (used by ssh-agent) here, but here's a workaround:

doveadm sync sh "SSH_AUTH_SOCK=$SSH_AUTH_SOCK ssh doveadm dsync-server"

Sending can be organized in a similar way (e.g., ssh host sendmail instead of sendmail), eliminating all the mail-specific authentication. See the Email note for more precise instructions.

Smart cards

Smart cards seem handy and secure for key-based authentication (when it's available), though the situation with ECDSA support there is unclear, as well as the standards themselves. While OpenPGP includes ECDSA since 2012, and SSH includes ECDSA since 2011, apparently some smart cards (e.g., Yubikey, the website of which is not very informative, or the technical information is just well-hidden there) don't handle it. As GnuPG's source code suggests and doc/gnupg-card-architecture.pdf pictures, software talks to USB smart cards via CCID (see CCID specification), with ISO/IEC 7816 on top of it. The cryptographic functions seem to be defined in ISO/IEC 7816 part 8, but it costs $165 (+ time and risks of dealing with purchasing on their semi-broken website), with no publically available copies in sight, so I didn't check further. Paywalled standards are frustrating.


Biometrics have an advantage of being easy to use, with no need to remember or carry anything. But the biometrics issues outweigh that in most cases.

HTTP authentication

Basic access authentication is indeed very basic, but simple and usable with TLS. Yet most of the time web developers (or their clients) feel like they should reinvent it in order to be able to reinvent the UI, so they make something comparable, but custom (hence not supported by generic HTTP clients), turning the OSI layers inside out even further. The attempts to add custom key-based authentication were ugly, but now there is a W3 web authentication standard, which is just a JS API to work with authenticators and doesn't have much to do with HTTP authentication, or with interlinked hypertext documents.

It's a trainwreck stretched out for decades; doesn't seem like there will be proper HTTP authentication anytime soon.