Operations

Baseline Repository Setup

The baseline repository is a configuration-only store of JSON policy files deployed to every managed tenant. This guide covers how to create it, populate it, and keep it maintained.

5 min read Updated March 22, 2026

What Is the Baseline Repository?

Config-only

No pipeline execution. Purely JSON policy files.

Shared by all

Every tenant pipeline checks out baseline at runtime.

Version controlled

All changes tracked in Git with descriptive commit messages.

Important: The baseline repo does not connect to any tenant and never runs deployments. It is purely a store for configuration files. Tenant pipelines check it out and apply the configs.

Step 1: Create the Repository

  1. 1. Go to Repos → New repository
  2. 2. Name: baseline
  3. 3. Project: {YourProject}
  4. 4. Click Create

Step 2: Populate Baseline Configurations

Option A: Export from Reference Tenant (Recommended)

If you have a reference M365 tenant with your standard policies, back it up and copy the JSON files into baseline.

1

Create a reference tenant

Onboard a reference tenant in the CONFIG365 portal. This creates a tenant-reference Gitea repo with the reference tenant's credentials.

2

Run the backup pipeline

Run the pipeline with "Run Backup Stage" enabled. JSON files are committed to backups/ in the repo.

3

Copy to baseline

Copy backups/groups/*.json → baseline/groups/, backups/conditional-access/* → baseline/conditional-access/, etc.

4

Placeholders are already applied

The backup pipeline automatically outputs files with {{GROUP:name}}, {{LOCATION:name}}, and {{TENANTID}} instead of hardcoded IDs. No manual replacement needed.

Option B: Create JSON Files Manually

In Gitea, navigate to the baseline repository → Files → the appropriate subfolder → ⋯ → New File, or push directly via Git. Example group file:

baseline/groups/Baseline - Emergency Access.json
{
  "displayName": "Baseline - Emergency Access",
  "description": "Emergency access accounts excluded from CA policies",
  "mailEnabled": false,
  "securityEnabled": true,
  "mailNickname": "baseline-emergency-access"
}

Step 3: Verify Repository Structure

baseline/
├── baseline/
│   ├── authentication-policies/
│   │   ├── microsoft-authenticator.json
│   │   └── passkeys-fido2.json
│   ├── conditional-access/
│   │   ├── named-locations/
│   │   │   └── AVD.json
│   │   ├── policies/
│   │   │   └── Baseline - *.json  (30+ policies)
│   │   └── optional-applications.json
│   ├── custom-attributes/
│   │   ├── attribute-definitions/
│   │   │   └── BaselineCSAAppExclusions_CAExclusion.json
│   │   └── attribute-sets/
│   │       └── BaselineCSAAppExclusions.json
│   ├── enterprise-apps/
│   ├── entra-id-consentpermissions/
│   │   ├── permissionClassifications/
│   │   │   └── low.json
│   │   └── policies/
│   │       ├── admin-consent-request-policy.json
│   │       └── authorization-policy.json
│   ├── entra-id-device-settings/
│   │   ├── device-registration-policy.json
│   │   └── entra-id-settings.json
│   ├── exchange/
│   │   └── transport-rules/
│   │       └── Baseline - *.json  (3 rules)
│   ├── groups/
│   │   └── Baseline - *.json  (50+ groups)
│   ├── intune/
│   │   ├── app-protection/
│   │   │   └── Android_Baseline - *.json / iOS_Baseline - *.json
│   │   ├── autopilot/
│   │   ├── compliance-policies/
│   │   │   └── Baseline - *.json / *.assignment.json
│   │   ├── platform-scripts-powershell/
│   │   │   └── Baseline - *.json / *.ps1 / *.assignment.json
│   │   ├── platform-scripts-bash/
│   │   │   └── Baseline - *.json / *.sh / *.assignment.json
│   │   ├── settings-catalog/
│   │   │   └── Baseline - *.json / *.assignment.json
│   │   ├── windows-driver-updates/
│   │   ├── windows-feature-updates/
│   │   ├── windows-quality-updates/
│   │   └── windows-updates/
│   ├── sharepoint-settings/
│   │   └── sharepoint-sharingCapability.json
│   └── teams/
├── baseline-remove/
└── README.md

Step 4: Maintenance

Updating Baseline Configurations

Edit the JSON file directly in Gitea or via Git, commit with a descriptive message:

git commit -m "Baseline update: Enable MFA policy (was report-only)"

Always test baseline changes with a single tenant pipeline before rolling out to all tenants.

Removing Resources from Tenants

To remove a resource from all tenants, add a minimal JSON file to baseline-remove/ matching the subfolder type:

baseline-remove/conditional-access/Old Deprecated Policy.json
{
  "displayName": "Old Deprecated Policy"
}

Cross-Tenant Placeholders

Use placeholders for values that differ per tenant. The deployment scripts resolve them by querying the target tenant before applying the configuration.

{{GROUP:Baseline - Emergency Access}}

Replaced with the group's object ID in the target tenant

Used in: excludeGroups or groupId fields

{{LOCATION:Corporate Offices}}

Replaced with the named location ID in the target tenant

Used in: includeLocations fields

{{TENANTID}}

Replaced with the tenant's Tenant ID

Used in: Cross-tenant references

Example CA policy using group placeholder
{
  "displayName": "Baseline - Require MFA",
  "state": "enabledForReportingButNotEnforced",
  "conditions": {
    "users": {
      "includeUsers": ["All"],
      "excludeGroups": ["{{GROUP:Baseline - Emergency Access}}"]
    }
  }
}

Common Issues

Baseline files not loading in tenant pipeline

Solution: Check the pipeline resources section — the baseline repository must be referenced as a repository resource with ref: refs/heads/main

Group not found error

Solution: Groups must be deployed before policies that reference them. Check the group displayName matches exactly (case-sensitive). Use {{GROUP:displayname}} placeholder syntax.

Changes not taking effect

Solution: Verify changes are committed and pushed to baseline, then re-run the tenant pipeline. Check the Plan output shows expected changes.