Emacs-slack token with macOS Keychain

Problem to solve

As described by the developer. Emacs-slack is setup with a slack Auth token. There are of course a few ways of securing the token for it not to be accidentally either pushed to a public git repo or getting in the hands of somebody else in another way.

Well I use macOS and so far I have been very happy doing it. Same with the builtin keychains system that it uses. With all the iCloud syncing and other convenience solutions, I use it to store most of my passwords and credentials and forget about them.

So why not use it to store my slack token for emacs-slack as well!?

Solution

The macOS keychains system – beside the Keychain Access.app – has a CLI that I can leverage for this.

$ man security | head -n 5
security(1)               BSD General Commands Manual              security(1)

NAME
     security -- Command line interface to keychains and Security framework

Store the token in the Keychain

security add-generic-password -s keychain_item_name -a keychain_item_account_name -w

How to obtain the token is out of scope for this post, but it is described by the emacs-slack README.md file. Once you have the token, you need to save it into a keychain:

You ll get a secure prompt (twice) to fill in the token.

keychain_item_name & keychain_item_account_name are really arbitrary and can be chosen by you. The item can be accessed with the Keychain Access.app of course.

Retrieving the token

Getting back the stored token is as simple as:

security find-generic-password -s keychain_item_name -a keychain_item_account_name -w

One is then prompted for the macOS user password to be granted access. There is an option to always allow access for convenience too. The security suffers of course.

Putting it all together for the emacs-slack package

This code is almost 1 to 1 to the example given in the package README.md file except for the token settings.

(use-package slack
  :commands (slack-start)
  :init
  (setq slack-buffer-emojify t) ;; if you want to enable emoji, default nil
  (setq slack-prefer-current-team t)
  :config
  (slack-register-team
   :name "emacs-slack"
   :default t
   :token
   (substring
    (shell-command-to-string "security find-generic-password -s keychain_item_name -a keychain_item_account_name -w")
    0 -1)))