1pass is a caching wrapper for the 1Password
Upgrading to version 1.1 requires installation of the
1pass will check for this (and
other) dependencies and remind you to install them.
1pass is designed to make using your 1Password usernames and passwords quick and easy. It is intended for use within an interactive shell as well as from scripts. Once installed and configured as described below, you can obtain an account password in a shell simply by typing:
$ 1pass Github
and your Gitbub password will be copied to the clipboard.
The official 1Password CLI application (
op) can be difficult to use interactively, and unlike
the macOS or Windows 1Password native applications, requires an internet connection to fetch data
from your password vaults. 1pass solves both of these problems.
Op needs session tokens to
be revalidated manually after 30 minutes of inactivity and produces rich output in JSON format. The
JSON output is easy for a program to use, but is not trivially consumed by humans without help.
1pass provides that help, with two main features:
- a simplified interface for listing and fetching usernames, passwords, and other fields for individual items.
- an encrypted local cache of 1Password CLI results.
Together these features enable easy use of 1Password-stored credentials.
$ brew cask install 1password-cli $ brew install jq expect
Copy the 1pass executable file to a suitable location on your PATH (for example, /usr/local/bin) and ensure that it is executable. For example:
curl https://raw.githubusercontent.com/dcreemer/1pass/master/1pass > /usr/local/bin/1pass chmod a+x /usr/local/bin/1pass
If you would like to install bash-completion for 1pass, place the
bash-completion.sh script in
and accessible location and then source it from your
.bash_profile. For example:
mkdir -p /usr/local/etc/1pass curl https://raw.githubusercontent.com/dcreemer/1pass/master/bash_completion.sh > /usr/local/etc/1pass/bash_completion.sh echo "source /usr/local/etc/1pass/bash_completion.sh" >> ~/.bash_profile
By default the completion script will look for
fzf completion support in your environment. If present,
it will use fzf completion (see here).
Note: If you have installed
fzf using homebrew on macOS, make sure you have enabled completion by
$(brew --prefix)/opt/fzf/install --completion and follow the prompts.
If you do not have fzf or if you turn this feature off it will revert to standard bash completion behavior. If you would like to explicitly disable FZF completion for 1pass, you can do so as follows:
This line should be added to your
Security and Warning
1pass requires you to store your 1Password master password in a local GPG-encrypted file. You should inspect the source code to ensure that you trust the software, as well as read this documentation to understand the security tradeoffs.
Like the 1Password application itself, 1pass relies on one password. However that password is not your 1Password "master password" -- it is your Gnu Privacy Guard (gpg) private key. GPG, when configured to use the GPG-agent, will cache your private key password for a configurable length of time (a few hours to a day is perhaps reasonable). 1pass uses your GPG key to store an encrypted copies of your 1Password master password and your 1Password account secret key.
When data is needed from your online 1Password data store, the master password and secret key are temporarily decrypted and exchanged for a session token, which is also then encrypted and stored. The session token will be refreshed as needed. These actions happen automatically once your GPG key is available in the GPG-agent.
The data that is fetched from the 1Password service is cached in local files -- once again also encrypted using your GPG private key.
You can "lock" your 1pass session by running the "forget" command:
$ 1pass -f cleared local session
which removes the local session token (if any), and calls
gpgconf --kill gpg-agent to purge
any running gpg-agent of your GPG secret keys.
In order to run with minimum user input, 1pass relies on the Gnu Privacy Guard
gpg to encrypt all locally stored data. 1Password needs both a master
password and a secret key to access your vault. Each of these must be stored in an encrypted file
(in ~/.1pass or
$XDG_CONFIG_HOME/1pass) for 1pass to work correctly. 1pass encrypts these and all other files
with your own gpg key. This key, as well as your 1Password login email and domain must be
configured in the ~/.1pass/config file. The domain is the full domain name that
you use to sign-in when you use the 1Password website, for example
GPG can be configured to use the
gpg-agent, which can prompt for your gpg password, and
cache it in a local agent for a fixed amount of time. If you configure GPG this way, you will only
need to enter you GPG password (e.g.) once a day, and then seldom need to enter your 1Password
1pass -rv repeatedly will output instructions on how to configure this file and safely
store your master password and secret key.
$ ./1pass -rv please config 1pass by editing /home/me/.1pass/config $ vi ~/.1pass/config $ ./1pass -rv please put your master password into /home/me/.1pass/_master.gpg ex: echo "master-password" | gpg -er email@example.com > /home/me/.1pass/_master.gpg $ echo "sEcre77" | gpg -er firstname.lastname@example.org > /home/me/.1pass/_master.gpg $ ./1pass -rv please put your mysubdomain.1password.com secret key into /home/me/.1pass/_secret.gpg ex: echo "A3-XXXXXX-XXXXXX-XXXXX-XXXXX-XXXXX-XXXXX" | gpg -er email@example.com > /home/me/.1pass/_secret.gpg $ echo "A3-XXXXXX-XXXXXX-XXXXX-XXXXX-XXXXX-XXXXX" | gpg -er firstname.lastname@example.org > /home/me/.1pass/_secret.gpg $ ./1pass -rv signing in to mysubdomain.1password.com email@example.com ...
Once you are configured and signed in, you are ready to use 1pass. The simplest command is 1pass with no arguments to list all items in your vault:
$ 1pass Github MyBankAccount gmail.com ...
The list consists of the titles of each item. You can then retrieve the password of an item:
$ 1pass -p Github sjd$kh23@0dfjs1DDj
The password is echoed to the standard output (when the '-p' option is used). You can easily use this in scripts, for example:
export PGPASSWORD=$(1pass -p MyPostgresServer)
Without the '-p' option, 1pass copies the password to the clipboard:
$ 1pass Github
The contents of the clipboard will be automatically cleared after 30 seconds. You can also pass 1pass an optional field argument -- for example "username" to retrieve that field from the item:
$ 1pass -p MyBankAccount username firstname.lastname@example.org
1pass can lookup other fields besides username or password. They field name is the "label" for the field in the 1Password GUI.
$ 1pass -p MyBankAccount pin 1234
1pass has special support for TOTP fields -- these are fetched directly via
rather than a local cache. (Thanks to (@ev0rtex)[https://github.com/ev0rtex]).
Note that this is different from using TOTP 2FA to log into your 1Password
account (that is supported too -- see below)
$ 1pass -p MyBankAccount totp 9865432
For the brave, a trivial Emacs wrapper library is included. E.g.
(setq freenode-nick-username (1pass--item-username "Freenode/nick1")) (setq freenode-nick-password (1pass--item-password "Freenode/nick1")) (setq freenode-nick-password (1pass--item-field "Freenode" "server"))
Caching and Sessions
When using 1pass, all response data from 1Password is encrypted and then cached to
~/.1pass/cache. Sometimes this cache will be out of date -- for example if you have created a
new password entry via the 1Password application. Passing
-r to 1pass will force a refresh
from the online 1Password vault.
Similarly, 1Password CLI sessions last for 30 minutes from the time of last use. 1pass will manage the session for you, and refresh it as needed.
2FA for 1Password
If you have turned on two-factor authentication (2FA) support for your 1Password account, then 1pass will prompt for you to enter a TOTP code when creating a session. Currently, you will need to re-enter this code after every session expiration (30 minutes of inactivity). Unfortunately this makes using 1pass in non-interactive scripts less useful.
Copyright (c) 2017-2019, David Creemer (twitter: @dcreemer) with some components from other GPL 2+ software.
Some ideas, and a tiny bit of code are taken from pass by Jason A. Donenfeld. Please see the git commit log for contributions from others.