#!/usr/bin/env bash # Minimal Vault helper for CI steps (AppRole login + KVv2 reads). # Requires: curl, sed. Uses VAULT_ADDR, VAULT_ROLE_ID, VAULT_SECRET_ID from env. set -euo pipefail : "${VAULT_ADDR:?missing VAULT_ADDR}" VAULT_TOKEN_FILE="${VAULT_TOKEN_FILE:-.vault_token}" log(){ printf '[vlt] %s\n' "$*" >&2; } login() { : "${VAULT_ROLE_ID:?missing VAULT_ROLE_ID}" : "${VAULT_SECRET_ID:?missing VAULT_SECRET_ID}" log "login approle" resp="$(curl -sfS -X POST -H 'Content-Type: application/json' \ --connect-timeout 5 --max-time 20 \ -d "{\"role_id\":\"${VAULT_ROLE_ID}\",\"secret_id\":\"${VAULT_SECRET_ID}\"}" \ "${VAULT_ADDR%/}/v1/auth/approle/login")" token="$(printf '%s' "$resp" | sed -n 's/.*"client_token"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')" [ -n "$token" ] || { echo "login failed" >&2; exit 1; } printf '%s' "$token" > "$VAULT_TOKEN_FILE" } ensure_token() { if [ -s "$VAULT_TOKEN_FILE" ]; then VAULT_TOKEN="$(cat "$VAULT_TOKEN_FILE")" else login VAULT_TOKEN="$(cat "$VAULT_TOKEN_FILE")" fi } # kv_get (KV v2) kv_get() { mount="$1"; path="$2"; field="$3" ensure_token url="${VAULT_ADDR%/}/v1/${mount}/data/${path}" resp="$(curl -sfS --connect-timeout 5 --max-time 20 -H "X-Vault-Token: ${VAULT_TOKEN}" "$url")" raw="$(printf '%s' "$resp" | sed -n "s/.*\"${field}\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p")" [ -n "$raw" ] || { echo "field not found: ${mount}/${path}:${field}" >&2; exit 2; } printf '%s' "$raw" | sed -e 's/\\n/\n/g' -e 's/\\t/\t/g' -e 's/\\"/"/g' -e 's/\\\\/\\/g' } # kv_to_file [mode] kv_to_file() { mount="$1"; path="$2"; field="$3"; dest="$4"; mode="${5:-600}" tmp="$(mktemp)" kv_get "$mount" "$path" "$field" > "$tmp" install -m "$mode" "$tmp" "$dest" rm -f "$tmp" log "wrote $dest" } case "${1:-}" in login) shift; login "$@";; kv_get) shift; kv_get "$@";; kv_to_file) shift; kv_to_file "$@";; *) echo "usage: vlt {login|kv_get|kv_to_file} ..." >&2; exit 64;; esac