Skip to content

Azure Entra and M365

Azure Entra is federated with Google Workspace via SAML and SCIM. Google is the authoritative identity source. Azure Entra receives users via SCIM sync and provides M365 application access.

Architecture

Google Workspace (authoritative identity)
         ├── SAML federation → Azure Entra (domain federation)
         │                       Users authenticate via Google SSO
         └── SCIM provisioning → Azure Entra (user objects)
                                  Group membership triggers license assignment

Google Workspace handles all authentication. Azure Entra stores user objects (synced from GWS via SCIM) and manages M365 licenses and application access.

Integration Components

Component Purpose
SAML federation (setup_federation.yml) Federate cwiq.io domain so Azure accepts GWS as the identity provider
SCIM provisioning (GWS App Autoprovisioning) Sync GWS users to Azure Entra user objects
Group-based license assignment (assign_group_license.yml) Assign M365 licenses to Azure Entra groups

M365 License Assignment

The primary operation for day-to-day use is assigning M365 licenses to users via the cwiq-io-m365 Google Workspace group:

  1. Admin adds user to cwiq-io-m365 GWS group (via "Onboard New Hire" template with grant_m365=yes, or manually)
  2. GWS SCIM autoprovisioning syncs the user to Azure Entra and adds them to the cwiq-io-m365 Entra group
  3. Group-based license assignment automatically assigns M365 Business Premium to the new group member
  4. Propagation takes up to 10 minutes

License SKUs

SKU Part Number Product Price
SPB Microsoft 365 Business Premium ~$22/user/month
POWER_BI_STANDARD Microsoft Fabric Free Free
POWERAPPS_DEV Power Apps for Developer Free
FLOW_FREE Power Automate Free Free

Managing Group Licenses

ssh ansible@ansible-shared-cwiq-io
ansible-helper

# List available license SKUs in the tenant
ansible-playbook azure/assign_group_license.yml --tags list-skus

# Check current license status of the M365 group
ansible-playbook azure/assign_group_license.yml --tags status \
  -e "license_group_name=cwiq-io-m365"

# Dry-run: preview what would happen
ansible-playbook azure/assign_group_license.yml \
  -e "license_group_name=cwiq-io-m365 license_sku=SPB license_dry_run=true"

# Assign M365 Business Premium to a group
ansible-playbook azure/assign_group_license.yml \
  -e "license_group_name=cwiq-io-m365 license_sku=SPB"

# Remove a license from a group
ansible-playbook azure/assign_group_license.yml --tags remove \
  -e "license_group_name=cwiq-io-m365 license_sku=SPB"

Group-based licensing requires Azure AD P1

This feature is included in M365 Business Premium. License assignment propagates to all group members within minutes and applies automatically to future members.

SCIM Attribute Mapping

The GWS → Azure Entra SCIM sync maps these attributes:

GWS Attribute Azure Entra Attribute
Formatted name displayName
First name givenName
Last name surname
Primary email userPrincipalName (required)
Primary email onPremisesImmutableId (required)
Alias name mailNickname (required)
Title jobTitle
Department department
Locality city
Country country
Postal code postalCode
Region state
Address streetAddress
Phone mobilePhone

Initial Setup (One-Time)

This section documents the federation and SCIM setup that has already been completed. Only needed for new deployments or disaster recovery.

Azure App Registration

  1. Azure Entra > App registrations > New registration
  2. Grant Microsoft Graph application permissions:
  3. Domain-InternalFederation.ReadWrite.All
  4. Domain.Read.All
  5. User.ReadWrite.All
  6. Group.ReadWrite.All
  7. GroupMember.ReadWrite.All
  8. Organization.Read.All
  9. Grant admin consent for the tenant

M365 SAML App in Google Workspace

  1. GWS Admin Console > Apps > Web and mobile apps > Add app > Microsoft 365 Web (SAML)
  2. Service provider details:
  3. Start URL: https://portal.office.com
  4. Name ID: Basic Information > Primary email
  5. SAML attribute mapping: see table above
  6. Download GoogleIDPMetadata.xml
  7. User access: enable only for cwiq.io domain (off for any others)

Domain Federation

# Configure federation (one-time, uses GoogleIDPMetadata.xml)
ansible-playbook azure/setup_federation.yml

SCIM Autoprovisioning (GWS)

  1. GWS > Apps > Web and mobile apps > Microsoft Office 365 > Autoprovisioning
  2. Authorize the app
  3. Configure attribute mapping as per the table above
  4. Set provisioning scope to cwiq-io-pilot group
  5. Deprovisioning settings: uncheck all "suspend account" options (GWS suspension should not propagate to Azure)
  6. Activate autoprovisioning

Troubleshooting

Symptom Cause Fix
User not appearing in Azure Entra Not in cwiq-io-pilot GWS group Add user to cwiq-io-pilot group, wait for SCIM sync (up to 15 min)
M365 license not assigned User not in cwiq-io-m365 GWS group Add user to cwiq-io-m365 GWS group
License propagation delayed Normal Azure behavior Wait up to 10 minutes after group membership change
"Permission denied" in playbook App registration missing Graph permissions Add required permissions and grant admin consent