From d575b93553948709f11f3c48172c7cd08e2303c0 Mon Sep 17 00:00:00 2001 From: dvirlabs Date: Sat, 23 May 2026 22:39:41 +0300 Subject: [PATCH] Add job to set permissions to vault --- .../vault/job-set-permissions.yaml | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 manifests/raw-resources-infra/vault/job-set-permissions.yaml diff --git a/manifests/raw-resources-infra/vault/job-set-permissions.yaml b/manifests/raw-resources-infra/vault/job-set-permissions.yaml new file mode 100644 index 0000000..64df674 --- /dev/null +++ b/manifests/raw-resources-infra/vault/job-set-permissions.yaml @@ -0,0 +1,138 @@ +# Prerequisites – two Kubernetes Secrets must exist in the infra namespace: +# +# 1. vault-root-token +# key: token → the Vault root token (created after `vault operator init`) +# +# 2. vault-oidc-credentials +# key: clientSecret → the Keycloak client secret for the "vault" OIDC client +# +# This Job runs as an ArgoCD PostSync hook so it fires on every sync of the +# raw-resources-infra application. Because selfHeal is enabled, ArgoCD will +# re-sync (and re-run this Job) any time the Job resource is removed, which +# effectively covers Vault restarts that trigger a pod replacement. +# +# What the Job configures (all operations are idempotent): +# - Enables the OIDC auth method (if not already enabled) +# - Writes the OIDC config pointing at Keycloak realm "lab" +# - Writes the default OIDC role with groups_claim and redirect URIs +# - Creates the "vault-admins" external identity group with the built-in "admin" policy +# - Creates the group alias that maps the Keycloak group "vault-admins" +# to the Vault external group via the OIDC mount accessor +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: vault-configure-permissions + namespace: infra + annotations: + argocd.argoproj.io/hook: PostSync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation +spec: + ttlSecondsAfterFinished: 600 + backoffLimit: 5 + template: + spec: + restartPolicy: OnFailure + containers: + - name: vault-configure + image: hashicorp/vault:1.17.0 + env: + - name: VAULT_ADDR + value: "http://vault.infra.svc.cluster.local:8200" + - name: VAULT_TOKEN + valueFrom: + secretKeyRef: + name: vault-root-token + key: token + - name: OIDC_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: vault-oidc-credentials + key: clientSecret + command: + - /bin/sh + - -c + - | + set -e + + # jq is not bundled in the Vault image – install it from Alpine repos + apk add jq -q --no-progress + + # ── Wait for Vault to be unsealed ────────────────────────────────── + echo ">>> Waiting for Vault to be unsealed..." + until vault status 2>&1 | grep -q "Sealed.*false"; do + echo " not ready yet, retrying in 5s..." + sleep 5 + done + echo ">>> Vault is ready." + + # ── OIDC auth method ─────────────────────────────────────────────── + if vault auth list | grep -q "^oidc/"; then + echo ">>> OIDC auth already enabled." + else + vault auth enable oidc + echo ">>> OIDC auth enabled." + fi + + vault write auth/oidc/config \ + oidc_discovery_url="https://keycloak.dvirlabs.com/realms/lab" \ + oidc_client_id="vault" \ + oidc_client_secret="${OIDC_CLIENT_SECRET}" \ + default_role="default" + echo ">>> OIDC config written." + + vault write auth/oidc/role/default \ + user_claim="sub" \ + groups_claim="groups" \ + allowed_redirect_uris="https://vault.dvirlabs.com/ui/vault/auth/oidc/oidc/callback" \ + allowed_redirect_uris="https://vault.dvirlabs.com/oidc/callback" \ + bound_audiences="vault" \ + ttl="8h" + echo ">>> OIDC role/default written." + + # ── Resolve OIDC mount accessor ──────────────────────────────────── + OIDC_ACCESSOR=$(vault auth list | awk '$1 == "oidc/" {print $3}') + echo ">>> OIDC accessor: ${OIDC_ACCESSOR}" + + # ── vault-admins external group ──────────────────────────────────── + if vault read identity/group/name/vault-admins > /dev/null 2>&1; then + echo ">>> vault-admins group exists – ensuring policy=admin..." + vault write identity/group/name/vault-admins \ + type="external" \ + policies="admin" + else + echo ">>> Creating vault-admins external group..." + vault write identity/group \ + name="vault-admins" \ + type="external" \ + policies="admin" + fi + + GROUP_ID=$(vault read -field=id identity/group/name/vault-admins) + echo ">>> vault-admins group id: ${GROUP_ID}" + + # ── Group alias: Keycloak "vault-admins" → Vault external group ──── + # Walk existing aliases and look for one bound to this group + accessor + EXISTING_ALIAS=$(vault list -format=json identity/group-alias/id 2>/dev/null \ + | jq -r '.[]' \ + | while read ALIAS_ID; do + DATA=$(vault read -format=json "identity/group-alias/id/${ALIAS_ID}" 2>/dev/null) + CID=$(echo "${DATA}" | jq -r '.data.canonical_id') + ACC=$(echo "${DATA}" | jq -r '.data.mount_accessor') + if [ "${CID}" = "${GROUP_ID}" ] && [ "${ACC}" = "${OIDC_ACCESSOR}" ]; then + echo "${ALIAS_ID}" + fi + done | head -1) + + if [ -n "${EXISTING_ALIAS}" ]; then + echo ">>> Group alias already exists (id=${EXISTING_ALIAS}), skipping." + else + vault write identity/group-alias \ + name="vault-admins" \ + canonical_id="${GROUP_ID}" \ + mount_accessor="${OIDC_ACCESSOR}" + echo ">>> Group alias created." + fi + + echo "" + echo ">>> Vault OIDC and permissions configuration complete."