Passwords, Credentials, Authentication and Secrets Primer
The purpose of this page is to record options and best practices for managing passwords, credentials, authentication and secrets.
Your goal is to maximize security and simplicity. Choose the platform that works everywhere, consistently regardless of the application (desktop, latptop, phone, server, platform, etc...).
Problem statement: You need access to password everywhere (desktop, laptop, phone, server), and you need the right people who have the right projects to have access to the right passwords. You need them secure. You need to be able to update them from anywhere, and you need changes distributed everywhere. You need them to work across multiple platforms such as Docker, Incus, Proxmox, AWS, Linode, Nix, Debian, etc… And, you cannot spend a fortune in tooling or time…
Age/Rage Primer
Age is popular go-based cli to encryption tool. Here is a quick summary. Rage is a rust-based re-write. Everywhere you see "age" below, you can replace with "rage". Example "rage-keygen".
Create a key:
age-keygen -o ~/.ssh/age-key
Notice that the public key will be printed to the screen. I will refer to this key below as "printed-key".
Create a public key file for reference if needed (similar to id_rsa.pub)
echo "printed-key" > ~/.ssh/age-key.pub
Also consider adding your public key in ~/.bashrc. Example:
AGE_KEY_PUB="printed-key"
Here as some examples of encrypting:
tar cvz ~/data | age -r "printed-key" > data.tar.gz.age age -r $AGE_KEY_PUB zram.txt > zram.txt.age
Here is an example of decrypting (put to a different file name to prevent overwriting the original):
age -d -i ~/.ssh/age-key zram.txt.age > zram.txt.decrypted
References:
- https://github.com/FiloSottile/age
- https://github.com/str4d/rage
- https://github.com/FiloSottile/passage - fork of pass (below) only uses age (instead of gpg)
All the below documentation is related to gpg and pass (password-store). Age is a newer concept and does not rely on pre-existing configuration.
GPG Primer
- Install
- sudo apt update
- sudo apt install gpg
- Note that gpg installs automatically when you install pass: sudo apt install pass
- Create key:
- gpg --gen-key
- Change expiration
- gpg --edit-key <key-here>
- expire
- save
- gpg --edit-key <key-here>
- Find existing keys:
- gpg -k # for public keys
- gpg -K # for private keys
- Export keys (when adding keys to another computer):
- mkdir delme-export-keys
- cd delme-export-keys
- gpg --output public.pgp --armor --export <key-here>
- gpg --output private.pgp --armor --export-secret-key <key-here>
- IMPORTANT: delete the delme-export-keys directory when done
- Import keys (when importing keys to another computer):
- gpg --import private.pgp
- gpg --import public.pgp
- Update trust level:
- gpg --edit-key <key-here>
- > trust
- > 5
- > quit
- gpg --edit-key <key-here>
- IMPORTANT: Delete the gpg.public and gpg.private files
- Remove keys
- gpg --delete-key <key-here>
- gpg --delete-secret-key <key-here>
References:
- /gpg-gnupg-openpgp/ (encrypt files and soap/rest details using gpg)
- openGPG best practices
Pass (Linux CLI password-store)
Summary: pass is a linux cli password manager/store is the best option for the above goal. It is backed by git, and it has read/write clients on just about very major platform.
References:
- man page: https://git.zx2c4.com/password-store/about/
- Getting Started: https://www.youtube.com/watch?v=FhwsfH2TpFA
- IOS: https://github.com/mssun/passforios/wiki#quick-start-guide-for-pass-for-ios
- Multiple Stores/Teams/Users: https://zwyx.dev/blog/shared-password-stores
- Automatic push after commit: https://stackoverflow.com/questions/7925850/how-can-i-automatically-push-after-committing-in-git
- Clever uses of pass: https://vitalyparnas.com/guides/pass/
- Pass work instructions
Pass Quick Reference
- pass insert/generate commands
- pass insert somepassfile # you enter password
- pass generate somepassfile # pass creates password
- pass generate -c Internet/github.com 21 --no-symbols
- # -c to clipboard with 21 length password and no symbols
- cat somefile.txt | pass insert -m somepassfile # -m allows for multi-line - needed for pipe to work - OR you can also use the following:
- pass insert -m somepassfile < somefile.txt
- pass read commands
- pass show somepassfile # show in command line
- pass edit seompassfile # edit in $EDITOR
- pass -c somepassfile # copy password to clipboard
- pass -c2 somepassfile # copy username to clipboard - second line
- pass -c3 somepassfile # copy url to clipboard - third line
- Note: the above -c2 and -c3 assume the convention of putting the username on line 2 and the url on line three. I recommend you create a readme entry to document all assumptions and conventions.
- pass edit readme
- pass find google # search for a file name that contains "google"
- pass grep aws # search for the term 'aws' inside an password file in any location in the file.
- echo "the secret password is: $(pass linode | head -1)" # extracts out the first line of the password file so that it can be used in a script to populate a variable or write to a file. Note that the "head -1" is only needed if the file has multiple lines.
- pass otp
- sudo apt install pass-extension-otp
- Insert into a new file or append an otp to an existing file
- pass otp append google-chuboe-acct # with following example URI:
- otpauth://totp/totp-secret?secret=XZIIEJSKCZZUDUMECOFGBYCMEAUQLQIEJSKCZOFGBY
- Get OTP
- pass otp google-chuboe-acct # prints to screen
- pass otp -c google-chuboe-acct #copies to clipboard
- Create new opt from qr
- Save qr to file
- zbarimg -q --raw qr-image.png | pass otp append chuboe/customer/somecust-vpn
- https://github.com/tadfisher/pass-otp
- Note: I am not really happy how to create an otp. I am used to simply copying and pasting the secret key into a field. Adding the beginning of the URL (otpauth://totp/totp-secret?secret=) is annoying. I will probably create a bash alias/function to make this task easier.
- pass git commands
- pass git init # run only once
- pass git status
- pass git pull
- pass git log -1 # see last commit
- pass git ... (any command that can be used with git can follow this format - including pushing to a private github repository).
Add Additional Key to Existing Password Store
There are times when you need to add an additional key to an existing password store. Here is the command:
pass init [original-key-id] [your-new-key-id]
Using pass from Inside Source Env File
There are times when you need to include an environment variable file in a repository. Below is an example of how to create your environment variable file so that I can read from a .password-store in the same directory (not the user's home directory).
? cat publisher.env PUB_HOST="localhost" PUB_PORT="5432" PUB_DB="idempiere" PUB_SCHEMA="adempiere" PUB_ADMIN="adempiere" PUB_USER="bi_subscriber" PUB_PASSWORD_STORE_DIR=$(pwd)/.password-store/ PUB_PASSWORD=$(PASSWORD_STORE_DIR=$PUB_PASSWORD_STORE_DIR pass bi_subscriber/pub-password)
Bash Functions for Quick Lookup
The following aliases and functions can be added to your .bashrc to make pass much easier to use. Note that I have not figured out a way to enable bash completions for functions/aliases for pass.
For the complete current commands, go here. Below is an example.
# pass find
alias pf='pass find'
# pass quick copy
function p() {
pass -c $1
}
# pass quick copy from local password store in current directory
function pl() {
PASSWORD_STORE_DIR=$(pwd)/.password-store/ pass -c $1
}
Troubleshooting
- You made a bad edit...
- pass git log # shows the last couple of commits
- pass git revert HEAD # reverts the last commit by creating a new commit
- Note: adding other key search words: purge,reverse,undo,back
gpg Defaults
Set the default password timeout to 1 hour (3600 seconds):
- echo "default-cache-ttl 3600" >> ~/.gnupg/gpg-agent.conf
- echo "max-cache-ttl 3600" >> ~/.gnupg/gpg-agent.conf
- gpg-connect-agent reloadagent /bye
gpg Timeout on Lock Screen
See chuboe-system-configurator => gpg-timeout.sh
Access from a Server, Container or Docker
Pass does not behave well inside a container if you are using a key with a password. The normal use case will result in of the following errors errors:
- gpg: decryption failed: No secret key
- This error happens because 'pass' is not configured to ask for your password from inside a ssh shell (from a remote machine).
- The first part of the solution is to pass in the following argument as a prefix to the pass command:
- PASSWORD_STORE_GPG_OPTS="--pinentry-mode loopback" pass edit some-secret-entry
- However, doing so will result in the next error:
- gpg: Sorry, we are in batchmode - can't get input
- This error happens because 'pass' tries to get the password from you in --batch mode.
- To resolve this issue, you need to modify the pass script using:
- sudo vim /usr/bin/pass
- remove the one reference to "--batch"
- After you modify the pass script to remove the --batch reference, the following will now successfully prompt you for a password:
- PASSWORD_STORE_GPG_OPTS="--pinentry-mode loopback" pass edit some-secret-entry
If you are not happy with the above solution, you can simply decript the password manually using the this command after gpg is configured and your private key is imported (just like normal pass operations):
- gpg --pinentry-mode loopback --decrypt --quiet some-secret-entry.gpg
It is a little bit of a bummer that pass does not magically work everywhere; however, I am not too concerned. The only thing you do on a server is decrypt. It is just as easy to use gpg in that case anyway.
Migrating from Another App to Pass
- Export your existing app's details to csv (most package managers have an export to plain text).
- Create a single pass entry that contains the contents of the entire export.
- pass insert -m keepass-csv < delme-kee-20240325.csv
- Use the following command to search your csv at any time
- pass edit keepass-csv
- This approach allows you to move all passwords at once so that you can start using pass for everything moving forward. Migration tools exist for pass; however, my quick experiments did not produce the desired results.
Passforios (IOS app)
The purpose of this section is to discuss how to get up and running with the apple iphone ios app (passforios).
- Get the app from the appstore: https://apps.apple.com/us/app/pass-password-store/id1205820573
- Passforious Quick Start Guide
- You will need to export your local gpg keys (see getting started video above). I used a temporary aws bucket to make them available via https. Remember to delete both the local and published versions after you consume them.
- Point the iphone app to the private github repo.
- To pull or push changes from your phone, simply drag down from the top (like any website or app feed).
- Things I wish were better about the phone app...
- I wish you could have more than one repository on the phone
- I wish you could have a password timeout. Instead, it is either always or never cached.
- Note: You can use your phone's password manager to remember the pass password.
Other Pass GUI Apps
On my desktop/laptop, I do not use a gui for pass. Instead, I simply press "super+t" to get a terminal and execute my pass command to get a password. I do the same for many other tools as well (example: buku bookmarks). I can appreciate that not everyone is comfortable with the terminal, and others might simply prefer a gui. Below are notable gui tools for pass.
- Multi Platform GUI - https://qtpass.org/
- Pass Plus extras [built in GIT support and multiple stores] - https://www.gopass.pw/
Backing up Pass
If you have git enabled and set to push regularly, the contents of pass are backed up using git; however, be aware that you need to backup the contents of gpg (~/.gnupg). Note that I updated the chuboe-system-configurator => sync-backup.sh to include "BU_PRIVATE[gpg]=~/.gnupg" as one of the directories that gets sent to rsync.net. I also included "BU_PRIVATE[password-store]=~/.password-store" for good measure and redundancy.
Pass Reviews and Discussions
Here are some interesting reviews and discussions:
Other Password Clients
KeepassXC (for linux desktop) is a good option; however, it has poor options for integrating with other desktops/phones. It does not have a good multi-master option (where the above pass uses git as its underlying merge/control platform).
Authy is another that has been recommended that can run on multiple platforms.