Skip to content

GitHub Secrets Setup Guide

Overview

⚠️ ONE-TIME SETUP: This configuration is done once per repository/environment, not per deployment.

GitHub Actions requires Azure credentials and developer principal IDs to deploy infrastructure. This guide explains how to configure these secrets.

What gets configured: - Azure service principal (for infrastructure deployment) - Developer Object IDs (for AI Foundry access after deployment)

When to run: - Initial repository setup - Adding new developers to the team - Rotating credentials (security best practice: quarterly)

Prerequisites

  • Azure subscription with sufficient permissions
  • GitHub repository admin access
  • Azure CLI installed locally

Quick Setup (Automated)

Run the automated setup script:

cd infrastructure/scripts
./setup-github-service-principal.sh

The script will: 1. Create Azure AD application and service principal 2. Configure OIDC federation for GitHub Actions 3. Assign required Azure RBAC roles 4. Output secret values for GitHub configuration

Manual Setup

Step 1: Create Service Principal

# Get subscription and tenant IDs
SUBSCRIPTION_ID=$(az account show --query id -o tsv)
TENANT_ID=$(az account show --query tenantId -o tsv)
GITHUB_REPO="owner/repo"  # Replace with your repo

# Create service principal
SP_DATA=$(az ad sp create-for-rbac \
  --name "loan-defenders-github-actions" \
  --role contributor \
  --scopes "/subscriptions/$SUBSCRIPTION_ID")

# Extract values
APP_ID=$(echo $SP_DATA | jq -r '.appId')
SP_OBJECT_ID=$(az ad sp show --id $APP_ID --query id -o tsv)

Step 2: Configure OIDC Federation

# Configure for dev environment
az ad app federated-credential create \
  --id $APP_ID \
  --parameters "{
    \"name\": \"github-actions-dev\",
    \"issuer\": \"https://token.actions.githubusercontent.com\",
    \"subject\": \"repo:${GITHUB_REPO}:environment:dev\",
    \"audiences\": [\"api://AzureADTokenExchange\"]
  }"

# Configure for staging environment
az ad app federated-credential create \
  --id $APP_ID \
  --parameters "{
    \"name\": \"github-actions-staging\",
    \"issuer\": \"https://token.actions.githubusercontent.com\",
    \"subject\": \"repo:${GITHUB_REPO}:environment:staging\",
    \"audiences\": [\"api://AzureADTokenExchange\"]
  }"

# Configure for prod environment
az ad app federated-credential create \
  --id $APP_ID \
  --parameters "{
    \"name\": \"github-actions-prod\",
    \"issuer\": \"https://token.actions.githubusercontent.com\",
    \"subject\": \"repo:${GITHUB_REPO}:environment:prod\",
    \"audiences\": [\"api://AzureADTokenExchange\"]
  }"

Step 3: Assign Required Roles

# Contributor (resource management)
az role assignment create \
  --assignee $SP_OBJECT_ID \
  --role "Contributor" \
  --scope "/subscriptions/$SUBSCRIPTION_ID"

# User Access Administrator (RBAC management)
az role assignment create \
  --assignee $SP_OBJECT_ID \
  --role "User Access Administrator" \
  --scope "/subscriptions/$SUBSCRIPTION_ID"

# Cognitive Services Contributor (soft-delete purge)
az role assignment create \
  --assignee $SP_OBJECT_ID \
  --role "Cognitive Services Contributor" \
  --scope "/subscriptions/$SUBSCRIPTION_ID"

Step 4: Get Developer Principal IDs

# Get your own Azure AD Object ID
YOUR_ID=$(az ad signed-in-user show --query id -o tsv)
echo "Your Object ID: $YOUR_ID"

# Get other developers' Object IDs
az ad user show --id developer@company.com --query id -o tsv

GitHub Secrets Configuration

Required Repository Secrets

Navigate to: SettingsSecrets and variablesActionsNew repository secret

Secret Name Value Description
AZURE_CLIENT_ID App ID from Step 1 Service principal client ID
AZURE_TENANT_ID Tenant ID from Step 1 Azure AD tenant ID
AZURE_SUBSCRIPTION_ID Subscription ID from Step 1 Azure subscription ID

Required Environment Secrets

For each environment (dev, staging, prod), add:

Secret Name Value Description
DEVELOPER_PRINCIPAL_IDS_DEV Comma-separated Object IDs Developer access for dev
DEVELOPER_PRINCIPAL_IDS_STAGING Comma-separated Object IDs Developer access for staging
DEVELOPER_PRINCIPAL_IDS_PROD Comma-separated Object IDs Developer access for prod

Example:

DEVELOPER_PRINCIPAL_IDS_DEV=fd4ae841-fbcf-47f9-86ea-e98b67016056,59d5784a-fe27-4abb-9d9c-9fd097fef9fd

Creating GitHub Environments

  1. Navigate to: SettingsEnvironments
  2. Click New environment
  3. Enter name: dev
  4. Click Configure environment
  5. Add environment secrets
  6. Repeat for staging and prod

Environment Protection Rules (Optional)

For production environment: 1. Enable Required reviewers 2. Add team members as reviewers 3. Enable Wait timer: 5 minutes 4. Enable Deployment branches: Only main branch

Verification

Test Service Principal Permissions

# Login as service principal
az login --service-principal \
  -u $APP_ID \
  --tenant $TENANT_ID \
  --federated-token "$(cat token.txt)"

# Verify permissions
az role assignment list --assignee $SP_OBJECT_ID --output table

# Expected roles:
# - Contributor
# - User Access Administrator
# - Cognitive Services Contributor

Test Deployment Workflow

# Trigger deployment
gh workflow run deploy-infrastructure.yml \
  --field environment=dev \
  --field deployment_name="" \
  --field deploy_vpn_gateway=false

# Check workflow status
gh run list --workflow=deploy-infrastructure.yml --limit 1

Troubleshooting

Issue: "Failed to log in to Azure"

Symptom: Workflow fails at Azure login step

Solution: 1. Verify OIDC federation is configured correctly:

az ad app federated-credential list --id $APP_ID
2. Check GitHub environment name matches OIDC subject 3. Verify service principal exists:
az ad sp show --id $APP_ID

Issue: "Insufficient privileges to complete the operation"

Symptom: Deployment fails with authorization error

Solution: 1. Verify service principal has required roles:

az role assignment list --assignee $SP_OBJECT_ID --output table
2. Ensure roles are assigned at subscription scope 3. Wait 5-10 minutes for role propagation

Issue: "Developer principal IDs not found"

Symptom: Deployment fails with developer access errors

Solution: 1. Verify GitHub secret exists: - Settings → Secrets and variables → Actions - Check for DEVELOPER_PRINCIPAL_IDS_DEV 2. Verify Object IDs are correct:

az ad user show --id user@company.com --query id -o tsv
3. Ensure comma-separated format (no spaces)

Issue: "Environment secret not found"

Symptom: Workflow fails to read developer IDs

Solution: 1. Ensure GitHub environments are created (dev, staging, prod) 2. Add secrets to environment (not repository) 3. Verify secret name matches workflow expectation

Security Best Practices

1. Principle of Least Privilege

  • Only grant required roles
  • Use environment-specific principal IDs
  • Limit production access to necessary users

2. Secret Rotation

  • Rotate service principal credentials quarterly
  • Use Azure Key Vault for additional secrets
  • Enable Azure AD access reviews

3. Monitoring

  • Enable Azure AD sign-in logs
  • Monitor service principal activity
  • Set up alerts for unusual access patterns

4. Environment Segregation

  • Use different principal IDs per environment
  • Apply stricter controls for production
  • Implement manual approval for prod deployments

Getting Object IDs

Your Own Object ID

az ad signed-in-user show --query id -o tsv

Another User's Object ID

az ad user show --id user@company.com --query id -o tsv

Service Principal Object ID

az ad sp show --id <app-id> --query id -o tsv

Group Object ID

az ad group show --group "Azure Developers" --query id -o tsv