246368c132
Legion is offline. Vault needs a GCP-native home. This commit provisions a 3-node Vault HA cluster on GCE e2-small VMs (us-central1 a/b/c) backed by Raft consensus with GCP KMS auto-unseal already in place. - vault-nodes.tf: 3 VMs with separate pd-ssd data disks (prevent_destroy), IAP-only SSH firewall, Raft peer firewall (8201), global HTTPS LB for vault.neuralplatform.ai with Google-managed cert, HTTP health checks against /v1/sys/health - vault/startup.sh: idempotent boot script — installs Vault from HashiCorp APT repo, mounts/formats the data disk, writes Raft config with dynamic retry_join peers resolved via gcloud metadata, starts vault.service - vault-auth-gcp.tf: GCP Secret Manager secret for init script; outputs the service account emails needed for GCP auth roles - vault/configure-vault-auth.sh: post-init script to enable gcp auth method, write marketing-policy and soma-policy, bind roles to Cloud Run service account identities After apply: set vault_lb_ip output as A record for vault.neuralplatform.ai in Cloudflare, then run vault operator init on vault-node-1 to bootstrap.
144 lines
5.0 KiB
Bash
144 lines
5.0 KiB
Bash
#!/usr/bin/env bash
|
|
# vault/configure-vault-auth.sh
|
|
#
|
|
# Configures Vault GCP IAM auth method and access policies for Cloud Run services.
|
|
#
|
|
# Run this ONCE after the Vault cluster is initialized and unsealed:
|
|
#
|
|
# export VAULT_ADDR=https://vault.neuralplatform.ai
|
|
# export VAULT_TOKEN=<root-token-from-vault-operator-init>
|
|
# bash servers/gcp/vault/configure-vault-auth.sh
|
|
#
|
|
# What this script does:
|
|
# 1. Enables the GCP auth method at auth/gcp
|
|
# 2. Creates Vault policies for marketing and soma
|
|
# 3. Creates GCP IAM auth roles bound to each service's Cloud Run SA
|
|
# 4. (Optional) Creates the kv-v2 secret engines at secret/ if not present
|
|
#
|
|
# After running this script, Cloud Run services can authenticate to Vault using
|
|
# their GCP service account identity — no long-lived tokens needed.
|
|
#
|
|
# Auth flow for Cloud Run:
|
|
# 1. Service calls metadata server to get an OIDC token for its SA
|
|
# 2. POST /v1/auth/gcp/login with role=<role> and jwt=<oidc-token>
|
|
# 3. Vault validates the token against GCP IAM, returns a Vault token
|
|
# 4. Service uses the Vault token to read secrets
|
|
#
|
|
# Vault CLI docs:
|
|
# https://developer.hashicorp.com/vault/docs/auth/gcp
|
|
|
|
set -euo pipefail
|
|
|
|
: "${VAULT_ADDR:?Set VAULT_ADDR to the Vault cluster address}"
|
|
: "${VAULT_TOKEN:?Set VAULT_TOKEN to a root or admin token}"
|
|
|
|
GCP_PROJECT="neuron-785695"
|
|
|
|
# SA emails from terraform outputs (vault-auth-gcp.tf)
|
|
MARKETING_SA="neuron-marketing-sa@${GCP_PROJECT}.iam.gserviceaccount.com"
|
|
SOMA_SA="neuron-soma-sa@${GCP_PROJECT}.iam.gserviceaccount.com"
|
|
|
|
echo "=== Vault GCP Auth Bootstrap ==="
|
|
echo "VAULT_ADDR: ${VAULT_ADDR}"
|
|
echo "GCP Project: ${GCP_PROJECT}"
|
|
echo ""
|
|
|
|
# ── Step 1: Enable kv-v2 secret engine ───────────────────────────────────────
|
|
echo "--- Enabling kv-v2 secret engine at secret/ ---"
|
|
if vault secrets list | grep -q "^secret/"; then
|
|
echo "secret/ already enabled — skipping"
|
|
else
|
|
vault secrets enable -path=secret kv-v2
|
|
echo "Enabled secret/ (kv-v2)"
|
|
fi
|
|
|
|
# ── Step 2: Enable GCP auth method ────────────────────────────────────────────
|
|
echo ""
|
|
echo "--- Enabling GCP auth method ---"
|
|
if vault auth list | grep -q "^gcp/"; then
|
|
echo "gcp/ auth already enabled — skipping"
|
|
else
|
|
vault auth enable gcp
|
|
echo "Enabled gcp/ auth method"
|
|
fi
|
|
|
|
# Configure the auth method to trust the GCP project
|
|
vault write auth/gcp/config \
|
|
project_id="${GCP_PROJECT}"
|
|
|
|
echo "Configured auth/gcp for project ${GCP_PROJECT}"
|
|
|
|
# ── Step 3: Write Vault policies ──────────────────────────────────────────────
|
|
echo ""
|
|
echo "--- Writing Vault policies ---"
|
|
|
|
vault policy write marketing-policy - <<'POLICY'
|
|
# marketing-policy: read access to marketing secrets
|
|
path "secret/data/marketing/*" {
|
|
capabilities = ["read"]
|
|
}
|
|
path "secret/metadata/marketing/*" {
|
|
capabilities = ["list", "read"]
|
|
}
|
|
POLICY
|
|
echo "Wrote marketing-policy"
|
|
|
|
vault policy write soma-policy - <<'POLICY'
|
|
# soma-policy: read access to soma secrets
|
|
path "secret/data/soma/*" {
|
|
capabilities = ["read"]
|
|
}
|
|
path "secret/metadata/soma/*" {
|
|
capabilities = ["list", "read"]
|
|
}
|
|
POLICY
|
|
echo "Wrote soma-policy"
|
|
|
|
# ── Step 4: Create GCP IAM auth roles ────────────────────────────────────────
|
|
echo ""
|
|
echo "--- Creating GCP auth roles ---"
|
|
|
|
# Marketing role — bound to the marketing Cloud Run SA
|
|
# type=iam means auth is validated against GCP IAM (service account JWT)
|
|
vault write auth/gcp/role/marketing \
|
|
type="iam" \
|
|
project_id="${GCP_PROJECT}" \
|
|
bound_service_accounts="${MARKETING_SA}" \
|
|
policies="marketing-policy" \
|
|
ttl="1h" \
|
|
max_ttl="24h"
|
|
echo "Created role: marketing (bound to ${MARKETING_SA})"
|
|
|
|
# Soma role — bound to the soma Cloud Run SA
|
|
vault write auth/gcp/role/soma \
|
|
type="iam" \
|
|
project_id="${GCP_PROJECT}" \
|
|
bound_service_accounts="${SOMA_SA}" \
|
|
policies="soma-policy" \
|
|
ttl="1h" \
|
|
max_ttl="24h"
|
|
echo "Created role: soma (bound to ${SOMA_SA})"
|
|
|
|
# ── Step 5: Smoke test ────────────────────────────────────────────────────────
|
|
echo ""
|
|
echo "--- Smoke test ---"
|
|
echo "Verifying policies exist:"
|
|
vault policy list | grep -E "marketing-policy|soma-policy"
|
|
|
|
echo ""
|
|
echo "Verifying auth roles exist:"
|
|
vault list auth/gcp/role
|
|
|
|
echo ""
|
|
echo "=== Done ==="
|
|
echo ""
|
|
echo "Vault GCP auth is configured. Cloud Run services can now authenticate using:"
|
|
echo " POST \${VAULT_ADDR}/v1/auth/gcp/login"
|
|
echo " body: { role: 'marketing', jwt: '<gcp-oidc-token>' }"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " 1. Write secrets: vault kv put secret/marketing/... key=value"
|
|
echo " 2. Write secrets: vault kv put secret/soma/... key=value"
|
|
echo " 3. Rotate the root token: vault token create -policy=... and revoke root"
|
|
echo " 4. Store the recovery keys securely (used if KMS key needs re-wrapping)"
|