Skip to content

Instantly share code, notes, and snippets.

@ejohnso49
Last active May 14, 2025 05:49
Show Gist options
  • Save ejohnso49/0365f4207d3f228c8083cae766bdb698 to your computer and use it in GitHub Desktop.
Save ejohnso49/0365f4207d3f228c8083cae766bdb698 to your computer and use it in GitHub Desktop.
1password CLI + AWS MFA
#!/bin/bash
# AWS MFA Authentication Script
# This script authenticates to AWS using MFA with the help of 1Password CLI, AWS CLI, and jq
# Requirements: 1Password CLI (op), AWS CLI, and jq must be installed
# Assumptions: The item in 1password containing AWS credentials is structured using the field recommendations
# found in the 1password docs: https://developer.1password.com/docs/cli/shell-plugins/aws/#optional-set-up-multi-factor-authentication
# Config variables - modify these according to your setup
OP_ITEM="AWS CLI (Dev)" # Name of the 1Password item storing your MFA token
OP_VAULT=""
SESSION_DURATION=43200 # Session duration in seconds (12 hours)
# Function to display usage
usage() {
echo "Usage: $0 [options]"
echo "Options:"
echo " -i, --item ITEM 1Password item name (default: $OP_ITEM)"
echo " -v, --vault VAULT 1Password vault name (default: $OP_VAULT)"
echo " -d, --duration SECONDS Session duration in seconds (default: $SESSION_DURATION)"
echo " -h, --help Display this help message"
return 1
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-i|--item)
OP_ITEM="$2"
shift 2
;;
-d|--duration)
SESSION_DURATION="$2"
shift 2
;;
-h|--help)
usage
;;
*)
echo "Unknown option: $1"
usage
;;
esac
done
# Check for required tools
command -v op >/dev/null 2>&1 || { echo "1Password CLI (op) is required but not installed. Aborting."; return 1; }
command -v aws >/dev/null 2>&1 || { echo "AWS CLI is required but not installed. Aborting."; return 1; }
command -v jq >/dev/null 2>&1 || { echo "jq is required but not installed. Aborting."; return 1; }
echo "πŸ”‘ Getting AWS information from 1Password..."
# Get MFA code and MFA serial from 1Password
OP_ITEM_JSON=$(op item get "$OP_ITEM" --format json | jq -r '.fields[]')
ACCESS_KEY_ID=$(echo "$OP_ITEM_JSON" | jq -r 'select(.label=="access key id") | .value')
SECRET_ACCESS_KEY=$(echo "$OP_ITEM_JSON" | jq -r 'select(.label=="secret access key") | .value')
MFA_TOKEN=$(echo "$OP_ITEM_JSON" | jq -r 'select(.label=="one-time password") | .totp')
MFA_DEVICE_ARN=$(echo "$OP_ITEM_JSON" | jq -r 'select(.label=="mfa serial") | .value')
if [ -z "$MFA_TOKEN" ]; then
echo "❌ Failed to get MFA token from 1Password"
return 1
fi
if [ -z "$MFA_DEVICE_ARN" ]; then
echo "❌ Failed to get MFA serial from 1Password"
echo "Please ensure you have a field called 'mfa serial' in your 1Password item"
return 1
fi
echo "βœ… MFA token and serial retrieved successfully"
echo "πŸ”„ Getting temporary AWS credentials..."
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
# Get temporary credentials with MFA
AWS_STS_JSON=$(AWS_ACCESS_KEY_ID="$ACCESS_KEY_ID" \
AWS_SECRET_ACCESS_KEY="$SECRET_ACCESS_KEY" \
aws sts get-session-token \
--serial-number "$MFA_DEVICE_ARN" \
--token-code "$MFA_TOKEN" \
--duration-seconds "$SESSION_DURATION")
if [ -z "$AWS_STS_JSON" ]; then
echo "❌ Failed to get temporary credentials from AWS"
return 1
fi
# Extract credentials from the response
ACCESS_KEY=$(echo "$AWS_STS_JSON" | jq -r '.Credentials.AccessKeyId')
SECRET_KEY=$(echo "$AWS_STS_JSON" | jq -r '.Credentials.SecretAccessKey')
SESSION_TOKEN=$(echo "$AWS_STS_JSON" | jq -r '.Credentials.SessionToken')
EXPIRATION=$(echo "$AWS_STS_JSON" | jq -r '.Credentials.Expiration')
echo "βœ… AWS temporary credentials configured successfully"
echo "⏰ Session will expire at: $EXPIRATION"
echo ""
echo "Exporting AWS credentials as environment variables..."
# Actually export the variables in the current shell
export AWS_ACCESS_KEY_ID=$ACCESS_KEY
export AWS_SECRET_ACCESS_KEY=$SECRET_KEY
export AWS_SESSION_TOKEN=$SESSION_TOKEN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment