Installation Instructions
Complete CIPP Deployment Guide
Lessons Learned from Production Deployment
Document Version: 1.0
Last Updated: December 31, 2024
Tested On: Azure Free Tier → Pay-As-You-Go
Target Use Case: Single tenant and multi-tenant M365 management
Table of Contents
- Overview
- Prerequisites
- Common Pitfalls to Avoid
- Step-by-Step Deployment
- Post-Deployment Configuration
- Security Hardening
- Troubleshooting
- Cost Management
Overview
What is CIPP?
CIPP (CyberDrain Improved Partner Portal) is an open-source M365 management platform that provides:
- Centralized management of single or multiple M365 tenants
- Simplified user, license, and mailbox management
- Security monitoring and compliance reporting
- Automation and standardization capabilities
Architecture
CIPP deploys to Azure and consists of:
- Static Web App: React frontend interface
- Function App: PowerShell-based API backend
- Storage Account: Data persistence and caching
- Key Vault: Secure credential storage
- App Service Plan: Consumption-tier hosting (pay-per-use)
Expected Costs
Monthly Azure Costs: \$15-20 USD
- Function App: ~\$5 (Consumption plan with free tier)
- Static Web App: Free tier
- Storage Account: ~\$5
- Key Vault: ~\$5
- Total: Approximately \$15-20/month
Prerequisites
1. GitHub Setup
Required Repositories (Must Be Your Forks):
- Fork the CIPP Frontend:
- Go to: https://github.com/KelvinTegelaar/CIPP
- Click "Fork" in top-right
- Save your fork URL:
https://github.com/YOUR-USERNAME/CIPP - Fork the CIPP API:
- Go to: https://github.com/KelvinTegelaar/CIPP-API
- Click "Fork" in top-right
- Save your fork URL:
https://github.com/YOUR-USERNAME/CIPP-API
Create GitHub Personal Access Token:
- GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
- Click "Generate new token (classic)"
- Note/Description: "CIPP Deployment"
- Expiration: 90 days (or longer)
- Scopes: Check "repo" (Full control of private repositories)
- Click "Generate token"
- CRITICAL: Copy the token immediately and save it securely
- You cannot retrieve this token again after leaving the page
Important Notes:
- Do NOT use fine-grained tokens - they cause deployment failures
- Must use classic tokens with full repo scope
- Store token securely - you'll need it for deployment and updates
2. Azure Subscription Setup
Option A: Free Tier (Will Hit Quota Issues)
- Azure Free tier subscriptions have zero quota for Dynamic VMs
- Deployment will fail in most regions
- Only works reliably in Central US region
- Not recommended unless you specifically need free tier
Option B: Pay-As-You-Go (Recommended)
- Upgrade your Azure subscription to Pay-As-You-Go
- You KEEP your \$200 free credit if within 30-day window
- Unlocks better regional availability
- Allows quota increase requests if needed
- Required for reliable deployments
How to Upgrade:
- Azure Portal → Subscriptions → Select your free subscription
- Click "Upgrade" in command bar
- Add payment method (won't be charged until credits exhausted)
- Upgrade completes in 2-5 minutes
- Return to deployment
3. M365 Account Setup
Your Personal Admin Account:
- Email: your-admin@yourdomain.com
- Role: Global Administrator (or will need it temporarily)
- MFA: Enabled and working
- Purpose: CIPP interface access, SAM wizard authentication
CIPP Service Account (Create This):
- Microsoft 365 Admin Center → Users → Active users → Add a user
- Username:
CIPPServiceAccount(full address: CIPPServiceAccount@yourdomain.onmicrosoft.com) - Display name:
CIPP Service Account - Password: Generate strong password, save in password manager
- Uncheck "Require password change at first sign-in"
- Uncheck "Send password in email"
- Assign product licenses: None required (can skip)
- Click "Finish adding"
Configure Service Account Roles:
- Microsoft Entra ID → Users → CIPPServiceAccount
- Assigned roles → Add assignments
- Select: Global Administrator
- Click "Add"
Configure Service Account MFA:
- Microsoft Entra ID → Users → CIPPServiceAccount → Authentication methods
- Click "Require re-register multifactor authentication"
- Open incognito browser window
- Sign in to portal.office.com as CIPPServiceAccount
- Complete MFA setup using Microsoft Authenticator (NOT Duo, Okta, or other third-party)
- Verify you can successfully authenticate
CRITICAL: Microsoft MFA Only
- CIPP requires Microsoft native MFA
- Duo, Okta, and third-party MFA providers are NOT supported
- Must use Microsoft Authenticator app or SMS/phone call
- Test MFA works before proceeding with deployment
Break-Glass Admin Account (Best Practice):
- Account: your-admin@yourdomain.onmicrosoft.com
- Purpose: Emergency access if custom domain fails
- Role: Global Administrator (keep permanently)
- Exclude from Conditional Access policies
- Store password securely (password manager + physical backup)
- Test quarterly, use only in emergencies
4. Network and Access Requirements
Ensure You Have:
- Stable internet connection
- Admin access to Azure Portal
- Admin access to Microsoft 365 Admin Center
- Admin access to Microsoft Entra ID
- Ability to authenticate with MFA on both accounts
Common Pitfalls to Avoid
Critical Mistakes That Will Cause Deployment Failures
1. Using Wrong Deployment Template
- ❌ WRONG: Using default "Deploy to Azure" button
- ✅ CORRECT: Use "Deploy to Azure - Alternative (Central US)" button
- Why: Default template hits quota issues on free/new Azure subscriptions
2. Inviting User as 'admin' Instead of 'superadmin'
- ❌ WRONG: Static Web App role = "admin"
- ✅ CORRECT: Static Web App role = "superadmin"
- Why: SAM Setup Wizard is only visible to superadmin role
- Impact: You won't see the setup wizard and can't configure CIPP
3. Not Granting Admin Consent Immediately
- ❌ WRONG: Creating CIPP-SAM app, then trying to connect tenant
- ✅ CORRECT: Create app → Grant admin consent → Wait 5 minutes → Connect tenant
- Why: Tenant connection fails with "Authorization_RequestDenied" if consent not granted
- Impact: "TenantFailed" entries in storage, hours of troubleshooting
4. Using Wrong Account for Tenant Connection
- ❌ WRONG: Authenticating with your personal admin account
- ✅ CORRECT: Authenticating with CIPPServiceAccount
- Why: CIPP specifically requires service account for tenant connection
- Impact: Authentication errors, wizard won't proceed
5. Removing Global Admin Too Early
- ❌ WRONG: Removing Global Admin from service account immediately
- ✅ CORRECT: Keep Global Admin on service account for full functionality
- Why: Delegated permissions require underlying user to have appropriate roles
- Impact: Operations fail with "Insufficient privileges" errors
6. Using Default GitHub Repository URLs
- ❌ WRONG: Leaving KelvinTegelaar's repository URLs in deployment
- ✅ CORRECT: Using YOUR forked repository URLs
- Why: Updates deploy to YOUR forks, not upstream repositories
- Impact: Cannot control updates, cannot customize deployment
7. Creating Service Principal Manually
- ❌ WRONG: Trying to manually create Windows Defender ATP service principals
- ✅ CORRECT: Skip missing service principals, proceed anyway
- Why: Some service principals don't exist in all tenant types
- Impact: Wasted hours troubleshooting non-critical permissions
8. Manual Credential Management
- ❌ WRONG: Manually entering app ID, secret, tenant ID
- ✅ CORRECT: Choose "Create application for me" in SAM wizard
- Why: Manual entry prone to errors (wrong secret value vs. secret ID)
- Impact: Authentication failures, refresh token issues
Step-by-Step Deployment
Phase 1: Azure Deployment (20-30 minutes)
Step 1: Navigate to Deployment Page
- Open browser to: https://docs.cipp.app/setup/installation/
- Locate deployment buttons
- Click: "Deploy to Azure - Alternative (Central US)"
- Azure Portal opens Custom Deployment form
Step 2: Configure Deployment Parameters
Basic Settings:
- Subscription: Select your Azure subscription (should auto-select if you only have one)
- Resource Group:
- Click "Create new"
- Name:
CIPP-Production(or your preferred name) - Click "OK"
- Region: Central US (should be pre-selected by Alternative template)
CIPP GitHub Settings:
- GitHub Repository:
- DELETE the default URL completely
- Paste YOUR fork:
https://github.com/YOUR-USERNAME/CIPP - Verify URL is correct before proceeding
- GitHub API Repository:
- DELETE the default URL completely
- Paste YOUR CIPP-API fork:
https://github.com/YOUR-USERNAME/CIPP-API - Verify URL is correct before proceeding
- GitHub Token:
- Paste your Personal Access Token (classic)
- Verify it's the classic token with repo scope
Double-Check Everything:
- Region = Central US
- Both GitHub URLs use YOUR username
- GitHub token is pasted correctly
- Resource group name is what you want
Step 3: Deploy
- Click "Review + create" at bottom
- Azure validates parameters (wait for green checkmark)
- Review all parameters one final time
- Click "Create"
- Deployment begins
Step 4: Monitor Deployment Progress
- Watch deployment progress in Azure Portal
- Click Notifications (bell icon in top bar) to see status
- Expected duration: 15-20 minutes
- Deployment creates 5 resources:
- Static Web App
- Function App
- Storage Account
- Key Vault
- App Service Plan
Step 5: Verify Deployment Success
- When deployment shows "Your deployment is complete"
- Click "Go to resource group"
- Verify you see all 5 resources in the group
- Click on Static Web App resource
- Find the URL field (e.g.,
https://happy-ocean-xyz123.azurestaticapps.net) - Copy this URL - this is your CIPP portal
- Open URL in new browser tab - should see CIPP login screen
If Deployment Fails:
- Check error message carefully
- Common issues:
- Quota error: Region doesn't have capacity, try different region or upgrade subscription
- GitHub token: Token expired or has wrong permissions
- Validation error: Check all parameters are filled correctly
Phase 2: Initial Access Setup (10 minutes)
Step 1: Create Your Superadmin Access
- In Azure Portal, still in the Static Web App resource
- Left menu → Settings → Role Management
- CRITICAL: This is NOT "Access control (IAM)" - use "Role Management" under Settings
- Click "Invite"
- Fill in invitation details:
- Email: your-admin@yourdomain.com
- Domain: Select your domain from dropdown
- Role: superadmin ← CRITICAL! NOT "admin"
- Click "Generate"
- Copy the invitation link that appears
- Open invitation link in new tab or click it directly
- Accept the invitation when prompted
Step 2: First Login to CIPP
- Open your CIPP URL (from Static Web App)
- You should see CIPP login screen
- Click to log in
- Sign in with your personal admin account (your-admin@yourdomain.com)
- Complete MFA
- CIPP interface loads
- You might see "Not supported" message on Dashboard - this is normal when no tenant is selected
Troubleshooting Login Issues:
- "You do not have access": Role invitation not accepted, or used wrong role
- Can't log in: Clear browser cache, try incognito window
- Login succeeds but no menus: Role is "admin" not "superadmin" - re-invite with correct role
Phase 3: SAM Setup Wizard (20-30 minutes)
The SAM (Secure Application Model) wizard creates the authentication infrastructure CIPP needs to access your M365 tenant.
Step 1: Navigate to Setup Wizard
- In CIPP interface, click hamburger menu (three horizontal lines) in top-left
- Navigate to Settings → SAM Setup Wizard
- Or look for "Setup Wizard" under CIPP Settings menu
- Or look in Advanced/Super Admin section
- You should see Step 1 - Onboarding
If you don't see SAM Setup Wizard:
- Your role is "admin" not "superadmin"
- Go back to Static Web App Role Management
- Delete existing invitation
- Re-invite with "superadmin" role
- Log out of CIPP completely and log back in
Step 2: Step 1 - Onboarding
- Select: "First Setup"
- Click "Authenticate with Microsoft"
- Microsoft login window opens
- Sign in with your personal admin account (your-admin@yourdomain.com)
- Complete MFA
- Click "Accept" if prompted for consent
- You're redirected back to CIPP
- Wizard advances to Step 2 automatically (or click "Next Step")
Step 3: Step 2 - Application
CRITICAL DECISION POINT:
- You'll see options for how to set up the CIPP-SAM application
- Select: "Create application for me and connect to my tenants"
- DO NOT select "Manually enter credentials"
- Click to proceed
What Happens Next:
- Microsoft consent window opens
- Sign in with your personal admin account (your-admin@yourdomain.com)
- You'll see a permissions consent screen listing all Microsoft Graph permissions CIPP needs
- This list is long (100+ permissions) - this is normal
- Scroll through permissions - familiarize yourself with what CIPP requests
- Click "Accept" to grant consent
- You're redirected back to CIPP
- CIPP creates the CIPP-SAM app registration in your Entra ID
- CIPP stores app credentials in Azure Key Vault
- Step 2 shows green checkmarks for success
What Was Just Created:
- App Registration in Entra ID named "CIPP-SAM"
- Client secret stored in Key Vault
- Admin consent granted for all Microsoft Graph permissions
- Refresh token generated and stored in Key Vault
Step 4: CRITICAL - Verify Admin Consent (Do This Immediately)
DO NOT proceed to Step 3 yet! First verify consent was granted:
- Open new browser tab
- Go to portal.azure.com
- Navigate to Microsoft Entra ID → App registrations → All applications
- Search for and click "CIPP-SAM"
- Left menu → API permissions
- Look at Status column for all permissions
- Every permission must show green checkmark with "Granted for [Your Tenant Name]"
If ANY permissions show "Not granted":
- At top of API permissions page, click "Grant admin consent for [Your Tenant Name]"
- Click "Yes" to confirm
- Wait for all permissions to show green checkmarks
- Wait 5-10 minutes for Microsoft Graph to propagate permissions
- Set a timer - do not proceed until time expires
- This waiting period is CRITICAL - skipping it causes tenant connection failures
If you proceed without verifying consent:
- Tenant connection will fail with "Authorization_RequestDenied"
- You'll get "TenantFailed" entries in Azure Storage
- You'll waste 1-2 hours troubleshooting
- Ask me how I know...
Step 5: Step 3 - Tenants (The Most Important Step)
After waiting 5-10 minutes for permission propagation:
- Return to CIPP → SAM Setup Wizard
- You should be on Step 3 - Tenants
- Top of page shows green checkmarks from Step 2 - this is good
- Scroll down to "Partner Tenant" section
- Read the note: "Please remember to log onto a service account dedicated for CIPP"
- Click "Connect to Partner Tenant (Recommended)"
Authentication Window Opens:
- CRITICAL: Sign in with CIPPServiceAccount@yourdomain.onmicrosoft.com
- DO NOT use your personal admin account
- Complete MFA for the service account
- If you don't remember the password, reset it in M365 Admin Center first
- If MFA isn't set up, you'll be prompted to configure it now
- Accept consent if prompted (may not be needed since you already granted it)
- You're redirected back to CIPP
What Should Happen:
- After authentication, you're back in CIPP on Step 3
- Scroll down to "Authenticated Tenants" section at bottom
- After 30-60 seconds, your tenant should appear in the table
- Tenant shows:
- Display Name (default domain or org name)
- Tenant ID
- Status (Connected or similar)
If Tenant Doesn't Appear:
- Click the refresh icon (circular arrows) near the search box
- Wait 2-3 minutes
- Click refresh again
- If still not appearing after 5 minutes, proceed to troubleshooting section
Step 6: Steps 4-7 (Quick Configuration)
Step 4 - Baselines:
- Optional configuration for applying security standards
- For initial setup: Skip this (can configure later)
- Click "Next Step"
Step 5 - Notifications:
- Optional configuration for CIPP alerts and notifications
- For initial setup: Skip this (can configure later)
- Click "Next Step"
Step 6 - Next Steps:
- Displays recommendations and next actions
- Review if interested, or skip
- Click "Next Step"
Step 7 - Confirmation:
- Final step summarizing setup
- Click "Finish" or "Complete Setup"
- SAM wizard closes
Step 7: Verify Tenant Appears in CIPP
- Navigate to Tenant Administration → Administration → Tenants
- Click refresh icon (circular arrows)
- Your tenant should appear in the list
- If not visible yet, proceed to next step anyway
Step 8: Select Your Tenant
- Look at top of CIPP interface
- Find the tenant selector dropdown (shows "All Tenants" or similar)
- Click the dropdown
- Select your tenant from the list
- Dashboard and all features should now load with your tenant data
If "All Tenants" is the only option:
- Tenant hasn't synced yet
- Wait 15-30 minutes for CIPP timer function to run
- Timer runs every 15 minutes at :00, :15, :30, :45
- Check back at next interval
- Click refresh in tenant selector dropdown
Phase 4: Post-Deployment Verification (10 minutes)
Step 1: Test Basic Functionality
With your tenant selected, verify these areas load correctly:
Dashboard:
- Navigate to Dashboard
- Should show:
- User count
- License allocation
- Recent activity
- Tenant overview statistics
Identity Management:
- Navigate to Identity Management → Users
- Should list all M365 users in your tenant
- Click on a user to view details
- Verify user information displays correctly
Email & Exchange:
- Navigate to Email & Exchange → Mailboxes
- Should list all mailboxes
- Verify mailbox details are accessible
Licenses:
- Navigate to Identity Management → Licenses
- Should show license allocation
- Verify license counts match M365 Admin Center
Step 2: Check CIPP Application Status
- Navigate to Settings → CIPP → Permissions
- Click "Run Permissions Check" (if available)
- Should show green checkmarks for all required permissions
- If any permissions missing, click "Repair Permissions"
Step 3: Verify Azure Resources
- portal.azure.com → Your CIPP Resource Group
- Verify all 5 resources are Running:
- Static Web App: Status = Running
- Function App: Status = Running
- Storage Account: Available
- Key Vault: Available
- App Service Plan: Running
- Click Function App → Functions
- Verify functions are enabled:
- CIPPActivityFunction: Enabled
- CIPPHttpTrigger: Enabled
- CIPPOrchestrator: Enabled
- CIPPTimer: Enabled
Step 4: Verify Key Vault Access
- Resource Group → Key Vault → Access policies
- Should see two policies:
- Your admin account (from manual addition)
- Function App managed identity (cippzhyys or similar)
- Both should have Get/List permissions for Secrets
Post-Deployment Configuration
Set Custom Tenant Display Name
By default, CIPP shows your tenant as "yourdomain.onmicrosoft.com" in the dropdown.
To customize:
- Select your tenant from dropdown
- Navigate to Tenant Administration → Manage Tenant
- Click "Edit Tenant" tab
- Find "Tenant Alias" field under "Edit Tenant Properties"
- Enter your preferred display name:
- "Your Company Name"
- "yourcompany.com"
- Or any friendly name you prefer
- Click "Save Changes"
- Refresh CIPP
- Tenant dropdown now shows your custom name
Set Up Custom Domain for CIPP Portal (Optional)
Instead of accessing CIPP via https://random-name-xyz123.azurestaticapps.net, you can use your own domain.
Prerequisites:
- Own a domain name
- Have DNS management access
Steps:
- Azure Portal → Your CIPP Resource Group → Static Web App
- Left menu → Settings → Custom domains
- Click "+ Add"
- Select "Custom domain on other DNS"
- Enter your subdomain:
cipp.yourdomain.com - Click "Next"
- Azure provides DNS records to add:
- CNAME record or TXT record for validation
- Add DNS records in your domain registrar/DNS provider
- Wait for DNS propagation (5 minutes to 24 hours)
- Return to Azure, click "Validate"
- Once validated, click "Add"
- Your CIPP is now accessible at
https://cipp.yourdomain.com
Configure Azure Cost Alerts
Protect against unexpected charges:
- Azure Portal → Cost Management + Billing → Budgets
- Click "+ Add"
- Scope: Select your CIPP Resource Group
- Budget details:
- Name: "CIPP Monthly Budget"
- Reset period: Monthly
- Creation date: First of current month
- Expiration date: (leave blank for no expiration)
- Amount: \$30 (buffer above expected \$15-20)
- Alert conditions:
- Add alert at 50% (\$15)
- Add alert at 80% (\$24)
- Add alert at 100% (\$30)
- Alert recipients: Enter your email
- Click "Create"
Monitor costs:
- Review weekly during first month to understand usage patterns
- Adjust budget alerts based on actual costs
- Typical steady-state cost is \$15-20/month
Enable Application Insights (Optional but Recommended)
For detailed logging and troubleshooting:
- Azure Portal → CIPP Resource Group → Function App
- Left menu → Application Insights
- If not enabled, click "Turn on Application Insights"
- Select: Create new resource or use existing
- Click "Apply"
- Benefits:
- Detailed error logging
- Performance metrics
- Request tracking
- Helps troubleshoot issues
Security Hardening
Service Account Role Management
Current State After Deployment:
- CIPPServiceAccount has Global Administrator role
- Required for full CIPP functionality
- Used for all CIPP automated operations
Why Global Admin is Needed:
CIPP uses delegated permissions, meaning:
- The CIPP-SAM app has Microsoft Graph permissions
- Operations execute "as" the CIPPServiceAccount
- The account itself needs appropriate admin roles
- Many write operations require Global Admin or specific admin roles
Security Recommendations:
Option 1: Keep Global Admin with Enhanced Security (Recommended for Full Functionality)
- Maintain Global Administrator role on CIPPServiceAccount
- Implement strong security controls:
- Strong unique password (25+ characters, random)
- MFA enforced (Microsoft Authenticator required)
- Never use for interactive sign-in (service account only)
- Monitor sign-in logs regularly
- Alert on any interactive sign-ins (should be none)
- Exclude from user-facing apps (only CIPP uses it)
- Create Conditional Access policy (if you have Azure AD Premium):
- Target: CIPPServiceAccount
- Conditions: All locations
- Grant: Require MFA
- Session: Sign-in frequency 1 hour
- Block interactive sign-ins if possible
Option 2: Use Granular Admin Roles (Limited Functionality)
If you want to avoid Global Admin, test these specific roles:
Core Roles:
- User Administrator (manage users)
- License Administrator (manage licenses)
- Exchange Administrator (manage mailboxes)
- SharePoint Administrator (manage SharePoint)
- Teams Administrator (manage Teams)
- Security Administrator (security settings)
To Test:
- Remove Global Administrator from CIPPServiceAccount
- Add specific admin roles above
- Test each CIPP feature you plan to use
- Some features may fail without Global Admin
- Document which roles are minimum required for your use case
Recommended Approach:
- Start with Global Admin for testing and demo
- After identifying which features you actually use
- Test with granular roles to find minimum permissions
- Balance security vs. functionality based on your needs
Break-Glass Account Protection
Your break-glass admin account (admin@yourdomain.onmicrosoft.com) should be protected:
Requirements:
- ✅ Maintain Global Administrator role permanently
- ✅ Strong unique password stored securely
- ✅ Password in password manager AND physical backup in safe
- ✅ Exclude from Conditional Access policies (if implemented)
- ✅ Test quarterly to verify access works
- ✅ Never use for daily admin tasks
- ✅ Only use in emergencies when primary access fails
Monitoring:
- Configure alerts for any sign-ins to this account
- Review audit logs monthly
- Any usage should trigger investigation
CIPP Access Control
Static Web App Roles:
- superadmin: Full access to everything including backend settings
- admin: Standard admin access, no backend settings
- editor: Can modify configurations
- readonly: View-only access
Best Practices:
- Invite each admin with appropriate role level
- Use superadmin sparingly (only for primary CIPP administrators)
- Use admin for day-to-day CIPP users
- Use readonly for auditors or managers who just need visibility
- Review role assignments quarterly
- Remove access for departed employees immediately
To Manage Roles:
- Azure Portal → CIPP Resource Group → Static Web App
- Settings → Role Management
- Add/remove invitations as needed
- Invitations expire and must be accepted within timeframe
Azure Resource Access
Key Vault Access:
- Only Function App managed identity should have access
- Your admin account for emergency troubleshooting
- Never grant access to other users or service principals
- Review access policies monthly
Function App Access:
- Restrict access via Azure RBAC
- Only CIPP administrators should have access
- Enable diagnostic logging
- Monitor execution patterns for anomalies
Network Security (Optional - Advanced)
If you have security requirements:
Private Endpoints:
- Configure Static Web App with private endpoint
- Restrict access to corporate network only
- Requires Azure Premium tier features
VNet Integration:
- Integrate Function App with Virtual Network
- Control outbound traffic
- Requires App Service Plan upgrade (increases cost)
IP Restrictions:
- Configure Static Web App firewall
- Allow only trusted IP ranges
- Balance security with accessibility
Troubleshooting
Common Deployment Issues
Issue: Quota Error - "SubscriptionIsOverQuotaForSku"
Error Message:
Operation cannot be completed without additional quota.
Dynamic VMs quota: 0
Cause: Azure Free tier has zero default quota for Consumption Plan Function Apps in many regions
Solutions (in order of preference):
- Use Alternative (Central US) Template:
- Cancel current deployment
- Use "Deploy to Azure - Alternative (Central US)" button
- Central US has better capacity for free tier subscriptions
- Try Different Regions:
- East US 2
- West US 2
- West Europe
- East Asia
- Avoid: East US, North Europe, Canada Central, France Central
- Upgrade to Pay-As-You-Go:
- Azure Portal → Subscriptions → Your subscription
- Click "Upgrade"
- Add payment method
- Keeps \$200 free credit if within 30 days
- Unlocks quota increase requests
Issue: GitHub Token Validation Fails
Symptoms:
- Deployment validation fails at Review step
- Error mentions GitHub token or repository access
Causes:
- Token expired
- Token has wrong permissions (need classic token with repo scope)
- Token is fine-grained instead of classic
Solutions:
- Create new classic Personal Access Token
- Ensure "repo" scope is checked
- Use the new token in deployment
- Verify repository URLs use YOUR forks, not upstream
Issue: Deployment Succeeds but Static Web App Won't Load
Symptoms:
- Deployment shows success
- Opening Static Web App URL shows blank page or error
Causes:
- GitHub Actions deployment still running
- Code deployment failed
- DNS not propagated yet
Solutions:
- Go to your GitHub CIPP fork → Actions tab
- Check if workflow is still running (orange dot)
- Wait for workflows to complete (green checkmark)
- Can take 5-10 minutes after Azure deployment
- Refresh CIPP URL after GitHub Actions complete
SAM Wizard Issues
Issue: Can't See SAM Setup Wizard
Symptoms:
- Logged into CIPP
- Settings menu visible
- No "SAM Setup Wizard" or "Setup Wizard" option
Cause: Your Static Web App role is "admin" instead of "superadmin"
Solution:
- Azure Portal → Static Web App → Settings → Role Management
- Check your invitation role
- If it shows "admin", delete the invitation
- Create new invitation with role "superadmin"
- Accept new invitation
- Log out of CIPP completely (close all tabs)
- Open CIPP in new incognito window
- Log in with your admin account
- SAM Setup Wizard should now be visible
Issue: "Authorization_RequestDenied" Error When Connecting Tenant
Error Message:
{"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation."}}
Cause: CIPP-SAM app registration doesn't have admin consent for Microsoft Graph permissions
Solution:
- portal.azure.com → Microsoft Entra ID → App registrations → All applications
- Search for "CIPP-SAM"
- Click on it → API permissions
- Check Status column - should all show "Granted for [Your Tenant]"
- If any show "Not granted":
- Click "Grant admin consent for [Your Tenant]" at top
- Click "Yes"
- Wait 5-10 minutes for propagation
- Return to CIPP → SAM Setup Wizard
- Delete failed tenant connection from Azure Storage:
- Azure Portal → CIPP Resource Group → Storage Account
- Storage browser → Tables → Tenants
- Delete any "TenantFailed" entries
- Retry tenant connection in SAM wizard Step 3
Issue: "Access to this CIPP API endpoint is not allowed"
Error Message:
Access to this CIPP API endpoint is not allowed, the user does not have the required permission
Cause: CIPPServiceAccount lacks necessary admin role for the operation being performed
Solution:
- Microsoft Entra ID → Users → CIPPServiceAccount
- Assigned roles → Verify Global Administrator is assigned
- If not assigned:
- Click Add assignments
- Select Global Administrator
- Click Add
- Wait 5 minutes for role to propagate
- Retry operation in CIPP
Alternative (For Specific Operations):
- Add specific admin role instead of Global Admin:
- License Administrator (for license operations)
- User Administrator (for user operations)
- Exchange Administrator (for mailbox operations)
- Test if specific role is sufficient for your use case
Issue: Tenant Not Appearing in CIPP
Symptoms:
- SAM wizard completed successfully
- Tenant selector dropdown shows "All Tenants" only
- Tenant list page shows "No records to display"
Causes:
- Background sync hasn't run yet
- Tenant connection failed but error wasn't displayed
- Cache needs clearing
Solutions:
Solution 1: Wait for Timer Function
- CIPP syncs tenants every 15 minutes
- Timer runs at :00, :15, :30, :45 of each hour
- Wait until next interval
- Refresh tenant selector dropdown
- Check Tenant list page again
Solution 2: Check Azure Storage for Errors
- Azure Portal → CIPP Resource Group → Storage Account
- Storage browser → Tables → Tenants
- Look for entries in the table:
- If you see "TenantFailed": Connection failed, check error message
- If empty: Timer hasn't run yet, wait and check back
- If you see your tenant: Frontend cache issue, clear browser cache
Solution 3: Clear Tenant Cache
- CIPP → Tenant Administration → Administration → Tenants
- Look for "Clear Tenant Cache" button (may be in toolbar or actions)
- Click it
- Wait 30 seconds
- Click refresh icon
- Check tenant selector dropdown
Solution 4: Force Timer Function
- Azure Portal → CIPP Resource Group → Function App
- Functions → CIPPTimer
- Try to test/run it (may fail due to timer trigger type)
- Even if test fails, it may trigger a sync
- Wait 2-3 minutes
- Check CIPP tenant list
Issue: "Invalid client secret" During Tenant Connection
Symptoms:
- SAM wizard Step 3 fails
- Error mentions client secret or authentication
Cause: CIPP stored wrong value in Key Vault (Secret ID instead of Secret VALUE)
Solution:
- portal.azure.com → Microsoft Entra ID → App registrations → CIPP-SAM
- Certificates & secrets
- + New client secret
- Description: "CIPP-Manual-Fix"
- Expires: 24 months
- Click Add
- IMMEDIATELY copy the VALUE column (NOT Secret ID)
- Value looks like:
abc~XYZ123def456... - Go to CIPP → Settings → SAM Setup Wizard
- Navigate to Step 2
- Choose "Update existing credentials" or "Manually enter credentials"
- Paste:
- Application ID: (get from CIPP-SAM app Overview)
- Application Secret: The VALUE you just copied
- Tenant ID: Your tenant ID
- Save and proceed to Step 3
- Retry tenant connection
Service Account Authentication Issues
Issue: Service Account MFA Not Working
Symptoms:
- Attempting to authenticate as CIPPServiceAccount
- MFA prompt doesn't appear, or fails
- Error about authentication requirements
Causes:
- Third-party MFA (Duo, Okta) configured instead of Microsoft MFA
- MFA not configured at all
- Conditional Access blocking the account
Solutions:
- Verify Microsoft Native MFA:
- Entra ID → Users → CIPPServiceAccount → Authentication methods
- Should show: Microsoft Authenticator or Phone
- Should NOT show: Third-party MFA provider
- Reset MFA Registration:
- Entra ID → Users → CIPPServiceAccount → Authentication methods
- Click "Require re-register multifactor authentication"
- Open incognito browser
- Sign in to portal.office.com as CIPPServiceAccount
- Complete MFA setup with Microsoft Authenticator
- Check Conditional Access:
- Entra ID → Security → Conditional Access
- Review policies that target "All users" or specific groups
- Ensure CIPPServiceAccount isn't blocked
- Temporarily exclude CIPPServiceAccount from policies for testing
Issue: Accidentally Locked Out of CIPP
Symptoms:
- Cannot log into CIPP portal
- "You do not have access" error
- Invitation expired or deleted
Solution:
- Azure Portal → CIPP Resource Group → Static Web App
- Settings → Role Management
- Find your invitation:
- If exists: Check role is "superadmin"
- If wrong role: Delete and recreate
- If missing: Create new invitation
- Create invitation:
- Email: your-admin@yourdomain.com
- Role: superadmin
- Generate and accept invitation
- Close all CIPP browser tabs
- Open CIPP in new incognito window
- Log in with your admin account
Cost Management
Expected Monthly Costs
Typical Costs (Single Tenant):
- Function App (Consumption): \$3-7
- Static Web App (Free tier): \$0
- Storage Account: \$3-5
- Key Vault: \$3-5
- App Service Plan: \$0 (Consumption)
- Total: \$15-20/month
Cost Factors:
Function App:
- Charged per execution and compute time
- Free grants: 400,000 GB-seconds and 1 million executions/month
- Typical CIPP usage stays within free grants
- Actual charges: \$3-7/month for storage transactions
Storage Account:
- Table storage for tenant data
- Blob storage for logs
- Transactions charged per operation
- Typical: \$3-5/month
Key Vault:
- Secret operations charged per 10,000 operations
- CIPP retrieves secrets frequently
- Typical: \$3-5/month
Static Web App:
- Free tier: 100 GB bandwidth/month
- CIPP easily stays within free tier
- Cost: \$0
Multi-Tenant Cost Scaling
Managing 2-5 Tenants:
- Minimal cost increase
- Expected: \$18-25/month
- Function executions increase slightly
- Storage grows modestly
Managing 10+ Tenants:
- Noticeable increase in function executions
- Storage grows linearly with tenant count
- Expected: \$30-50/month
- Still very cost-effective for multi-tenant management
Managing 50+ Tenants:
- May require Function App performance upgrades
- Consider Premium plan for better performance
- Expected: \$100-200/month
- Consult CIPP documentation for optimization strategies
Cost Optimization Tips
1. Monitor Cold Starts
Issue:
- Function Apps "sleep" after inactivity (15-20 minutes)
- First request after sleep is slow (cold start)
- Affects user experience but saves money
Options:
- Accept cold starts (free, recommended for testing)
- Keep-alive pings (minimal cost increase):
- Azure Logic App pings API every 4 minutes during business hours
- Prevents cold starts when you need CIPP
- ~\$2-3/month for Logic App
- Only ping during work hours (8am-6pm) to minimize cost
2. Optimize Storage
- Table storage retention: CIPP manages this automatically
- Blob storage cleanup: Review logs quarterly, delete old logs if needed
- Typical savings: Minimal, but prevents unbounded growth
3. Monitor Function Executions
- Azure Portal → Function App → Metrics
- Monitor "Function Execution Count"
- If unusually high:
- Check for stuck workflows
- Review scheduled tasks
- Optimize frequency of background jobs
4. Use Free Tier Features
- Static Web App: Stay on Free tier (sufficient for most users)
- Application Insights: Free tier includes 5 GB/month (plenty for CIPP)
- Don't upgrade unless you hit actual limits
5. Set Budget Alerts
- Create budget with \$30 limit (buffer above expected cost)
- Alert at 80% (\$24) to investigate before month end
- Investigate spikes immediately
- Common causes: Runaway functions, data retention issues
Shutting Down CIPP (Cost Avoidance)
For Testing/Temporary Deployments:
To Stop Costs Without Losing Configuration:
- Azure Portal → CIPP Resource Group → Function App
- Click "Stop" in command bar
- Static Web App → Configuration → Disable
- Costs drop to near-zero (only storage charges)
- To resume: Start Function App and enable Static Web App
To Completely Remove:
- Export any data/configuration you want to keep
- Document settings for recreation if needed
- Azure Portal → Resource Groups → CIPP Resource Group
- Click "Delete resource group"
- Type resource group name to confirm
- Click "Delete"
- Also delete CIPP-SAM app registration:
- Entra ID → App registrations → All applications → CIPP-SAM → Delete
- All costs stop immediately
Cost After Deletion:
- \$0/month
- Can redeploy at any time using this guide
- GitHub forks remain intact for redeployment
Maintenance and Updates
Keeping CIPP Updated
CIPP updates deploy automatically when you sync your GitHub forks.
Update Process:
- Go to your CIPP fork on GitHub
- You'll see a message: "This branch is X commits behind KelvinTegelaar:main"
- Click "Sync fork"
- Click "Update branch"
- CRITICAL: Never click "Discard commits" - this deletes important workflow files
- Repeat for CIPP-API fork
- GitHub Actions automatically deploy updates to Azure
- Wait 5-10 minutes for deployment
- Refresh CIPP interface
After Updates:
- Navigate to CIPP → Settings → CIPP → Permissions
- Click "Run Permissions Check"
- If new permissions needed, click "Repair Permissions"
- New versions sometimes require additional Microsoft Graph permissions
- Grant admin consent if prompted
Update Frequency:
- Check for updates weekly or monthly
- Security updates: Apply immediately
- Feature updates: Review changelog, apply when ready
- Breaking changes: Read release notes carefully
Monitoring CIPP Health
Daily Checks (Automated):
- Set up email alerts for Azure budget thresholds
- Monitor Azure Service Health for region issues
- Function App automatically restarts on errors
Weekly Checks (Manual):
- Verify CIPP loads correctly
- Test key functionality (user management, license assignment)
- Check Azure costs are within expected range
- Review any error notifications received
Monthly Checks:
- Review Azure cost breakdown
- Check for CIPP updates and apply
- Review audit logs for suspicious activity
- Verify Key Vault access policies unchanged
- Test break-glass admin account still works
Quarterly Checks:
- Review Static Web App role assignments
- Verify service account permissions still appropriate
- Update documentation for any configuration changes
- Review and clean up old data if needed
Backup and Disaster Recovery
What to Back Up:
Critical Configuration:
- CIPP-SAM Application ID (from Entra ID)
- Your Tenant ID
- Static Web App URL
- Custom domain configuration (if used)
- Azure Resource Group name and region
How to Back Up:
- Document in password manager or secure documentation
- Export CIPP settings if available
- Screenshot important configurations
- Store GitHub fork URLs
Recovery Scenarios:
Scenario 1: Accidentally Deleted CIPP Resource Group
- Redeploy using this guide (30-45 minutes)
- Use same GitHub forks
- Complete SAM wizard again
- Tenant connections must be re-established
- Custom configurations must be re-applied
Scenario 2: CIPP-SAM App Deleted
- Run SAM Setup Wizard again
- Choose "Create application for me"
- Grant admin consent
- Reconnect tenants
- Verify permissions check passes
Scenario 3: Lost Access to CIPP
- Azure Portal → Static Web App → Role Management
- Re-invite yourself with superadmin role
- Accept invitation
- Log in to CIPP
Scenario 4: Service Account Compromised
- Immediately reset service account password
- Reset MFA on service account
- Review audit logs for unauthorized activity
- Rotate CIPP-SAM client secret:
- Entra ID → App registrations → CIPP-SAM → Certificates & secrets
- Create new client secret
- Update in CIPP via SAM wizard Step 2
- Review all CIPP changes during compromise period
- Notify affected parties if data accessed
Appendix
Glossary
Azure Terms:
- Resource Group: Container that holds related Azure resources
- Static Web App: Azure service for hosting static websites (React, Vue, etc.)
- Function App: Serverless compute service for running code on-demand
- Key Vault: Secure storage for secrets, keys, and certificates
- Storage Account: Scalable storage for blobs, tables, queues, files
- App Service Plan: Defines compute resources for web apps and function apps
- Consumption Plan: Pay-per-use pricing for Function Apps
Microsoft 365 Terms:
- Entra ID: Microsoft's cloud identity service (formerly Azure Active Directory)
- Tenant: An instance of Microsoft 365 services for an organization
- Global Administrator: Highest privilege role in Microsoft 365
- Delegated Permissions: Permissions granted to an app to act on behalf of a user
- Admin Consent: Tenant-wide approval for an app's permissions
- Service Principal: Identity used by apps/services to access resources
CIPP Terms:
- SAM (Secure Application Model): Microsoft's framework for secure app authentication
- CIPP-SAM: The app registration CIPP creates for authentication
- Partner Tenant: The tenant hosting CIPP (where Azure resources live)
- Managed Tenant: Tenants you manage through CIPP
- Refresh Token: Long-lived credential allowing CIPP to access M365 APIs
- Tenant Mode: Setting that determines single vs. multi-tenant operation
Useful Links
CIPP Resources:
- Official Documentation: https://docs.cipp.app
- GitHub Repository: https://github.com/KelvinTegelaar/CIPP
- GitHub API Repository: https://github.com/KelvinTegelaar/CIPP-API
- Discord Community: https://discord.gg/cyberdrain (look for #cipp-community-help)
- CyberDrain Blog: https://www.cyberdrain.com
Microsoft Resources:
- Azure Portal: https://portal.azure.com
- Microsoft 365 Admin Center: https://admin.microsoft.com
- Entra ID Portal: https://entra.microsoft.com
- Microsoft Graph Explorer: https://developer.microsoft.com/graph/graph-explorer
- Azure Pricing Calculator: https://azure.microsoft.com/pricing/calculator/
Learning Resources:
- Microsoft Learn - Azure Fundamentals: https://learn.microsoft.com/training/azure/
- Microsoft Graph Documentation: https://learn.microsoft.com/graph/
- Azure Function Apps Guide: https://learn.microsoft.com/azure/azure-functions/
Version History
Version 1.0 (December 31, 2024)
- Initial comprehensive guide
- Based on production deployment and troubleshooting experience
- Covers all known issues and solutions
- Tested on Azure Free → Pay-As-You-Go subscription
- Single tenant and multi-tenant scenarios
Future Updates Will Include:
- Advanced multi-tenant configurations
- GDAP setup for MSP scenarios
- Standards and baselines configuration
- Advanced automation examples
- Performance optimization for large deployments
Document Maintenance
This document should be updated when:
- CIPP releases breaking changes
- Azure deployment templates change
- New common issues discovered
- Microsoft Graph permission requirements change
- Cost structures change significantly
Last Reviewed: December 31, 2024
Next Review Due: March 31, 2025
Document Owner: Jeff Ricica
Contact: jeff@triaxis.tech
End of Document