#!/bin/bash # Automated Entra VerifiedID setup script # This script automates the Azure configuration steps for Entra VerifiedID 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 # Logging functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_step() { echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${BLUE}Step:${NC} $1" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n" } # Check prerequisites check_prerequisites() { log_step "Checking prerequisites" if ! command -v az &> /dev/null; then log_error "Azure CLI not found. Please install: https://docs.microsoft.com/cli/azure/install-azure-cli" exit 1 fi if ! az account show &> /dev/null; then log_error "Not logged in to Azure. Run: az login" exit 1 fi log_success "Prerequisites check passed" } # Get configuration get_config() { log_step "Getting configuration" read -p "Enter Azure Subscription ID (or press Enter to use current): " SUBSCRIPTION_ID if [ -z "${SUBSCRIPTION_ID}" ]; then SUBSCRIPTION_ID=$(az account show --query id -o tsv) fi read -p "Enter Resource Group name: " RESOURCE_GROUP read -p "Enter App Registration name (e.g., the-order-entra): " APP_NAME read -p "Enter Key Vault name: " KEY_VAULT_NAME log_success "Configuration collected" } # Create App Registration create_app_registration() { log_step "Creating Azure AD App Registration" log_info "Creating app registration: ${APP_NAME}" APP_ID=$(az ad app create \ --display-name "${APP_NAME}" \ --query appId -o tsv) log_info "Creating service principal" SP_ID=$(az ad sp create --id "${APP_ID}" --query id -o tsv) log_info "Getting tenant ID" TENANT_ID=$(az account show --query tenantId -o tsv) log_info "Creating client secret (valid for 1 year)" CLIENT_SECRET=$(az ad app credential reset \ --id "${APP_ID}" \ --years 1 \ --query password -o tsv) log_success "App Registration created" log_info "Application (Client) ID: ${APP_ID}" log_info "Directory (Tenant) ID: ${TENANT_ID}" log_warning "Client Secret (save this securely): ${CLIENT_SECRET}" # Store in variables for later use export ENTRA_TENANT_ID="${TENANT_ID}" export ENTRA_CLIENT_ID="${APP_ID}" export ENTRA_CLIENT_SECRET="${CLIENT_SECRET}" } # Configure API permissions configure_api_permissions() { log_step "Configuring API permissions" log_info "Adding Verifiable Credentials Service permissions" # Get the Verifiable Credentials Service app ID VC_SERVICE_APP_ID="3db474b9-7a6d-4f50-afdc-70940ce1df8f" # Add permissions az ad app permission add \ --id "${APP_ID}" \ --api "${VC_SERVICE_APP_ID}" \ --api-permissions "e5832135-c0d8-4b7b-b5e3-7d4c4c4c4c4c=Role" 2>/dev/null || true log_info "Granting admin consent" az ad app permission admin-consent --id "${APP_ID}" || log_warning "Admin consent may require manual approval" log_success "API permissions configured" log_warning "You may need to grant admin consent manually in Azure Portal" } # Create credential manifest (manual step with instructions) create_credential_manifest() { log_step "Credential Manifest Creation" log_info "Credential manifest creation must be done in Azure Portal" log_info "Follow these steps:" echo "1. Go to Azure Portal → Verified ID" echo "2. Click 'Add credential'" echo "3. Choose credential type and configure" echo "4. Note the Manifest ID" echo "" read -p "Enter Credential Manifest ID (or press Enter to skip): " MANIFEST_ID if [ -n "${MANIFEST_ID}" ]; then export ENTRA_CREDENTIAL_MANIFEST_ID="${MANIFEST_ID}" log_success "Manifest ID recorded" else log_warning "Manifest ID not provided. You can add it later." fi } # Store secrets in Key Vault store_secrets() { log_step "Storing secrets in Key Vault" log_info "Storing Entra Tenant ID" az keyvault secret set \ --vault-name "${KEY_VAULT_NAME}" \ --name "entra-tenant-id" \ --value "${ENTRA_TENANT_ID}" \ --output none || log_error "Failed to store tenant ID" log_info "Storing Entra Client ID" az keyvault secret set \ --vault-name "${KEY_VAULT_NAME}" \ --name "entra-client-id" \ --value "${ENTRA_CLIENT_ID}" \ --output none || log_error "Failed to store client ID" log_info "Storing Entra Client Secret" az keyvault secret set \ --vault-name "${KEY_VAULT_NAME}" \ --name "entra-client-secret" \ --value "${ENTRA_CLIENT_SECRET}" \ --output none || log_error "Failed to store client secret" if [ -n "${ENTRA_CREDENTIAL_MANIFEST_ID:-}" ]; then log_info "Storing Credential Manifest ID" az keyvault secret set \ --vault-name "${KEY_VAULT_NAME}" \ --name "entra-credential-manifest-id" \ --value "${ENTRA_CREDENTIAL_MANIFEST_ID}" \ --output none || log_error "Failed to store manifest ID" fi log_success "Secrets stored in Key Vault" } # Generate environment file generate_env_file() { log_step "Generating environment file template" ENV_FILE=".env.entra.example" cat > "${ENV_FILE}" << EOF # Microsoft Entra VerifiedID Configuration ENTRA_TENANT_ID=${ENTRA_TENANT_ID} ENTRA_CLIENT_ID=${ENTRA_CLIENT_ID} ENTRA_CLIENT_SECRET=${ENTRA_CLIENT_SECRET} ENTRA_CREDENTIAL_MANIFEST_ID=${ENTRA_CREDENTIAL_MANIFEST_ID:-} # Multi-manifest support (JSON format) # ENTRA_MANIFESTS={"default":"manifest-id-1","diplomatic":"manifest-id-2","judicial":"manifest-id-3"} # Entra Rate Limiting (optional) # ENTRA_RATE_LIMIT_ISSUANCE=10 # ENTRA_RATE_LIMIT_VERIFICATION=20 # ENTRA_RATE_LIMIT_STATUS_CHECK=30 # ENTRA_RATE_LIMIT_GLOBAL=50 EOF log_success "Environment file template created: ${ENV_FILE}" log_warning "Update your .env file with these values" } # Main execution main() { log_info "Entra VerifiedID Automated Setup" log_info "This script will help you set up Entra VerifiedID for The Order" check_prerequisites get_config create_app_registration configure_api_permissions create_credential_manifest store_secrets generate_env_file log_success "Setup complete!" log_info "Next steps:" echo "1. Review and update .env file with the generated values" echo "2. Create credential manifests in Azure Portal (if not done)" echo "3. Test the integration using the API endpoints" echo "4. Configure webhook URLs in Entra VerifiedID settings" } # Run main function main "$@"