Skip to main content
Version: Next

Appendix H: B2B Sync Templates

Reference Azure

DOCUMENT CATEGORY: Reference SCOPE: Cross-tenant sync templates PURPOSE: JSON templates for Entra ID B2B sync MASTER REFERENCE: Microsoft Learn - Cross-Tenant Sync

Status: Active


Overview

This appendix contains JSON template files for configuring Entra ID B2B Cross-Tenant Synchronization (CTS) between a management tenant and customer tenants.

These templates provision users as Member type (not Guest), enabling:

  • Full RBAC/PIM support
  • Seamless Azure portal experience
  • Native Azure Local management capabilities

Template Files

FileDescriptionDeployed To
customer-inbound-policy.jsonCross-tenant access policy allowing CTS inboundCustomer Tenant
management-outbound-policy.jsonCross-tenant access policy for outbound syncManagement Tenant
cts-application.jsonCTS application instantiation templateManagement Tenant
cts-credentials.jsonTarget tenant credentials configurationManagement Tenant
cts-provisioning-job.jsonProvisioning job with attribute mappingsManagement Tenant
cts-group-assignment.jsonGroup assignment to CTS configurationManagement Tenant

Template Variables

Replace these placeholders before deployment:

VariableDescriptionExample
{{CUSTOMER_TENANT_ID}}Customer's Entra ID tenant IDa1b2c3d4-e5f6-7890-abcd-ef1234567890
{{CUSTOMER_NAME}}Customer name for display purposesInfinite azurelocal Corp
{{MGMT_TENANT_ID}}Management tenant ID00000000-aaaa-bbbb-cccc-111111111111
{{SERVICE_PRINCIPAL_ID}}CTS service principal ID (from app instantiation)12345678-1234-1234-1234-123456789abc
{{APP_ROLE_ID}}App role ID (from app instantiation)87654321-4321-4321-4321-cba987654321
{{JOB_ID}}Provisioning job ID (from job creation)abcd1234-5678-90ab-cdef-1234567890ab

Service Groups

VariableGroup NameDescription
{{GROUP_ID_OPERATIONS}}OperationsCore operations team
{{GROUP_ID_SUPPORT}}SupportSupport team
{{GROUP_ID_ENGINEERING}}EngineeringImplementation engineers
{{GROUP_ID_ADMINS}}AdminsAdministrative access

Deployment Order

1. Customer Tenant (requires customer admin)

Deploy customer-inbound-policy.json

2. Azure Local Cloud MGMT (requires Azure Local Cloud admin)

  1. Add customer tenant to cross-tenant access settings
  2. Deploy Azure Local Cloud-outbound-policy.json
  3. Deploy cts-application.json → save SERVICE_PRINCIPAL_ID and APP_ROLE_ID
  4. Deploy cts-credentials.json
  5. Deploy cts-provisioning-job.json → save JOB_ID
  6. Deploy cts-group-assignment.json for each required group
  7. Start provisioning job

Customer Inbound Policy

This policy is deployed to the Customer Tenant to allow inbound CTS from the management tenant.

{
"tenantId": "{{MGMT_TENANT_ID}}",
"b2bCollaborationInbound": {
"usersAndGroups": {
"accessType": "allowed",
"targets": [
{
"target": "AllUsers",
"targetType": "user"
}
]
},
"applications": {
"accessType": "allowed",
"targets": [
{
"target": "AllApplications",
"targetType": "application"
}
]
}
},
"b2bCollaborationOutbound": {
"usersAndGroups": {
"accessType": "blocked"
},
"applications": {
"accessType": "blocked"
}
},
"automaticUserConsentSettings": {
"inboundAllowed": true
},
"trustSettings": {
"isCompliantDeviceTrusted": true,
"isHybridAzureADJoinedDeviceTrusted": true,
"isMfaTrusted": true
},
"crossTenantSynchronization": {
"enabled": true
}
}
Key Settings
  • b2bCollaborationInbound: Allows users and applications from Azure Local Cloud
  • automaticUserConsentSettings.inboundAllowed: Auto-consents synced users
  • trustSettings: Trusts MFA, compliant devices, and hybrid-joined devices
  • crossTenantSynchronization.enabled: Enables CTS inbound

Management Outbound Policy

This policy is deployed to the management tenant to allow outbound sync to customer tenants.

{
"tenantId": "{{CUSTOMER_TENANT_ID}}",
"b2bCollaborationOutbound": {
"usersAndGroups": {
"accessType": "allowed",
"targets": [
{
"target": "{{GROUP_ID_OPERATIONS}}",
"targetType": "group"
},
{
"target": "{{GROUP_ID_SUPPORT}}",
"targetType": "group"
},
{
"target": "{{GROUP_ID_ENGINEERING}}",
"targetType": "group"
},
{
"target": "{{GROUP_ID_ADMINS}}",
"targetType": "group"
}
]
},
"applications": {
"accessType": "allowed",
"targets": [
{
"target": "AllApplications",
"targetType": "application"
}
]
}
},
"automaticUserConsentSettings": {
"outboundAllowed": true
},
"trustSettings": {
"isCompliantDeviceTrusted": true,
"isHybridAzureADJoinedDeviceTrusted": true,
"isMfaTrusted": true
},
"crossTenantSynchronization": {
"enabled": true
}
}

CTS Application Template

Creates the Cross-Tenant Synchronization application in the management tenant.

{
"displayName": "CTS to {{CUSTOMER_NAME}}",
"description": "Cross-Tenant Synchronization application for automated user provisioning to {{CUSTOMER_NAME}}",
"signInAudience": "AzureADMultipleOrgs",
"web": {
"redirectUris": [],
"logoutUrl": null,
"implicitGrantSettings": {
"enableAccessTokenIssuance": false,
"enableIdTokenIssuance": false
}
},
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "5b567255-7703-4780-807c-7be8301ae99b",
"type": "Role"
},
{
"id": "df021288-bdef-4463-88db-98f22de89214",
"type": "Role"
}
]
}
]
}

CTS Credentials Template

Configures target tenant credentials for the provisioning job.

{
"value": [
{
"key": "TargetTenantId",
"value": "{{CUSTOMER_TENANT_ID}}"
}
]
}

CTS Provisioning Job Template

Defines the synchronization rules and attribute mappings.

{
"templateId": "Azure2Azure",
"code": "CTS-{{CUSTOMER_NAME}}",
"description": "Cross-Tenant Synchronization provisioning job to {{CUSTOMER_NAME}}",
"enabled": true,
"sourceIdentity": {
"type": "AzureActiveDirectory",
"id": "{{MGMT_TENANT_ID}}"
},
"targetIdentity": {
"type": "AzureActiveDirectory",
"id": "{{CUSTOMER_TENANT_ID}}"
},
"synchronizationRules": [
{
"name": "USER_OUTBOUND_USER",
"sourceDirectory": "AzureActiveDirectory",
"targetDirectory": "AzureActiveDirectory",
"objectMappings": [
{
"sourceObjectName": "User",
"targetObjectName": "User",
"attributeMappings": [
{
"source": { "name": "userPrincipalName", "type": "Attribute" },
"target": { "name": "userPrincipalName", "type": "Attribute" },
"applyOnce": false
},
{
"source": { "name": "displayName", "type": "Attribute" },
"target": { "name": "displayName", "type": "Attribute" },
"applyOnce": false
},
{
"source": { "name": "mail", "type": "Attribute" },
"target": { "name": "mail", "type": "Attribute" },
"applyOnce": false
},
{
"source": { "value": "true", "type": "Constant" },
"target": { "name": "showInAddressList", "type": "Attribute" },
"applyOnce": false
},
{
"source": { "value": "Member", "type": "Constant" },
"target": { "name": "userType", "type": "Attribute" },
"applyOnce": true
}
]
}
]
}
]
}
Member vs Guest

The userType: Member constant ensures synced users get full portal access, RBAC, and PIM eligibility - not limited Guest access.


Deployment Commands

Replace Variables

# Replace variables (example using sed)
sed -e 's/{{CUSTOMER_TENANT_ID}}/actual-tenant-id/g' \
-e 's/{{CUSTOMER_NAME}}/CustomerName/g' \
customer-inbound-policy.json > customer-inbound-policy-deploy.json

Deploy Using Azure CLI

# Deploy cross-tenant access policy
az rest --method PATCH \
--url "https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners/{{CUSTOMER_TENANT_ID}}" \
--body '@customer-inbound-policy-deploy.json' \
--headers Content-Type=application/json

Deploy Using PowerShell

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Policy.ReadWrite.CrossTenantAccess"

# Update cross-tenant access policy
$policy = Get-Content -Path "customer-inbound-policy-deploy.json" | ConvertFrom-Json
Update-MgPolicyCrossTenantAccessPolicyPartner -CrossTenantAccessPolicyConfigurationPartnerTenantId $CustomerTenantId -BodyParameter $policy

Verification

Check Sync Status

# Get provisioning job status
Get-MgServicePrincipalSynchronizationJob -ServicePrincipalId $ServicePrincipalId

# Get provisioning logs
Get-MgAuditLogProvisioning -Filter "jobId eq '$JobId'" -Top 10

Verify User Sync

# In customer tenant - check synced users
Get-MgUser -Filter "userType eq 'Member' and creationType eq 'Invitation'" | Select-Object DisplayName, UserPrincipalName, UserType

Troubleshooting

Sync Not Starting

  1. Verify cross-tenant access policies on both tenants
  2. Check CTS is enabled in both policies
  3. Verify group assignments include target groups
  4. Check provisioning job is enabled

Users Not Appearing as Members

  1. Verify userType: Member in attribute mappings
  2. Check applyOnce: true for userType (prevents overwrite)
  3. Re-provision affected users

Permission Errors

  1. Verify Microsoft Graph API permissions granted
  2. Check admin consent provided
  3. Verify service principal has required roles