├── .gitignore ├── docs ├── source │ ├── license.rst │ ├── images │ │ ├── decrypt.png │ │ └── encrypt.png │ ├── support.rst │ ├── background.rst │ ├── index.rst │ ├── installation.rst │ ├── usage.rst │ ├── tutorial.rst │ └── conf.py └── Makefile ├── README.rst ├── LICENSE └── keybase.bash /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | docs/build 3 | -------------------------------------------------------------------------------- /docs/source/license.rst: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | .. include:: ../../LICENSE 5 | 6 | -------------------------------------------------------------------------------- /docs/source/images/decrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbauhardt/pass-keybase/HEAD/docs/source/images/decrypt.png -------------------------------------------------------------------------------- /docs/source/images/encrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbauhardt/pass-keybase/HEAD/docs/source/images/encrypt.png -------------------------------------------------------------------------------- /docs/source/support.rst: -------------------------------------------------------------------------------- 1 | Contact & Support 2 | ================= 3 | 4 | - You can create issues / ask questions / starting conversation directly on the Github_ 5 | 6 | .. _Github: https://github.com/mbauhardt/pass-keybase/issues 7 | 8 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = source 8 | BUILDDIR = build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/source/background.rst: -------------------------------------------------------------------------------- 1 | 2 | Background / Why do I need this pass extension 3 | ============================================== 4 | 5 | The idea behind this project is to have an encrypted backup of my gpg container maintained with pass. 6 | One question could be why would I like to have a backup? 7 | Here are some reasons why I want to have a backup of my gpg-encrypted passwords. 8 | 9 | - It happened to me that I went to the office and I forget my yubikey. So I was not able to decrypt any of my passwords. 10 | No email, no irc, no webbased logins, no git usage or ssh logins at this time. 11 | - It happened to me that I type in a wrong password 3 times in a row for my yubikey. 12 | So my yubikey was locked and I hadn't my admin/reset pin with me. 13 | - Sometimes I'm to lazy to standup go to my physical keyring to grab my yubikey. 14 | In such moment it would be nice to decrypt a password without my gpg key. 15 | 16 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | pass-keybase 2 | ============ 3 | 4 | - Documentation_ 5 | 6 | *pass-keybase* is a pass_ extension to create an encrypted backup of all your existing gpg encypted passwords. 7 | Under the hood keybase_ is used to encrypt the backup. 8 | 9 | The version control functionality (via git) of pass will also be supported by this extension. 10 | In other words, keybase encrypted passwords will be commited to your git repo. 11 | 12 | .. _pass: https://www.passwordstore.org/ 13 | .. _keybase: https://keybase.io/ 14 | .. _Documentation: https://pass-keybase.readthedocs.io/ 15 | 16 | Encrypt one or all password 17 | 18 | .. image:: https://pass-keybase.readthedocs.io/en/latest/_images/encrypt.png 19 | 20 | Decrypt a password 21 | 22 | .. image:: https://pass-keybase.readthedocs.io/en/latest/_images/decrypt.png 23 | 24 | There are several more commands, e.g. reporting to figure out if your 25 | GPG and Keybase keychain is in sync. 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Marko Bauhardt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. pass-keybase documentation master file, created by 2 | sphinx-quickstart on Mon Jan 7 21:58:29 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to pass-keybase's documentation! 7 | ======================================== 8 | 9 | *pass-keybase* is a pass_ extension to create an encrypted backup of all your existing gpg encypted passwords. 10 | Under the hood keybase_ is used to encrypt the backup. 11 | 12 | The version control functionality (via git) of pass will also be supported by this extension. 13 | In other words, keybase encrypted passwords will be commited to your git repo. 14 | 15 | .. _pass: https://www.passwordstore.org/ 16 | .. _keybase: https://keybase.io/ 17 | 18 | Encrypt one or all password 19 | 20 | .. image:: /images/encrypt.png 21 | 22 | Decrypt a password 23 | 24 | .. image:: /images/decrypt.png 25 | 26 | There are several more commands, e.g. reporting to figure out if your 27 | GPG and Keybase keychain is in sync. 28 | 29 | 30 | .. toctree:: 31 | :caption: Users 32 | :maxdepth: 2 33 | 34 | background 35 | tutorial 36 | usage 37 | installation 38 | 39 | .. toctree:: 40 | :caption: General 41 | :maxdepth: 2 42 | 43 | support 44 | license 45 | -------------------------------------------------------------------------------- /docs/source/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | You have to enable the extension support for pass by exporting the following variable. 5 | 6 | :: 7 | 8 | export PASSWORD_STORE_ENABLE_EXTENSIONS=true 9 | 10 | Copy the script `keybase.bash` to your extension directory. 11 | 12 | Quick and Dirty 13 | --------------- 14 | 15 | *via curl* 16 | 17 | :: 18 | 19 | mkdir ~/.password-store/.extensions 20 | cd ~/.password-store/.extensions 21 | curl -fsSL https://raw.githubusercontent.com/mbauhardt/pass-keybase/master/keybase.bash -o keybase.bash 22 | chmod u+x keybase.bash 23 | 24 | *via wget* 25 | 26 | :: 27 | 28 | mkdir ~/.password-store/.extensions 29 | cd ~/.password-store/.extensions 30 | wget https://raw.githubusercontent.com/mbauhardt/pass-keybase/master/keybase.bash -O 31 | chmod u+x keybase.bash 32 | 33 | The recommended way 34 | ------------------- 35 | 36 | *via git submodule* 37 | 38 | Install pass-keybase as submodule 39 | 40 | :: 41 | 42 | mkdir ~/.password-store/.extensions 43 | cd ~/.password-store/.extensions 44 | git submodule add git@github.com:mbauhardt/pass-keybase.git pass-keybase 45 | ln -s pass-keybase/keybase.bash keybase.bash 46 | 47 | Commit and push the submodule to your existing git repo 48 | 49 | :: 50 | 51 | cd ~/.password-store 52 | git add .extensions/pass-keybase 53 | git add .gitmodules 54 | git add .extensions/keybase.bash 55 | git commit -m 'added submodule pass-keybase' 56 | 57 | Update to the latest version 58 | 59 | :: 60 | 61 | cd ~/.password-store/ 62 | git submodule update --remote 63 | 64 | -------------------------------------------------------------------------------- /docs/source/usage.rst: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | The `help` command shows all the available commands. 5 | 6 | :: 7 | 8 | pass keybase help 9 | 10 | The `version` command shows the version of the program. 11 | 12 | :: 13 | 14 | pass keybase version 15 | 16 | The `init` command initialize the program. This must be called before the program can be used. 17 | `keybase-id...` is a space separated list of keybase usernames which will be used to encrypt or decrypt passwords. 18 | 19 | :: 20 | 21 | pass keybase init keybase-id... 22 | 23 | The `encrypt` command can be use to decrypt the given `pass-name` via gpg and pipe it to keybase to encrypt it under the same path but with extension '.keybase'. 24 | 25 | :: 26 | 27 | pass keybase encrypt pass-name 28 | 29 | `encrypt-all` is there to make a keybase encrypted backup of all your gpg encrypted passwords. 30 | 31 | :: 32 | 33 | pass keybase encrypt-all 34 | 35 | Use the `decrypt` command to decrypt a given pass-name 36 | 37 | :: 38 | 39 | pass keybase decrypt pass-name 40 | 41 | It is also possible to decrypt a password file and put the first line on the clipboard. 42 | The clipboard will be cleared in $CLIP_TIME seconds. 43 | 44 | :: 45 | 46 | pass keybase clip pass-name 47 | 48 | To remove a given pass-name use the command described below. 49 | 50 | :: 51 | 52 | pass keybase remove pass-name 53 | 54 | With `remove-all` all of your keybase encrypted passwords will be removed. 55 | 56 | :: 57 | 58 | pass keybase remove-all 59 | 60 | `report` print out how many GPG and how many Keybase encrypted files you have. 61 | 62 | :: 63 | 64 | pass keybase report 65 | 66 | Over the time it will happen that you have to update your password from a given 67 | website. If so, you will use `pass` to update your GPG password, and maybe 68 | forget to update your keybase entry via `pass keybase encrypt`. And this can 69 | happen to many of your passwords. Using the `diff` command can help to get an 70 | overview which passwords are not in sync / are not equal to each other. 71 | 72 | :: 73 | 74 | pass keybase diff 75 | 76 | -------------------------------------------------------------------------------- /docs/source/tutorial.rst: -------------------------------------------------------------------------------- 1 | Tutorial 2 | ======== 3 | 4 | Lets create a new password store and enable the extension support 5 | 6 | :: 7 | 8 | /tmp/passwords 9 | ❯ export PASSWORD_STORE_DIR=/tmp/passwords 10 | 11 | Generate a new password, e.g. for github.com 12 | 13 | :: 14 | 15 | /tmp/passwords 16 | ❯ pass generate Websites/github.com 17 | [master a0befb2] Add generated password for Websites/github.com. 18 | 1 file changed, 0 insertions(+), 0 deletions(-) 19 | create mode 100644 Websites/github.com.gpg 20 | The generated password for Websites/github.com is: 21 | 9lllpU3K4NUx#r&vn{( master) Add generated password for Websites/github.com. (5 seconds ago) 30 | * 73a0e91 - Configure git repository for gpg file diff. (20 seconds ago) 31 | * 0e00d33 - Add current contents of password store. (21 seconds ago) 32 | 33 | Use pass-keybase report to figure out if there is a new gpg entry 34 | 35 | :: 36 | 37 | /tmp/passwords 38 | ❯ pass keybase report 39 | 40 | Number of GPG encryped files: 1 41 | Number of Keybase encryped files: 0 42 | 43 | GPG encrypted passwords which are not encrypted with Keybase: 44 | ************************************************************* 45 | Websites/github.com 46 | 47 | You can encrypt the whole password store 48 | 49 | :: 50 | 51 | /tmp/passwords 52 | ❯ pass keybase encrypt-all 53 | [master 20b145b] Reencrypt password store using keybase-id mbauhardt 54 | 3 files changed, 218 insertions(+) 55 | create mode 100644 Websites/github.com.keybase 56 | 57 | /tmp/passwords 58 | ❯ glol 59 | * 20b145b - (HEAD -> master) Reencrypt password store using keybase-id mbauhardt (19 seconds ago) 60 | * a0befb2 - Add generated password for Websites/github.com. (3 minutes ago) 61 | * 73a0e91 - Configure git repository for gpg file diff. (3 minutes ago) 62 | * 0e00d33 - Add current contents of password store. (3 minutes ago) 63 | 64 | Lets decrpt with keybase to make sure everyting went well. 65 | 66 | :: 67 | 68 | /tmp/passwords 69 | ❯ pass keybase decrypt Websites/github.com 70 | Authored by mbauhardt (you). 71 | 9lllpU3K4NUx#r&vn{( "${XDG_CONFIG_HOME:-$HOME/.config}/pass-keybase/keybase-id" 97 | } 98 | 99 | cmd_remove() { 100 | local path="$1" 101 | local passfile="$PREFIX/$path.keybase" 102 | check_sneaky_paths "$path" 103 | 104 | if [[ -f "$passfile" ]]; then 105 | set_git "$passfile" 106 | rm "$passfile" 107 | git -C "$INNER_GIT_DIR" rm -qr "$passfile" 108 | set_git "$passfile" 109 | git_commit "Remove $path from store." 110 | elif [[ -z "$path" ]]; then 111 | die "" 112 | else 113 | die "Error: $path is not in the password store." 114 | fi 115 | } 116 | 117 | cmd_remove_all() { 118 | while read -r -d "" passfile; do 119 | git -C "$INNER_GIT_DIR" rm -qr "$passfile" 120 | set_git "$passfile" 121 | done < <(find "$PREFIX" -iname '*.keybase' -print0) 122 | git_commit "Remove all keybase files from store." 123 | } 124 | 125 | cmd_decrypt() { 126 | local path="$1" 127 | local passfile="$PREFIX/$path.keybase" 128 | check_sneaky_paths "$path" 129 | 130 | if [[ -f "$passfile" ]]; then 131 | keybase decrypt --force -i "$passfile" 132 | elif [[ -z "$path" ]]; then 133 | die "" 134 | else 135 | die "Error: $path is not in the password store." 136 | fi 137 | } 138 | 139 | cmd_clip() { 140 | local path="$1" 141 | local passfile="$PREFIX/$path.keybase" 142 | check_sneaky_paths "$path" 143 | 144 | if [[ -f "$passfile" ]]; then 145 | local pass="$(keybase decrypt --force -i $passfile 2>/dev/null | head -n 1)" 146 | clip "$pass" "$path" 147 | elif [[ -z "$path" ]]; then 148 | die "" 149 | else 150 | die "Error: $path is not in the password store." 151 | fi 152 | } 153 | 154 | cmd_report() { 155 | local gpgcount=0; 156 | local kbcount=0; 157 | 158 | echo '' 159 | while read -r -d "" passfile; do 160 | let gpgcount++; 161 | done < <(find "$PREFIX" -iname '*.gpg' -print0) 162 | echo 'Number of GPG encryped files: '$gpgcount 163 | 164 | while read -r -d "" passfile; do 165 | let kbcount++; 166 | done < <(find "$PREFIX" -iname '*.keybase' -print0) 167 | echo 'Number of Keybase encryped files: '$kbcount 168 | 169 | echo '' 170 | echo 'GPG encrypted passwords which are not encrypted with Keybase:' 171 | echo '*************************************************************' 172 | while read -r -d "" passfile; do 173 | local keytoshow="${passfile%.gpg}" 174 | local keybasefile="${passfile%.gpg}.keybase" 175 | [ ! -f "$keybasefile" ] && echo "${keytoshow#$PREFIX/}" 176 | done < <(find "$PREFIX" -iname '*.gpg' -print0) 177 | 178 | } 179 | 180 | cmd_diff() { 181 | while read -r -d "" passfile; do 182 | local keytoshow="${passfile%.gpg}" 183 | local keybasefile="${passfile%.gpg}.keybase" 184 | if [[ ! -f "$keybasefile" ]]; then 185 | echo ${keytoshow#$PREFIX/} 186 | else 187 | local md5_gpg=$($GPG -d "${GPG_OPTS[@]}" $passfile | md5sum) 188 | local md5_keybase="$(keybase decrypt --force -i $keybasefile 2> /dev/null | md5sum)" 189 | [[ $md5_gpg != $md5_keybase ]] && echo ${keytoshow#$PREFIX/} 190 | fi 191 | done < <(find $PREFIX -iname '*.gpg' -print0) 192 | } 193 | 194 | case "$1" in 195 | help) 196 | cmd_help 197 | ;; 198 | version) 199 | cmd_version 200 | ;; 201 | init) 202 | shift; 203 | cmd_init "$@" 204 | ;; 205 | encrypt) 206 | shift; 207 | cmd_encrypt "$@" 208 | ;; 209 | encrypt-all) 210 | shift; 211 | cmd_encrypt_all 212 | ;; 213 | decrypt) 214 | shift; 215 | cmd_decrypt "$@" 216 | ;; 217 | clip) 218 | shift; 219 | cmd_clip "$@" 220 | ;; 221 | remove) 222 | shift; 223 | cmd_remove "$@" 224 | ;; 225 | remove-all) 226 | cmd_remove_all 227 | ;; 228 | report) 229 | cmd_report 230 | ;; 231 | diff) 232 | cmd_diff 233 | ;; 234 | *) 235 | cmd_help 236 | ;; 237 | esac 238 | exit 0 239 | --------------------------------------------------------------------------------