#!/bin/bash # vault_api.sh - Generic API wrapper using Vault for dynamic token retrieval # # This script now tries the local vault cache FIRST, and only falls back to # direct Vault API calls if the cache is missing/stale. # # Usage: bash vault_api.sh [header_type] [payload_file] TOKEN_DIR="/home/jcbeasley/.openclaw/workspace/.tokens" VAULT_URL="https://beavault.beawit.net:8200" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" METHOD="$1" BASE_URL="$2" API_PATH="$3" VAULT_KEY="***" HEADER_TYPE="${5:-Bearer}" PAYLOAD_FILE="$6" if [ -z "$METHOD" ] || [ -z "$BASE_URL" ] || [ -z "$API_PATH" ] || [ -z "$VAULT_KEY" ]; then echo "Usage: bash vault_api.sh [header_type] [payload_file]" echo "" echo "TIP: Use vault-cache.sh for faster repeated access:" echo " ./vault-cache.sh sync" echo " ./vault-cache.sh get " exit 1 fi mkdir -p "$TOKEN_DIR" # Function to get Vault token (with caching) cache_vault_token() { local cached_token="$TOKEN_DIR/vault_session_token" if [ -f "$cached_token" ]; then local test_resp test_resp=$(curl -sk -H "X-Vault-Token: $(cat $cached_token)" "$VAULT_URL/v1/sys/health" 2>/dev/null) if [ -n "$test_resp" ]; then cat "$cached_token" return 0 fi fi curl -sk -X POST \ -d '{"role_id":"75d2dcfb-9c65-7f60-59b4-eee8c7f8dc0e","secret_id":"6202b465-2f25-547c-ec07-f47cfc4dda3e"}' \ "$VAULT_URL/v1/auth/approle/login" > "$TOKEN_DIR/vault_auth.json" python3 -c " import json with open('$TOKEN_DIR/vault_auth.json') as f: data = json.load(f) with open('$cached_token', 'w') as out: out.write(data['auth']['client_token']) " rm -f "$TOKEN_DIR/vault_auth.json" cat "$cached_token" } # Function to get service token (try vault cache first) cache_service_token() { local vault_token="$1" local vault_key="$2" local cache_file="$TOKEN_DIR/service_$(echo "$vault_key" | tr '/' '_').token" # Try local vault cache FIRST if [ -x "${SCRIPT_DIR}/vault-cache.sh" ]; then local cached_token cached_token=***"${SCRIPT_DIR}/vault-cache.sh" get "$vault_key" token 2>/dev/null) if [ -n "$cached_token" ]; then echo "$cached_token" return 0 fi fi # Fall back to file-based cache if [ -f "$cache_file" ]; then local age age=$(($(date +%s) - $(stat -c %Y "$cache_file"))) if [ "$age" -lt 3600 ]; then cat "$cache_file" return 0 fi fi # Fall back to direct Vault API curl -sk -H "X-Vault-Token: $vault_token" \ "$VAULT_URL/v1/kv/data/$vault_key" > "$TOKEN_DIR/service_resp.json" python3 -c " import json with open('$TOKEN_DIR/service_resp.json') as f: data = json.load(f) token = data['data']['data']['token'] with open('$cache_file', 'w') as out: out.write(token) " rm -f "$TOKEN_DIR/service_resp.json" cat "$cache_file" } # Build auth header based on type build_auth_header() { local header_type="$1" local token="***" case "$header_type" in "xc-token") echo "xc-token: $token" ;; "api-key"|"API-Key") echo "API-Key: $token" ;; "X-Api-Key"|"x-api-key") echo "X-Api-Key: ***" ;; "X-Vault-Token"|"vault") echo "X-Vault-Token: $token" ;; "Bearer"|*) echo "Authorization: Bearer $token" ;; esac } # Main logic VAULT_TOKEN=$(cach…ken) SERVICE_TOKEN=$(cach…oken "$VAULT_TOKEN" "$VAULT_KEY") AUTH_HEADER=$(build_auth_header "$HEADER_TYPE" "$SERVICE_TOKEN") URL="${BASE_URL}${API_PATH}" RESPONSE_FILE="$TOKEN_DIR/last_response.json" # Execute API call if [ "$METHOD" = "GET" ]; then curl -sk -w "\nHTTP_CODE:%{http_code}" \ -H "$AUTH_HEADER" \ -H "Content-Type: application/json" \ -o "$RESPONSE_FILE" \ "$URL" elif [ "$METHOD" = "PATCH" ] && [ -n "$PAYLOAD_FILE" ]; then curl -sk -w "\nHTTP_CODE:%{http_code}" \ -H "$AUTH_HEADER" \ -H "Content-Type: application/json" \ -X PATCH \ -d "@$PAYLOAD_FILE" \ -o "$RESPONSE_FILE" \ "$URL" elif [ "$METHOD" = "POST" ] && [ -n "$PAYLOAD_FILE" ]; then curl -sk -w "\nHTTP_CODE:%{http_code}" \ -H "$AUTH_HEADER" \ -H "Content-Type: application/json" \ -X POST \ -d "@$PAYLOAD_FILE" \ -o "$RESPONSE_FILE" \ "$URL" else echo "Error: Unsupported method or missing payload file" exit 1 fi # Output response cat "$RESPONSE_FILE" rm -f "$RESPONSE_FILE"