#!/usr/bin/env sh set -eu log() { echo "[vault-k8s-auth] $*"; } status_json="$(vault status -format=json || true)" if [ -z "${status_json}" ]; then log "vault status failed; check VAULT_ADDR and VAULT_TOKEN" exit 1 fi if ! printf '%s' "${status_json}" | grep -q '"initialized":[[:space:]]*true'; then log "vault not initialized; skipping" exit 0 fi if printf '%s' "${status_json}" | grep -q '"sealed":[[:space:]]*true'; then log "vault sealed; skipping" exit 0 fi k8s_host="https://${KUBERNETES_SERVICE_HOST}:443" k8s_ca="$(cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt)" k8s_token="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" role_ttl="${VAULT_K8S_ROLE_TTL:-1h}" if ! vault auth list -format=json | grep -q '"kubernetes/"'; then log "enabling kubernetes auth" vault auth enable kubernetes fi log "configuring kubernetes auth" vault write auth/kubernetes/config \ token_reviewer_jwt="${k8s_token}" \ kubernetes_host="${k8s_host}" \ kubernetes_ca_cert="${k8s_ca}" write_policy_and_role() { role="$1" namespace="$2" service_accounts="$3" read_paths="$4" write_paths="$5" policy_body="" for path in ${read_paths}; do policy_body="${policy_body} path \"kv/data/atlas/${path}\" { capabilities = [\"read\"] } path \"kv/metadata/atlas/${path}\" { capabilities = [\"list\"] } " done for path in ${write_paths}; do policy_body="${policy_body} path \"kv/data/atlas/${path}\" { capabilities = [\"create\", \"update\", \"read\"] } path \"kv/metadata/atlas/${path}\" { capabilities = [\"list\"] } " done log "writing policy ${role}" printf '%s\n' "${policy_body}" | vault policy write "${role}" - log "writing role ${role}" vault write "auth/kubernetes/role/${role}" \ bound_service_account_names="${service_accounts}" \ bound_service_account_namespaces="${namespace}" \ policies="${role}" \ ttl="${role_ttl}" } write_policy_and_role "outline" "outline" "outline-vault" \ "outline/*" "" write_policy_and_role "planka" "planka" "planka-vault" \ "planka/*" "" write_policy_and_role "bstein-dev-home" "bstein-dev-home" "bstein-dev-home" \ "bstein-dev-home/* shared/chat-ai-keys-runtime shared/portal-e2e-client" "" write_policy_and_role "gitea" "gitea" "gitea-vault" \ "gitea/*" "" write_policy_and_role "vaultwarden" "vaultwarden" "vaultwarden-vault" \ "vaultwarden/*" "" write_policy_and_role "sso" "sso" "sso-vault,mas-secrets-ensure" \ "sso/* shared/keycloak-admin shared/portal-e2e-client" "" write_policy_and_role "mailu-mailserver" "mailu-mailserver" "mailu-vault-sync" \ "mailu/* shared/postmark-relay" "" write_policy_and_role "harbor" "harbor" "harbor-vault-sync" \ "harbor/*" "" write_policy_and_role "nextcloud" "nextcloud" "nextcloud-vault" \ "nextcloud/* shared/keycloak-admin" "" write_policy_and_role "comms" "comms" "comms-vault,atlasbot" \ "comms/* shared/chat-ai-keys-runtime" "" write_policy_and_role "jenkins" "jenkins" "jenkins-vault-sync" \ "jenkins/*" "" write_policy_and_role "monitoring" "monitoring" "monitoring-vault-sync" \ "monitoring/* shared/postmark-relay" "" write_policy_and_role "logging" "logging" "logging-vault-sync" \ "logging/*" "" write_policy_and_role "pegasus" "jellyfin" "pegasus-vault-sync" \ "pegasus/*" "" write_policy_and_role "crypto" "crypto" "crypto-vault-sync" \ "crypto/*" "" write_policy_and_role "sso-secrets" "sso" "mas-secrets-ensure" \ "shared/keycloak-admin" \ "harbor/harbor-oidc vault/vault-oidc-config comms/synapse-oidc logging/oauth2-proxy-logs-oidc" write_policy_and_role "comms-secrets" "comms" \ "comms-secrets-ensure,mas-db-ensure,mas-admin-client-secret-writer,othrys-synapse-signingkey-job" \ "" \ "comms/turn-shared-secret comms/livekit-api comms/synapse-redis comms/synapse-macaroon comms/atlasbot-credentials-runtime comms/synapse-db comms/mas-db comms/mas-admin-client-runtime comms/mas-secrets-runtime comms/othrys-synapse-signingkey"