#!/bin/bash # Setup Vault OIDC Authentication set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Load environment variables if [ -f "infra/compose/.env" ]; then source "infra/compose/.env" fi DOMAIN=${DOMAIN:-local.lan} VAULT_ADDR="http://localhost:8200" AUTHENTIK_URL="https://auth.${DOMAIN}" echo -e "${BLUE}🔧 Setting up Vault OIDC Authentication...${NC}" # Function to check if Vault is ready wait_for_vault() { echo -e "${YELLOW}⏳ Waiting for Vault to be ready...${NC}" local max_attempts=30 local attempt=1 while [ $attempt -le $max_attempts ]; do if docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault status > /dev/null 2>&1; then echo -e "${GREEN}✅ Vault is ready!${NC}" return 0 fi echo -n "." sleep 2 attempt=$((attempt + 1)) done echo -e "${RED}❌ Vault failed to start${NC}" return 1 } # Main setup function setup_vault() { # Check if we have the root token if [ -z "${VAULT_DEV_ROOT_TOKEN_ID:-}" ]; then echo -e "${RED}❌ VAULT_DEV_ROOT_TOKEN_ID not found in environment${NC}" return 1 fi # Check if we have the client secret if [ -z "${AUTHENTIK_VAULT_CLIENT_SECRET:-}" ]; then echo -e "${RED}❌ AUTHENTIK_VAULT_CLIENT_SECRET not found in environment${NC}" return 1 fi # Execute commands inside the Vault container echo -e "${YELLOW}🔐 Configuring Vault OIDC...${NC}" # Login docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault login "$VAULT_DEV_ROOT_TOKEN_ID" > /dev/null # Enable OIDC auth method (ignore error if already enabled) docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault auth enable oidc 2>/dev/null || true echo -e "${GREEN}✅ OIDC auth enabled${NC}" # Configure OIDC # Note: We use the internal Docker network URL for discovery if possible, or the public one if Vault can resolve it. # Since Vault is in the backend network, it can reach 'apa-authentik-server'. # However, the discovery URL usually needs to match what the user sees (issuer validation). # Authentik's issuer is usually the slug URL. # Using the public URL for discovery URL as per standard OIDC validation # We might need to ensure Vault container can resolve auth.local.lan to the Traefik IP or Authentik IP. # In our setup, auth.local.lan resolves to 127.0.0.1 on host. Inside container, it needs to resolve to the gateway or authentik. # For now, let's try using the public URL. If it fails, we might need to add a host alias to the Vault container. docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault write auth/oidc/config \ oidc_discovery_url="$AUTHENTIK_URL/application/o/vault-oidc/" \ oidc_client_id="vault" \ oidc_client_secret="$AUTHENTIK_VAULT_CLIENT_SECRET" \ default_role="reader" \ bound_issuer="localhost" \ oidc_discovery_ca_pem=@/certs/local.crt echo -e "${GREEN}✅ OIDC config written${NC}" # Create reader role docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault write auth/oidc/role/reader \ bound_audiences="vault" \ allowed_redirect_uris="https://vault.${DOMAIN}/ui/vault/auth/oidc/oidc/callback,https://vault.${DOMAIN}/oidc/callback,http://localhost:8250/oidc/callback" \ oidc_scopes="openid,email,profile" \ user_claim="email" \ policies="default" \ ttl="1h" echo -e "${GREEN}✅ OIDC role 'reader' created${NC}" echo echo -e "${GREEN}🎉 Vault OIDC setup complete!${NC}" echo -e " Login at: ${BLUE}https://vault.${DOMAIN}/ui/vault/auth/oidc/oidc/callback${NC}" } # Run wait_for_vault setup_vault