encpass.sh provides a lightweight solution for using encrypted passwords in shell scripts using OpenSSL. It allows a user to encrypt a password (or any other secret) at runtime and then use it, decrypted, within a script. This prevents shoulder surfing passwords and avoids storing the password in plain text, which could inadvertently be sent to or discovered by an individual at a later date.
This script generates an AES 256 bit symmetric key for each script (or user-defined bucket) that stores secrets. This key will then be used to encrypt all secrets for that script or bucket.
Subsequent calls to retrieve a secret will not prompt for a secret to be entered as the file with the encrypted value already exists.
Note: By default, encpass.sh sets up a directory (.encpass) under the user's home directory where keys and secrets will be stored. This directory can be overridden by setting the environment variable ENCPASS_HOME_DIR to a directory of your choice.
~/.encpass (or the directory specified by ENCPASS_HOME_DIR) will contain the following subdirectories:
- keys (Holds the private key for each script or user-defined bucket)
- secrets (Holds the secrets stored for each script or user-defined bucket)
encpass.sh requires the following software to be installed:
- POSIX compliant shell environment (sh, bash, ksh, zsh)
Note: Even if you use fish or other types of modern shells, encpass.sh should still be usable as those shells typically support running POSIX compliant scripts. You just won't be able to include encpass.sh in any fish specific scripts or other non-POSIX compliant scripts.
Download the encpass.sh script and install it to a directory in your path.
Example: curl the script to /usr/local/bin
$ curl https://raw.githubusercontent.com/ahnick/encpass.sh/master/encpass.sh -o /usr/local/bin/encpass.sh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3085 100 3085 0 0 5184 0 --:--:-- --:--:-- --:--:-- 5193
Source encpass.sh in your script and call the get_secret function.
See the example.sh sample script...
#!/bin/sh . encpass.sh password=$(get_secret) # Call it specifying a named secret #password=$(get_secret password) # Call it specifying a named secret for a specific label #password=$(get_secret example.sh password) echo $password
Command Line Management
encpass.sh also provides a command line interface to perform the following management functions:
- Add secrets/buckets
- Remove secrets/buckets
- List secrets/buckets
- Show secrets/bucket
- Lock/Unlock all keys for buckets
For example, the following command will list the secrets stored for example.sh:
$ ./encpass.sh ls example.sh password
Use the following command to list all commands along with their descriptions:
$ ./encpass.sh ?
By default encpass.sh will create a hidden directory in the user's home directory to store all it's data (keys and secrets) in. A different directory can be specified by setting the ENCPASS_HOME_DIR environment variable.
For example, you could store the .encpass directory on an encrypted filesystem or networked mount point such as KBFS (Keybase Filesystem). To do this you can place the following line (substituting your own username) in your ~/.bashrc or ~/.bash_profile, so that everytime you start a shell encpass.sh will point to this location for the .encpass directory.
Testing with Docker
All testing can be carried out using the Makefile bundled with the repo. This Makefile will build and run a docker image to carry out the testing; therefore, you must have docker installed on your local machine in order to execute the tests.
To verify that any changes made do not contain any errors, please run shellcheck using make.
If there are any errors output please correct those errors or suppress the warnings if appropriate.
encpass.sh also strives to be usable in all POSIX compliant shell environments (i.e. SH, BASH, ZSH, KSH). To verify changes to the script have not broken compliance, you can run the bundled unit tests with the repo using make.
Important Security Information
Although encpass.sh encrypts every secret on disk within the user's home directory, once the password is decrypted within a script, the script author must take care not to inadvertently expose the password. For example, if you invoke another process from within a script that is using the decrypted password AND you pass the decrypted password to that process, then it would be visible to ps.
Imagine a script like the following...
#!/bin/sh . ./encpass.sh password=$(get_secret) watch whatever.sh --pass=$password & ps -A
Upon executing you should see the password in the ps output...
97349 ?? 9:56.30 watch whatever.sh --pass=P@$$w0rd