Skip to content

Control 2.8: Access Control and Segregation of Duties

Overview

Control ID: 2.8 Control Name: Access Control and Segregation of Duties Regulatory Reference: SOX 302/404, FINRA 4511, GLBA 501(b), SEC 17a-4 Setup Time: 2-3 hours initial setup, ongoing quarterly reviews

Purpose

This control establishes access control mechanisms and segregation of duties (SoD) for AI agent governance in financial institutions. Regulatory frameworks require that no single individual can initiate, approve, and deploy agents to production without independent review. This control defines role-based access, approval workflows, and continuous access monitoring to prevent unauthorized changes and ensure compliance with SOX, FINRA, and other FSI regulations.


Prerequisites

Primary Owner Admin Role: Power Platform Admin Supporting Roles: Dataverse System Admin, Entra Privileged Role Admin

Required Licenses

  • Microsoft Entra ID P1/P2 (for access reviews and PIM)
  • Power Platform per-user or per-app licenses
  • Microsoft 365 E3/E5 (for Compliance Center)

Required Permissions

  • Global Administrator or Privileged Role Administrator (Entra ID PIM)
  • Power Platform Administrator (security role management)
  • Compliance Administrator (access review configuration)

Important - Admin Self-Elevation Required: Power Platform administrators must now self-elevate to the System Administrator role within each environment to manage security roles. This is no longer automatic. See Manage high-privileged admin roles for details.

Dependencies

  • Control 1.1 (Restrict Agent Publishing)
  • Control 1.18 (Application-Level RBAC)
  • Control 2.3 (Change Management)

Pre-Setup Checklist

  • [ ] Role definitions documented and approved
  • [ ] Separation requirements identified per regulation
  • [ ] Access review cadence determined
  • [ ] Approval workflow stakeholders identified

Governance Levels

Baseline (Level 1)

Implement least-privilege access; separate creator, reviewer, approver roles.

Automated access reviews; quarterly recertification; automated deprovisioning.

Regulated/High-Risk (Level 4)

Mandatory segregation of duties; no single person can approve and deploy; continuous access monitoring.


Setup & Configuration

Step 1: Define Agent Governance Roles

Establish role hierarchy with clear separation of duties.

Agent Governance Role Matrix:

Role Create/Edit Review Approve Deploy to Prod Manage Config
Agent Developer
Agent Reviewer
Agent Approver
Release Manager
Platform Admin
AI Governance Lead ✅ (read) ✅ (read) ✅ (read) ✅ (read)

Step 2: Create Security Groups in Entra ID

Microsoft Entra Admin Center:

  1. Navigate to entra.microsoft.com
  2. Go to IdentityGroupsAll groups
  3. Click New group
  4. Create the following groups:
Group Name Type Purpose
SG-Agent-Developers Security Agent creation and editing
SG-Agent-Reviewers Security Agent review and testing
SG-Agent-Approvers Security Agent approval for production
SG-Agent-ReleaseManagers Security Production deployment
SG-PowerPlatform-Admins Security Platform configuration
SG-AI-Governance-Leads Security Read-only oversight access
  1. Configure Membership rules for dynamic groups if applicable

Step 3: Configure Power Platform Security Roles

Power Platform Admin Center:

  1. Navigate to admin.powerplatform.microsoft.com
  2. Select your Production environment
  3. Go to SettingsUsers + permissionsSecurity roles
  4. Create custom security roles:

Agent Developer Role:

  • Environment Maker (base)
  • Custom permissions:
  • Copilot Studio: Create, Read, Write (own)
  • Solutions: Create, Read, Write (own)
  • Flows: Create, Read, Write (own)
  • No publish permissions

Agent Reviewer Role:

  • Basic User (base)
  • Custom permissions:
  • Copilot Studio: Read (all)
  • Solutions: Read (all)
  • Test framework: Full access
  • No write or publish permissions

Agent Approver Role:

  • Basic User (base)
  • Custom permissions:
  • Approval entity: Full access
  • Copilot Studio: Read (all)
  • Environment: Read settings
  • No deployment permissions

Release Manager Role:

  • Environment Maker (base)
  • Custom permissions:
  • Solutions: Import (all)
  • Copilot Studio: Publish (all)
  • No create/edit permissions

Step 4: Implement Privileged Identity Management (PIM)

For Tier 3 Enterprise agents, require just-in-time access.

Microsoft Entra Admin Center:

  1. Navigate to entra.microsoft.com
  2. Go to Identity governancePrivileged Identity Management
  3. Click Azure AD rolesRoles
  4. Configure PIM for agent governance roles:

For Power Platform Administrator:

  1. Click the role → Settings
  2. Configure:
  3. Activation maximum duration: 4 hours
  4. On activation, require: MFA, Justification, Ticket information
  5. On active assignment, require: MFA
  6. Require approval: Yes
  7. Select approvers: AI Governance Lead, CISO

For Agent Deployment roles:

  1. Create custom Entra ID role for deployment (if using Azure DevOps integration)
  2. Add to PIM with same approval requirements
  3. Assign as "Eligible" not "Active"

Step 5: Configure Approval Workflows with Segregation

Build Power Automate workflow enforcing segregation of duties.

Create Approval Flow:

  1. Navigate to make.powerautomate.com
  2. Create new Automated cloud flow
  3. Trigger: When agent marked "Ready for Review" in Dataverse
  4. Implement SoD checks:
// Pseudocode for approval logic
1. Get RequestorId (who created/modified agent)
2. Get list of eligible approvers from SG-Agent-Approvers
3. EXCLUDE RequestorId from eligible approvers
4. If no eligible approvers remain:
   - Escalate to AI Governance Lead
   - Log SoD exception
5. Route to eligible approvers
6. Require approval from 2 different approvers (for Tier 3)
7. Validate deployer ≠ creator ≠ approvers
8. Log all decisions with timestamps

Step 6: Enable Access Reviews

Microsoft Entra Admin Center:

  1. Navigate to entra.microsoft.com
  2. Go to Identity governanceAccess reviews
  3. Click New access review

Configure Quarterly Review:

  • Review name: Agent Governance Roles - Quarterly
  • Frequency: Quarterly
  • Scope: Selected groups (all SG-Agent-* groups)
  • Reviewers: Group owners
  • Auto-apply results: Yes
  • If reviewers don't respond: Remove access
  • Enable reviewer decision helper: Yes

Step 7: Configure Access Analytics and Monitoring

Microsoft Entra Admin Center:

  1. Navigate to entra.microsoft.com
  2. Go to IdentityMonitoring & healthSign-in logs
  3. Create saved view for agent governance sign-ins
  4. Filter by application: Power Platform, Copilot Studio

Create Alert for Unusual Access:

  1. Go to Azure portalMonitorAlerts
  2. Create new alert rule:
  3. Condition: Sign-in from unusual location for Power Platform Admin
  4. Action: Email security team, create incident

Step 8: Implement Continuous Access Evaluation

Enable CAE for Power Platform:

  1. Navigate to entra.microsoft.com
  2. Go to ProtectionConditional AccessPolicies
  3. Create or edit existing policy for Power Platform
  4. Under Session controls:
  5. Enable Continuous access evaluation
  6. Set Disable resilience defaults: No

PowerShell Configuration

# ============================================================
# Control 2.8: Access Control and Segregation of Duties
# ============================================================

# Connect to required services
Connect-MgGraph -Scopes "Directory.ReadWrite.All", "RoleManagement.ReadWrite.Directory", "Group.ReadWrite.All", "AccessReview.ReadWrite.All"
Connect-AzureAD
Import-Module Microsoft.PowerApps.Administration.PowerShell

# -------------------------------------------------------------
# Section 1: Create Security Groups for Role Separation
# -------------------------------------------------------------

Write-Host "Creating security groups for agent governance roles..." -ForegroundColor Cyan

$Groups = @(
    @{
        DisplayName = "SG-Agent-Developers"
        Description = "Agent creators and editors - Tier 2/3 development access"
        MailNickname = "sg-agent-developers"
    },
    @{
        DisplayName = "SG-Agent-Reviewers"
        Description = "Agent reviewers - testing and validation access"
        MailNickname = "sg-agent-reviewers"
    },
    @{
        DisplayName = "SG-Agent-Approvers"
        Description = "Agent approvers - production approval authority"
        MailNickname = "sg-agent-approvers"
    },
    @{
        DisplayName = "SG-Agent-ReleaseManagers"
        Description = "Release managers - production deployment only"
        MailNickname = "sg-agent-releasemgrs"
    },
    @{
        DisplayName = "SG-PowerPlatform-Admins"
        Description = "Platform administrators - environment configuration"
        MailNickname = "sg-pp-admins"
    },
    @{
        DisplayName = "SG-AI-Governance-Leads"
        Description = "AI governance oversight - read-only access to all"
        MailNickname = "sg-ai-govleads"
    }
)

foreach ($Group in $Groups) {
    $ExistingGroup = Get-MgGroup -Filter "displayName eq '$($Group.DisplayName)'" -ErrorAction SilentlyContinue

    if (-not $ExistingGroup) {
        $NewGroup = New-MgGroup -DisplayName $Group.DisplayName `
                                -Description $Group.Description `
                                -MailNickname $Group.MailNickname `
                                -MailEnabled:$false `
                                -SecurityEnabled:$true `
                                -GroupTypes @()
        Write-Host "Created group: $($Group.DisplayName)" -ForegroundColor Green
    } else {
        Write-Host "Group already exists: $($Group.DisplayName)" -ForegroundColor Yellow
    }
}

# -------------------------------------------------------------
# Section 2: Validate Segregation of Duties
# -------------------------------------------------------------

Write-Host "`nValidating segregation of duties (SoD)..." -ForegroundColor Cyan

# Define SoD conflicts (roles that should not overlap)
$SoDConflicts = @(
    @{ Role1 = "SG-Agent-Developers"; Role2 = "SG-Agent-Approvers"; Reason = "Developers cannot approve their own work" },
    @{ Role1 = "SG-Agent-Developers"; Role2 = "SG-Agent-ReleaseManagers"; Reason = "Developers cannot deploy their own work" },
    @{ Role1 = "SG-Agent-Approvers"; Role2 = "SG-Agent-ReleaseManagers"; Reason = "Approvers cannot also deploy" }
)

$SoDViolations = @()

foreach ($Conflict in $SoDConflicts) {
    $Group1 = Get-MgGroup -Filter "displayName eq '$($Conflict.Role1)'" -ErrorAction SilentlyContinue
    $Group2 = Get-MgGroup -Filter "displayName eq '$($Conflict.Role2)'" -ErrorAction SilentlyContinue

    if ($Group1 -and $Group2) {
        $Members1 = Get-MgGroupMember -GroupId $Group1.Id -All | Select-Object -ExpandProperty Id
        $Members2 = Get-MgGroupMember -GroupId $Group2.Id -All | Select-Object -ExpandProperty Id

        $Overlap = $Members1 | Where-Object { $Members2 -contains $_ }

        foreach ($UserId in $Overlap) {
            $User = Get-MgUser -UserId $UserId -ErrorAction SilentlyContinue
            $SoDViolations += [PSCustomObject]@{
                User = $User.UserPrincipalName
                ConflictingRoles = "$($Conflict.Role1) & $($Conflict.Role2)"
                Reason = $Conflict.Reason
                Severity = "HIGH"
            }
        }
    }
}

if ($SoDViolations.Count -gt 0) {
    Write-Host "⚠️ SEGREGATION OF DUTIES VIOLATIONS DETECTED:" -ForegroundColor Red
    $SoDViolations | Format-Table -AutoSize
    $SoDViolations | Export-Csv "SoD_Violations_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
} else {
    Write-Host "✅ No segregation of duties violations found" -ForegroundColor Green
}

# -------------------------------------------------------------
# Section 3: Power Platform Role Assignment
# -------------------------------------------------------------

Write-Host "`nAssigning Power Platform security roles..." -ForegroundColor Cyan

# Get production environment
$ProdEnv = Get-AdminPowerAppEnvironment | Where-Object { $_.DisplayName -like "*Prod*" }

if ($ProdEnv) {
    Write-Host "Production environment: $($ProdEnv.DisplayName)" -ForegroundColor Cyan

    # Note: Security role assignment requires Dataverse SDK or portal configuration
    # This script identifies the groups; actual role binding is done in Power Platform Admin Center

    $RoleMapping = @"

    ============================================
    POWER PLATFORM SECURITY ROLE ASSIGNMENTS
    Environment: $($ProdEnv.DisplayName)
    ============================================

    Assign these security roles in Power Platform Admin Center:

    1. SG-Agent-Developers -> Environment Maker (limited publish)
    2. SG-Agent-Reviewers -> Basic User + Custom Test Role
    3. SG-Agent-Approvers -> Basic User + Approval Access
    4. SG-Agent-ReleaseManagers -> Solution Import + Publish Access
    5. SG-PowerPlatform-Admins -> System Administrator
    6. SG-AI-Governance-Leads -> Read-Only Access (all entities)

    Navigate to: admin.powerplatform.microsoft.com
    Select Environment -> Settings -> Users + permissions -> Teams
    Add each group and assign appropriate security role

"@
    Write-Host $RoleMapping -ForegroundColor Yellow
}

# -------------------------------------------------------------
# Section 4: Configure Access Review
# -------------------------------------------------------------

Write-Host "`nConfiguring access review for agent governance groups..." -ForegroundColor Cyan

# Get group IDs for review scope
$GroupsForReview = Get-MgGroup -Filter "startsWith(displayName, 'SG-Agent-')"

$ReviewDefinition = @{
    displayName = "Agent Governance Roles - Quarterly Review"
    descriptionForAdmins = "Quarterly review of agent governance role assignments for SOX compliance"
    descriptionForReviewers = "Please review and certify that these users still require access to agent governance roles"
    scope = @{
        "@odata.type" = "#microsoft.graph.accessReviewQueryScope"
        query = "/groups?`$filter=(displayName eq 'SG-Agent-Developers' or displayName eq 'SG-Agent-Reviewers' or displayName eq 'SG-Agent-Approvers' or displayName eq 'SG-Agent-ReleaseManagers')/members"
        queryType = "MicrosoftGraph"
    }
    reviewers = @(
        @{
            query = "/groups/{group-id}/owners"
            queryType = "MicrosoftGraph"
        }
    )
    settings = @{
        mailNotificationsEnabled = $true
        reminderNotificationsEnabled = $true
        justificationRequiredOnApproval = $true
        defaultDecisionEnabled = $true
        defaultDecision = "None"
        instanceDurationInDays = 14
        autoApplyDecisionsEnabled = $true
        recommendationsEnabled = $true
        recurrence = @{
            pattern = @{
                type = "absoluteMonthly"
                interval = 3
            }
            range = @{
                type = "noEnd"
                startDate = (Get-Date).ToString("yyyy-MM-dd")
            }
        }
    }
}

Write-Host "Access review configuration prepared. Create in Entra ID portal:" -ForegroundColor Yellow
Write-Host "  Identity governance -> Access reviews -> New access review" -ForegroundColor Yellow

# -------------------------------------------------------------
# Section 5: Audit Access Patterns
# -------------------------------------------------------------

Write-Host "`nAuditing access patterns for agent governance roles..." -ForegroundColor Cyan

$RoleAccessReport = @()

foreach ($Group in $GroupsForReview) {
    $Members = Get-MgGroupMember -GroupId $Group.Id -All

    foreach ($Member in $Members) {
        $User = Get-MgUser -UserId $Member.Id -Property DisplayName, UserPrincipalName, SignInActivity -ErrorAction SilentlyContinue

        if ($User) {
            $LastSignIn = $User.SignInActivity.LastSignInDateTime
            $DaysSinceSignIn = if ($LastSignIn) { ((Get-Date) - $LastSignIn).Days } else { 999 }

            $RoleAccessReport += [PSCustomObject]@{
                Group = $Group.DisplayName
                User = $User.DisplayName
                UPN = $User.UserPrincipalName
                LastSignIn = $LastSignIn
                DaysSinceSignIn = $DaysSinceSignIn
                Status = if ($DaysSinceSignIn -gt 90) { "STALE" } else { "ACTIVE" }
            }
        }
    }
}

# Export report
$RoleAccessReport | Export-Csv "Agent_Role_Access_Report_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
Write-Host "Access report exported" -ForegroundColor Green

# Identify stale accounts
$StaleAccounts = $RoleAccessReport | Where-Object { $_.Status -eq "STALE" }
if ($StaleAccounts.Count -gt 0) {
    Write-Host "⚠️ Stale accounts detected (no sign-in > 90 days):" -ForegroundColor Yellow
    $StaleAccounts | Format-Table -AutoSize
}

# -------------------------------------------------------------
# Section 6: Generate Compliance Report
# -------------------------------------------------------------

Write-Host "`nGenerating access control compliance report..." -ForegroundColor Cyan

$ComplianceReport = @"
===============================================================================
ACCESS CONTROL AND SEGREGATION OF DUTIES - COMPLIANCE REPORT
Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
===============================================================================

EXECUTIVE SUMMARY
-----------------
Total Governance Groups: $($GroupsForReview.Count)
Total Role Assignments: $($RoleAccessReport.Count)
Segregation of Duties Violations: $($SoDViolations.Count)
Stale Accounts (>90 days): $($StaleAccounts.Count)

COMPLIANCE STATUS
-----------------
$(if ($SoDViolations.Count -eq 0) { "✅ SOX 404: Segregation of duties requirements MET" } else { "❌ SOX 404: Segregation of duties VIOLATIONS detected" })
$(if ($StaleAccounts.Count -eq 0) { "✅ Access hygiene: All accounts active" } else { "⚠️ Access hygiene: Stale accounts require review" })

ROLE DISTRIBUTION
-----------------
$(($RoleAccessReport | Group-Object -Property Group | ForEach-Object { "$($_.Name): $($_.Count) members" }) -join "`n")

REQUIRED ACTIONS
----------------
$(if ($SoDViolations.Count -gt 0) { "1. URGENT: Resolve segregation of duties violations listed in SoD_Violations report" })
$(if ($StaleAccounts.Count -gt 0) { "2. Review and remove stale account access" })
3. Complete quarterly access review when scheduled
4. Document any exceptions with business justification

===============================================================================
"@

$ComplianceReport | Out-File "Access_Control_Compliance_$(Get-Date -Format 'yyyyMMdd').txt"
Write-Host $ComplianceReport

Write-Host "`nAccess Control and SoD configuration complete" -ForegroundColor Green

Financial Sector Considerations

Regulatory Alignment

Regulation Access Control Requirement Control Implementation
SOX 302/404 Segregation of duties for financial systems No single user can create, approve, and deploy
FINRA 4511 Access to records must be controlled and logged Role-based access with audit trails
GLBA 501(b) Restrict access to customer information Least privilege access to agent data
SEC 17a-4 Control over records modification Immutable audit logs of access
FFIEC CAT Access management controls Quarterly access reviews, PIM for admin roles
OCC 2011-12 Model access controls Separate roles for development vs. validation

Zone-Specific Configuration

Zone Access Controls SoD Requirements
Zone 1 - Personal Default user access Self-service, no SoD required
Zone 2 - Team Team owner approval Creator ≠ Approver
Zone 3 - Enterprise Full SoD enforcement Creator ≠ Reviewer ≠ Approver ≠ Deployer

FSI Role Hierarchy Example

                    ┌─────────────────────┐
                    │  CISO / CRO         │ (Ultimate oversight)
                    └──────────┬──────────┘
                               │
              ┌────────────────┼────────────────┐
              │                │                │
    ┌─────────▼──────┐ ┌───────▼────────┐ ┌────▼─────────────┐
    │ AI Governance  │ │ Compliance     │ │ IT Security      │
    │ Lead           │ │ Officer        │ │ Admin            │
    └─────────┬──────┘ └───────┬────────┘ └────┬─────────────┘
              │                │                │
              └────────────────┼────────────────┘
                               │
        ┌──────────────────────┼──────────────────────┐
        │                      │                      │
  ┌─────▼─────┐         ┌──────▼──────┐        ┌──────▼──────┐
  │ Agent     │ ──X──── │ Agent       │ ──X─── │ Release     │
  │ Developer │         │ Approver    │        │ Manager     │
  └───────────┘         └─────────────┘        └─────────────┘
        │                      │                      │
        │                      │                      │
   (Creates)             (Approves)            (Deploys)

   X = No overlap allowed (Segregation of Duties)

Verification & Testing

Verification Steps

  1. SoD Validation
  2. Run PowerShell SoD check script
  3. Verify no users in conflicting groups
  4. Document any exceptions with approval

  5. Access Review Configuration

  6. Entra ID → Identity governance → Access reviews
  7. Confirm quarterly review scheduled
  8. Verify group owners assigned as reviewers

  9. PIM Configuration (Tier 3)

  10. Entra ID → Privileged Identity Management
  11. Verify admin roles require activation
  12. Confirm approval workflow for activation

  13. Workflow Enforcement

  14. Test approval workflow with sample agent
  15. Verify creator cannot approve own agent
  16. Confirm deployment blocked without approval

Compliance Checklist

  • [ ] Security groups created for all agent governance roles
  • [ ] Power Platform security roles configured
  • [ ] No segregation of duties violations detected
  • [ ] Quarterly access reviews scheduled
  • [ ] PIM configured for admin roles (Tier 3)
  • [ ] Approval workflows enforce SoD
  • [ ] Access analytics monitoring enabled
  • [ ] Stale account remediation process defined

Troubleshooting & Validation

Issue: User Cannot Access Required Resources

Symptoms: User blocked from performing authorized tasks Solution:

  1. Verify user is member of correct security group
  2. Check Power Platform security role assignment
  3. For PIM roles, confirm user has activated role
  4. Review Conditional Access policy blocking

Issue: Segregation of Duties Violation Detected

Symptoms: Same user in conflicting groups Solution:

  1. Identify the conflict from SoD report
  2. Determine which role is primary
  3. Remove user from conflicting group
  4. If exception needed, document with CISO approval
  5. Implement compensating controls

Issue: Access Review Not Completing

Symptoms: Reviewers not responding, reviews stuck Solution:

  1. Check reminder notification settings
  2. Verify reviewer has access to review portal
  3. Escalate to backup reviewer
  4. Review auto-apply settings for non-response

Issue: PIM Activation Failures

Symptoms: Cannot activate privileged role Solution:

  1. Verify eligible assignment exists
  2. Check if MFA requirement met
  3. Verify approver is available
  4. Check activation time limits
  5. Review PIM audit logs for denial reason

Additional Resources

Control Relationship
1.1 - Restrict Agent Publishing Publishing requires appropriate role
1.18 - Application-Level RBAC Complements agent-level access control
2.3 - Change Management Approval workflows integrate with access control
1.7 - Audit Logging Log all access and role changes
2.12 - Supervision and Oversight Oversight requires appropriate access

Support & Questions

For implementation support or questions about this control, contact:

  • AI Governance Lead (governance direction)
  • Compliance Officer (regulatory requirements)
  • Technical Implementation Team (platform setup)

Updated: Dec 2025
Version: v1.0 Beta (Dec 2025)
UI Verification Status: ❌ Needs verification