Stage 2 · EasyPIM.Orchestrator

Bring privileged access under EasyPIM.Orchestrator control

Store your PIM model in JSON, preview drift, and apply approved policies and assignments consistently across Entra, Azure, and group roles.

  • Configuration-as-code covering policy expectations, assignments, and protected users.
  • Safety-first workflow with WhatIf previews, WouldRemove exports, and drift reports.
  • Reusable templates to enforce the same requirements everywhere without copy/paste.
  • Scoped overrides that document the rare roles needing different guardrails.

Step 1 · Model your privileged access as code

EasyPIM.Orchestrator reads a single configuration file that captures policy expectations and assignments for Entra roles, Azure RBAC, and privileged groups so you can version control every change.

Single configuration source

Track policy baselines, assignments, ProtectedUsers, and metadata together under source control.

Deterministic apply

EasyPIM.Orchestrator resolves the JSON into concrete policies and assignments before touching your tenant.

CI/CD ready

Run the same file locally, in GitHub Actions, or Azure DevOps with OIDC authentication and audit-friendly exports.

{
  "PolicyTemplates": {}, #empty for clarity, see step 2 to learn more
  "EntraRoles": {
    "Policies": {
      "Security Reader": { "Template": "HighSecurity" }
    }
  },
  "AzureRoles": {
    "Policies": {
      "Reader": {
        "Scope": "/subscriptions/<subscriptionId>",
        "Template": "HighSecurity"
      }
    }
  },
  "Assignments": {
    "EntraRoles": [
      {
        "roleName": "Security Reader",
        "assignments": [
          {
            "principalId": "11111111-2222-3333-4444-555555555555",
            "principalType": "User",
            "assignmentType": "Eligible",
            "duration": "P30D",
            "justification": "Baseline Tier-0 review cadence"
          }
        ]
      }
    ]
  }
}

Treat the JSON like any other infrastructure code

Store the configuration in Git, require pull requests, and let orchestrator commands enforce the approved state in every environment.

Step 2 · define reusable policy templates

Capture your default approval, activation, and notification requirements inside the PolicyTemplates block so every role can inherit the same guardrails.

{
  "PolicyTemplates": {
    "HighSecurity": {
      "ActivationDuration": "PT4H",
      "ActivationRequirement": "MultiFactorAuthentication,Justification,Ticketing",
      "ApprovalRequired": true,
      "Approvers": [
        {
          "id": "11111111-2222-3333-4444-555555555555",
          "description": "Privileged Access CAB"
        }
      ],
      "AllowPermanentEligibility": false,
      "MaximumEligibilityDuration": "P30D",
      "Notification_Activation_Alert": {
        "isDefaultRecipientEnabled": true,
        "notificationLevel": "All",
        "Recipients": ["soc-alerts@contoso.com"]
      }
    }
  }
}

Template keys = telemetry context

Use descriptive template names (HighSecurity, Tier0, FinanceSOX). They appear in drift reports, WhatIf output, and telemetry, making it obvious which safeguard is in effect.

Step 3 · reference the template in your role policies

Define each role in the policy block and point it at the shared template. Set PolicySource to "template" so diffs stay explicit.

{
  "EntraRoles": {
    "Policies": [
      {
        "RoleName": "Security Administrator",
        "PolicySource": "template",
        "Template": "HighSecurity"
      },
      {
        "RoleName": "Privileged Role Administrator",
        "PolicySource": "template",
        "Template": "HighSecurity"
      }
    ]
  }
}

One template for different resources

Because they share common structure a single template can be applied to Entra and Azure roles

Step 4 · add inline overrides when a role needs something special

Only specify the fields that differ from the template. EasyPIM merges your overrides with the template and records the resulting payload as ResolvedPolicy for auditing.

Configuration excerpt

{
  "EntraRoles": {
    "Policies": [
      {
        "RoleName": "User Access Administrator",
        "PolicySource": "template",
        "Template": "HighSecurity",
        "ActivationRequirement": "MultiFactorAuthentication,Justification,Ticketing",
        "AuthenticationContext_Enabled": true,
        "AuthenticationContext_Value": "c1:HighRiskOperations",
        "Notification_Activation_Alert": {
          "isDefaultRecipientEnabled": true,
          "notificationLevel": "Critical",
          "Recipients": [
            "soc-alerts@contoso.com",
            "compliance@contoso.com"
          ]
        }
      }
    ]
  }
}

What the orchestrator applies

{
  "RoleName": "User Access Administrator",
  "PolicySource": "template",
  "Template": "HighSecurity",
  "ResolvedPolicy": {
    "ActivationDuration": "PT4H",
    "ActivationRequirement": "MultiFactorAuthentication,Justification,Ticketing",
    "ApprovalRequired": true,
    "Approvers": [
      {
        "id": "11111111-2222-3333-4444-555555555555",
        "description": "Privileged Access CAB"
      }
    ],
    "AuthenticationContext_Enabled": true,
    "AuthenticationContext_Value": "c1:HighRiskOperations",
    "AllowPermanentEligibility": false,
    "MaximumEligibilityDuration": "P30D",
    "Notification_Activation_Alert": {
      "isDefaultRecipientEnabled": true,
      "notificationLevel": "Critical",
      "Recipients": [
        "soc-alerts@contoso.com",
        "compliance@contoso.com"
      ]
    }
  }
}

Make the review easy to follow

Include a short note in your change review explaining why this role deviates. Auditors can trace the review back to the JSON line that changed and confirm the override in ResolvedPolicy output.

Step 5 · validate drift and apply with EasyPIM.Orchestrator

Run Test-PIMPolicyDrift to spot configuration deviations, then execute Invoke-EasyPIMOrchestrator once reviewers approve the change.

# Detect drift before merging a pull request
Test-PIMPolicyDrift `
  -TenantId $TENANT_ID `
  -SubscriptionId $SUBSCRIPTION_ID `
  -ConfigPath "./config/pim-template-demo.json" `
  -PassThru |
  Where-Object Status -ne 'Match'
# Apply the approved configuration
Invoke-EasyPIMOrchestrator `
  -ConfigFilePath "./config/pim-template-demo.json" `
  -TenantId $TENANT_ID `
  -SubscriptionId $SUBSCRIPTION_ID `
  -Mode delta `
  -WhatIf `
  -WouldRemoveExportPath "./reports/would-remove"

# When the preview looks good, rerun without -WhatIf

Audit every run

Test-PIMPolicyDrift produces a drift report you can archive, and the orchestrator’s WouldRemove export captures every assignment change for reviewers and auditors.