Storing Secrets

In my never ending crusade to move as many functions as possible into Emacs, I’ve lately been dealing with functions that require a user name and password. For example, part of the mbsync configuration that downloads my emails requires a user name and password. Similarly, org2blog/wp needs the password for my blog.

Here at Irreal, we’ve settled on two strategies:

  • Putting the credentials in the .authinfo file
    This method has the benefit that you can get at the credentials with Elisp. This makes it easy to make passwords and other credentials available to your Emacs configuration without having them displayed in plain text. Take a look at the auth-source info documentation and auth-source.el to see what’s available. Sadly not all the functions are documented so you may have to look at the code. See the Blogging section of Arjen Wiersma’s configuration for an example of using the auth-source package with org2blog/wp.
  • Putting credentials in the macOS keychain
    Obviously, this is Mac specific but the other OS’s have similar functionality. This method is useful when you need to get at the credentials from outside Emacs. For example, my mbsync configuration retrieves the password for the Apple IMAP server from the Mac keychain because Elisp isn’t available to mbsync. Aria Fallah has an excellent post on how to access the Mac keychain. If you’re running on macOS, you need to give it a read.

Lately, I’ve been working on bringing Gmail under the mu4e umbrella. Gmail really wants you to use OAuth2 to authenticate and they make it pretty easy to set up an account to get the tokens but it’s really hard to see how to integrate it into mbsync. There’s some python code on the Web that I think I can have mbsync call to do the OAuth2 but as far as I can tell, most mbsync users simply turn off the OAuth2 authentication to get things working.

That’s not ideal but isn’t a worry for me because I use Gmail only for mailing lists. Still, it would be nice to find a reasonable solution using OAuth2.

This entry was posted in General and tagged , , . Bookmark the permalink.
  • I run a lot of mail accounts through legacy google apps accounts (remember when they were free?). I'm using mbsync and mu4e for all of them. I had no luck until I turned off 2-factor authentication on the accounts. I think it has something to do with the app keys that you need to use instead of a user-name and login when 2-factor is turned on. I've tried generating keys, but mbsync and before that fetchmail choked on them. They were expecting traditional user name and login.

    I would love to go back to using 2-factor again, but haven't found a solution. If you find one, please post!

  • I use `pass` to store my passwords. Emacs integrates nicely with this with a couple packages. mbsync can also use this to retrieve passwords.

  • Damien Cassou

    I also use `pass` which has a backend for auth-source (https://github.com/DamienCassou/auth-password-store, now part of Emacs 26) as well as a major mode (https://petton.fr/git/nico/pass). All my applications inside Emacs (magit, notmuch, jabber, ...) and outside Emacs (firefox, offlineimap, sudo, vdirsyncer, ...) use pass too (even on my mobile phone). I highly recommend this setup.

  • Arjen Wiersma

    Just to chime in... it is one of the issues with how we have
    developed systems in the past, there is not a really uniform way to deal with credentials (although I started adopting pass last week as well).

    I myself have started using a system centered around GPG on my
    machines, it is portable across all platforms. I will write about it when I have some more time, but for now let me show an excerpt:

    On a linux machine the .authinfo (cleartext) is the standard. You can
    easily encrypt this file with GPG and edit it from emacs (more later). The contents of the file is something like this:


    .authinfo.gpg
    machine buildfunthings.com login someuser password somepass

    In emacs, enable epa-file, which comes in as a dependency in my config.


    (require 'epa-file)
    (epa-file-enable)

    Now you can use this savely stored file as a source for logins,
    whenever emacs reads a gpg file it will automatically decrypt it for you using your passphrase. The section would become something like this, note the expand-file-name and then the auth-source-user-and-password function.


    (let (credentials)
    (add-to-list 'auth-sources (expand-file-name "~/.authinfo.gpg"))
    (setq credentials (auth-source-user-and-password
    "buildfunthings.com"))
    (setq org2blog/wp-blog-alist
    `((.....
    :username ,(car credentials)
    :password ,(cadr credentials))))))

    Obviously this would break other tools, like offlineimap. For this I
    have this helper piece of code that makes it work as within Emacs:


    Python code:
    #!/usr/bin/python
    import re, os

    def get_password_emacs(machine, login, port):
    s = "machine %s login %s port %s password ([^ ]*)n" % (machine,
    login, port)
    p = re.compile(s)
    authinfo = os.popen("gpg -q --no-tty -d ~/.authinfo.gpg").read()
    return p.search(authinfo).group(1)

    In my offlineimaprc file I call this in the following construct:


    remotepasseval = get_password_emacs("www.buildfunthings.com",
    "someuser", "993")

    Hope this helps! I will ping back to you when I have written fully
    about my system.