Skip to content

Instantly share code, notes, and snippets.

@mickaelperrin
Last active November 27, 2023 16:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mickaelperrin/2e155fc054f80fe948441962c367ae75 to your computer and use it in GitHub Desktop.
Save mickaelperrin/2e155fc054f80fe948441962c367ae75 to your computer and use it in GitHub Desktop.
1Password login / logout helper

Session sharing across terminals for 1Password

This script intends to improve usability of 1Password CLI when working with multiple sessions and.or terminals

How to use ?

Login

oplogin

Logout

oplogout

Refresh session

In the case you have multiple opened windows and you reauthenticate in one, you can simply run opup to refresh your OP_ env variables.

Why ?

1Password has a CLI that relies on environment variables to store some authentication secrets. The trouble comes that by nature environment variables are sticked to the terminal session where you create them. So each time, you launch a new terminal session or a new program using the environment variable you should auth first.

How ?

This script stores the authentication token encrypted on disk and source it automatically each time you launch a new terminal session.

Usage in scripts

To grab the auth variables in your shell scripts include that at the beginning of your scripts

. opsign.sh
eval $(get1PasswordSession)

Specificity

This script will try to login on both on your 1Password team and on your personal 1Password account.

Requirements ?

Sotfware

  • gpg
  • gpg-agent
  • op CLI

Environment variables

  • MY_GPG_PUBLIC_ID: the ID of your GPG public key (make it trusted to prevent confirmation)
  • MY_GPG_PRIVATE_KEYGRIP: the key grip of your private key (to check if key is loaded in gnupg agent)
  • OP_TEAM_SHORTHAND: the shorthand name of your 1Password team
#!/usr/bin/env bash
# This file is intended to be included in your .bashrc
export MY_GPG_PUBLIC_ID="PUTITHERE"
export OP_TEAM_SHORTHAND="PUTITHERE"
alias oplogin='eval $(opsign.sh in)'
alias oplogout='eval $(opsign.sh out)'
alias opup='eval $(opsign.sh update)'
opup
#!/usr/bin/env bash
# This file must be in your PATH and executable
set -e
TEAM_SESSION_KEY=
MY_SESSION_KEY=
ACTION=${1:-in}
function checks() {
if ! which op > /dev/null; then
echo "1Password CLI (op) is not installed."
exit 1
fi
if [[ -z "$MY_GPG_PUBLIC_ID" ]]; then
echo "MY_GPG_PUBLIC_ID environment variable missing"
exit 1
fi
if [[ -z "$OP_TEAM_SHORTHAND" ]]; then
echo "OP_TEAM_SHORTHAND environment variable missing"
exit 1
fi
if [[ -z "$OP_SESSIONSHARING_FILE" ]]; then
mktemp -t opsessions > /dev/null
fi
}
function cleanup() {
find ${TMPDIR:-/tmp} -maxdepth 1 -name "opsessions.*" -print0 | xargs -0 ls -1 -t | tail -n +2 | xargs /bin/rm
}
function op_signin() {
TEAM_SESSION_KEY=$(op signin $OP_TEAM_SHORTHAND --output=raw)
MY_SESSION_KEY=$(op signin my --output=raw)
}
function op_signout() {
if [[ -f "$OP_SESSIONSHARING_FILE" ]]; then
/bin/rm "$OP_SESSIONSHARING_FILE"
fi
op signout
echo "export OP_SESSION_${OP_TEAM_SHORTHAND}="
echo "export OP_SESSION_my="
}
function persistSessionKeys() {
echo "export OP_SESSION_${OP_TEAM_SHORTHAND}=${TEAM_SESSION_KEY}"
echo "export OP_SESSION_my=${MY_SESSION_KEY}"
}
function getSessionSharingFile() {
find ${TMPDIR:-/tmp} -maxdepth 1 -name "opsessions.*" -print0 | xargs -0 ls -1 -t | head -1
}
function get1PasswordSession() {
if [[ -z "$OP_SESSIONSHARING_FILE" ]]; then
OP_SESSIONSHARING_FILE=$(getSessionSharingFile)
fi
if [[ "$(isAuthenticatedOnGPG)" == "1" ]] && [[ ! -z "$OP_SESSIONSHARING_FILE" ]] && [[ -f "$OP_SESSIONSHARING_FILE" ]]; then
gpg --quiet --decrypt "$OP_SESSIONSHARING_FILE"
fi
}
function isAuthenticatedOnGPG() {
gpg-connect-agent 'keyinfo --list' /bye 2>/dev/null | awk "BEGIN{CACHED=0} /^S KEYINFO $MY_GPG_PRIVATE_KEYGRIP/ {if(\$7==1){CACHED=1}} END{if(\$0!=\"\"){print CACHED} else {print \"none\"}}"
}
# Only exec if not sourced
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
OP_SESSIONSHARING_FILE=$(getSessionSharingFile)
checks
cleanup
if [[ "$ACTION" == "in" ]]; then
op_signin
persistSessionKeys | gpg --encrypt --batch --yes --quiet --recipient "$MY_GPG_PUBLIC_ID" --output "$OP_SESSIONSHARING_FILE"
persistSessionKeys
elif [[ "$ACTION" == "update" ]]; then
get1PasswordSession
else
op_signout
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment