Get a vault token and request a new one only if expired using direnv and 1password cli:

The script:

#!/bin/bash

# Determine the full path of the current script
SCRIPT_PATH=$(realpath "$0")

# Extract directory names for the suffix
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
CURRENT_DIR=$(basename "$SCRIPT_DIR")
PARENT_DIR=$(basename "$(dirname "$SCRIPT_DIR")")
GRANDPARENT_DIR=$(basename "$(dirname "$(dirname "$SCRIPT_DIR")")")

# Construct the suffix and token file path
SUFFIX="${GRANDPARENT_DIR}-${PARENT_DIR}-${CURRENT_DIR}"
TOKEN_FILE="$HOME/.vault_token-${SUFFIX}.json"

# Function to fetch a new token from Vault
fetch_new_token() {
    local retries=3
    local attempt=1

    while ((attempt <= retries)); do
        GITHUB_TOKEN=$(op read "op://Private/Github/token")
        if vault login -method=github token="$GITHUB_TOKEN" -format=json | tee "$TOKEN_FILE" >/dev/null; then
            return 0
        fi

        sleep 2
        ((attempt++))
    done

    echo "Failed to fetch token after $retries attempts. Exiting."
    exit 1
}

# Check if the token file exists and is valid
if [ -f "$TOKEN_FILE" ]; then
    LEASE_DURATION=$(jq -r '.auth.lease_duration' "$TOKEN_FILE")
    FILE_CREATION_TIME=$(stat -c %Z "$TOKEN_FILE")
    CURRENT_TIME=$(date +%s)
    EXPIRATION_TIME=$((FILE_CREATION_TIME + LEASE_DURATION))

    if [ "$CURRENT_TIME" -ge "$EXPIRATION_TIME" ]; then
        fetch_new_token
    fi
else
    fetch_new_token
fi

# Export the token
VAULT_TOKEN=$(jq -r '.auth.client_token' "$TOKEN_FILE")
if [ "$VAULT_TOKEN" = "" ]; then
    echo "Error: Failed to read VAULT_TOKEN from $TOKEN_FILE."
    exit 1
fi

echo "export VAULT_TOKEN=\"$VAULT_TOKEN\""

In .envrc:

export VAULT_ADDR=https://vault.your.host
eval "$(./get_token.sh)"

This will create and store the token in $HOME/.vault_token-<path>.json, for example, if your project is in /home/projects/company/vault/test, file will be stored in:

~/.vault_token-company-vault-test.json

That will cover your TEST env, for PROD maybe you have something like: /home/projects/company/vault/prod, file will be stored in:

~/.vault_token-company-vault-prod.json