#!/bin/bash # Complete Authentik initial setup and get API token 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 # Configuration # Load environment variables ENV_FILE="${ENV_FILE:-infra/compose/.env}" if [ -f "$ENV_FILE" ]; then source "$ENV_FILE" fi DOMAIN=${DOMAIN:-local} AUTHENTIK_URL="https://auth.${DOMAIN}" ADMIN_EMAIL="admin@${DOMAIN}" ADMIN_PASSWORD="${AUTHENTIK_ADMIN_PASSWORD:-admin123}" echo -e "${BLUE}🔧 Completing Authentik initial setup...${NC}" echo # Function to update env file update_env_var() { local var_name="$1" local var_value="$2" if grep -q "^${var_name}=" "$ENV_FILE"; then # Update existing variable if [[ "$OSTYPE" == "darwin"* ]]; then # macOS sed -i '' "s|^${var_name}=.*|${var_name}=${var_value}|" "$ENV_FILE" else # Linux sed -i "s|^${var_name}=.*|${var_name}=${var_value}|" "$ENV_FILE" fi echo -e "${GREEN}✅ Updated ${var_name}${NC}" else # Add new variable echo "${var_name}=${var_value}" >> "$ENV_FILE" echo -e "${GREEN}✅ Added ${var_name}${NC}" fi } # Function to check if setup is complete check_setup_status() { local host host=$(echo "$AUTHENTIK_URL" | sed -E 's#^https?://([^/]+).*$#\1#') local resolve=(--resolve "${host}:443:127.0.0.1") local setup_code setup_code=$(curl -ks "${resolve[@]}" -o /dev/null -w '%{http_code}' "$AUTHENTIK_URL/if/flow/initial-setup/" || true) if [[ "$setup_code" == "404" ]]; then return 0 # Setup is complete else return 1 # Setup is still needed fi } # Function to get API token get_api_token() { echo -e "${YELLOW}🔑 Getting API token...${NC}" local host host=$(echo "$AUTHENTIK_URL" | sed -E 's#^https?://([^/]+).*$#\1#') local resolve=(--resolve "${host}:443:127.0.0.1") # Get CSRF token first local csrf_token csrf_token=$(curl -ks "${resolve[@]}" -c /tmp/authentik_cookies.txt "$AUTHENTIK_URL/if/flow/default-authentication-flow/" | grep -o 'csrfmiddlewaretoken[^>]*value="[^"]*"' | sed 's/.*value="\([^"]*\)".*/\1/' || echo "") if [ -z "$csrf_token" ]; then echo -e "${RED}❌ Could not get CSRF token${NC}" return 1 fi # Login to get session local login_response login_response=$(curl -ks "${resolve[@]}" -b /tmp/authentik_cookies.txt -c /tmp/authentik_cookies.txt \ -X POST "$AUTHENTIK_URL/if/flow/default-authentication-flow/" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Referer: $AUTHENTIK_URL/if/flow/default-authentication-flow/" \ -d "csrfmiddlewaretoken=$csrf_token&uid_field=$ADMIN_EMAIL&password=$ADMIN_PASSWORD" \ -w '%{http_code}' -o /tmp/login_response.html || echo "") if [[ "$login_response" =~ ^(200|302)$ ]]; then echo -e "${GREEN}✅ Login successful${NC}" # Create API token local token_response token_response=$(curl -ks "${resolve[@]}" -b /tmp/authentik_cookies.txt \ -X POST "$AUTHENTIK_URL/api/v3/core/tokens/" \ -H "Content-Type: application/json" \ -H "X-CSRFToken: $csrf_token" \ -d "{ \"identifier\": \"ai-tax-agent-bootstrap\", \"description\": \"Bootstrap token for AI Tax Agent setup\", \"expires\": \"2025-12-31T23:59:59Z\" }" 2>/dev/null || echo "") if [ -n "$token_response" ]; then local token token=$(echo "$token_response" | python3 -c "import sys, json; print(json.load(sys.stdin)['key'])" 2>/dev/null || echo "") if [ -n "$token" ]; then echo -e "${GREEN}✅ API token created${NC}" echo "$token" return 0 fi fi fi echo -e "${RED}❌ Failed to get API token${NC}" return 1 } # Main function main() { # Check if we already have a valid token (not the placeholder) if [ -n "${AUTHENTIK_BOOTSTRAP_TOKEN:-}" ] && [ "$AUTHENTIK_BOOTSTRAP_TOKEN" != "ak-bootstrap-token" ]; then echo -e "${GREEN}✅ Bootstrap token already configured in .env${NC}" return 0 fi # Check if setup is already complete if check_setup_status; then echo -e "${GREEN}✅ Authentik setup is already complete${NC}" # Try to get API token local api_token if api_token=$(get_api_token); then echo -e "${GREEN}🔑 API token obtained${NC}" # Update .env file with token update_env_var "AUTHENTIK_BOOTSTRAP_TOKEN" "$api_token" echo echo -e "${GREEN}🎉 Setup complete! You can now run:${NC}" echo -e " ${BLUE}make setup-authentik${NC} - to import blueprint configuration" else echo -e "${YELLOW}⚠️ Could not get API token automatically.${NC}" echo -e " (This is expected if you changed the admin password during setup)" echo echo -e "${BLUE}📋 ACTION REQUIRED: Manual Configuration${NC}" echo -e " 1. Open ${BLUE}https://auth.${DOMAIN}/if/admin/#/core/tokens${NC} and log in" echo -e " 2. Click 'Create'" echo -e " - Identifier: ${YELLOW}ai-tax-agent-bootstrap${NC}" echo -e " - User: ${YELLOW}akadmin${NC}" echo -e " 3. Copy the ${YELLOW}Key${NC} (it's a long string)" echo -e " 4. Open ${YELLOW}infra/environments/local/.env${NC} in your editor" echo -e " 5. Replace ${YELLOW}AUTHENTIK_BOOTSTRAP_TOKEN=ak-bootstrap-token${NC} with your new token" echo -e " 6. Run ${BLUE}make setup-sso${NC} again" exit 1 fi else echo -e "${YELLOW}📋 Initial setup still required:${NC}" echo -e " 1. Open ${BLUE}https://auth.${DOMAIN}/if/flow/initial-setup/${NC}" echo -e " 2. Complete the setup wizard with these credentials:" echo -e " • Email: ${BLUE}$ADMIN_EMAIL${NC}" echo -e " • Password: ${BLUE}$ADMIN_PASSWORD${NC}" echo -e " 3. Re-run this script after setup is complete" fi # Cleanup rm -f /tmp/authentik_cookies.txt /tmp/login_response.html } # Run main function main "$@"