Skip to content

Securing AI Agent Sessions with Inactivity Timeout Controls

Inactivity Timeout Enforcement (ITE)

Version: 1.0.5 Solution Type: Automated Compliance Detection and Monitoring Platform: Microsoft Power Platform with Dataverse


Executive Summary

Problem Statement

Copilot Studio agents and Power Platform environments without properly configured inactivity timeout controls create significant security and compliance risks. When user sessions remain active indefinitely or exceed regulatory timeframes, they expose organizations to unauthorized access through unattended workstations, session hijacking, and regulatory violations.

Risk Exposure: - Unauthorized Access: Active sessions on unattended workstations allow unauthorized users to impersonate legitimate users - Session Hijacking: Extended session lifetimes increase attack windows for session token theft - Compliance Violations: Failure to enforce timeout controls violates regulatory requirements (GLBA Section 501(b), SOX Section 302, FINRA Rule 4511(a), NIST 800-53 AC-11/AC-12) - Data Exposure: Prolonged sessions increase risk of data leakage through unattended terminals - Audit Gaps: Inability to demonstrate timeout enforcement creates examination findings

Solution Overview

The Inactivity Timeout Enforcement (ITE) solution provides continuous automated monitoring of Power Platform environment inactivity timeout configurations across your tenant. The solution evaluates timeout settings against zone-based governance policies, detects non-compliant configurations (including timeouts exceeding 120 minutes), and generates compliance reports with email alerting for immediate remediation.

Key Capabilities: - Continuous Detection: Daily automated scans across all Power Platform environments - Zone-Based Policy Enforcement: Different maximum timeout durations per governance zone (Personal/Team/Enterprise) - Compliance Status Tracking: Compliant, Non-Compliant, and Unknown status classification with immutable audit trail - Guarded Alerting: Email notifications sent only when issues detected (Non-Compliant or Unknown environments) - Error Handling: Isolated per-environment error handling prevents scan failures from blocking tenant-wide visibility

Business Value: - Reduce session-based security incidents through proactive timeout detection - Eliminate manual audit overhead with automated compliance validation - Support regulatory examinations with complete compliance history and evidence export - Enable zone-based risk management with tailored timeout policies per environment tier


Technical Details

Architecture Overview

ITE operates as a single Power Automate cloud flow with daily scheduled execution. The architecture follows a policy-load, enumerate-evaluate, report pattern with per-environment error isolation and guarded notification.

┌─────────────────────────────────────────────────────────────────────┐
│             Inactivity Timeout Enforcement (ITE)                     │
│          Daily Compliance Detection & Monitoring                     │
└─────────────────────────────────────────────────────────────────────┘
                    ┌───────────────────────────────┐
                    │   Detect Inactivity Timeout   │
                    │   Non-Compliance Flow         │
                    │   (Daily 06:00 UTC)           │
                    └───────────────┬───────────────┘
        ┌───────────────────────────┼───────────────────────────┐
        │                           │                           │
        ▼                           ▼                           ▼
┌───────────────┐          ┌─────────────────┐        ┌─────────────────┐
│  Load Policy  │          │   Enumerate     │        │   Evaluate      │
│  from         │──────────▶│  Environments   │────────▶│  Compliance     │
│  Dataverse    │          │  (BAP API)      │        │  Per Env        │
└───────────────┘          └─────────────────┘        └────────┬────────┘
                                                ┌───────────────────────────┐
                                                │  Write Compliance Record  │
                                                │  to Dataverse             │
                                                │  (Immutable)              │
                                                └───────────┬───────────────┘
        ┌───────────────────────────────────────────────────┼───────────────┐
        │                                                   │               │
        ▼                                                   ▼               ▼
┌───────────────┐                                  ┌─────────────┐  ┌──────────────┐
│  Query Non-   │                                  │  Query      │  │  Query       │
│  Compliant    │                                  │  Unknown    │  │  Compliant   │
│  Records      │                                  │  Records    │  │  Count       │
└───────┬───────┘                                  └──────┬──────┘  └──────┬───────┘
        │                                                 │                │
        └─────────────────────────┬───────────────────────┘                │
                                  │                                        │
                                  ▼                                        │
                          ┌───────────────┐                                │
                          │  Has Issues?  │                                │
                          │  (Guarded)    │                                │
                          └───────┬───────┘                                │
                                  │                                        │
                          Yes     │   No                                   │
                                  │   (skip email)                         │
                                  ▼                                        │
                        ┌─────────────────┐                                │
                        │  Send HTML      │                                │
                        │  Alert Email    │◀───────────────────────────────┘
                        │  (High Priority)│   (Include summary stats)
                        └─────────────────┘

Solution Components

Detect Inactivity Timeout Non-Compliance Flow

Flow Name: Detect Inactivity Timeout Non-Compliance

Purpose: Continuous monitoring of inactivity timeout configurations across all Power Platform environments with zone-based policy evaluation.

Trigger: - Schedule: Daily at 06:00 UTC (configurable) - Scope: All Power Platform environments in the tenant - Type: Recurrence trigger

Compliance Logic:

The flow implements three-state compliance classification:

Compliance Status Code Detection Criteria Result
Compliant 0 Timeout enabled AND duration ≤ required maximum for zone Pass
Non-Compliant 1 Timeout disabled OR duration > required maximum for zone Fail
Unknown 2 Missing policy for environment OR BAP API error OR timeout enabled but duration null (indeterminate) Unknown

Zone-Based Policy Enforcement:

Environments are classified into governance zones with tailored maximum timeout durations:

Zone Classification Recommended Max Timeout Rationale
Zone 1 Personal Development 120 minutes Individual developers with minimal data exposure
Zone 2 Team Collaboration 120 minutes Team environments with moderate data sensitivity
Zone 3 Enterprise Production 60 minutes Production environments with regulatory requirements

Note: Enterprise/production environments (Zone 3) should have the shortest timeouts per NIST 800-53 AC-11 and FINRA Rule 4511(a). All timeouts should not exceed 120 minutes (2 hours).

Process Flow:

  1. Initialization:
  2. Generate unique scan run ID (GUID) for correlation
  3. Read environment variables via @environmentVariables():

    • fsi_ITE_NotificationRecipients — Semicolon-separated email addresses
  4. Policy Loading:

  5. Query fsi_environmentpolicies table from Dataverse
  6. Extract environment-to-zone mappings with required maximum durations
  7. Cache policy array in memory for fast lookup

  8. Environment Enumeration:

  9. Call BAP Admin API: https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments
  10. Use Managed Service Identity (MSI) authentication
  11. Retrieve all environments in tenant

  12. Per-Environment Evaluation (Parallel):

  13. Concurrency: Hardcoded to 5 parallel evaluations (configured in flow's runtimeConfiguration)
  14. For each environment:
    • Extract environment name (canonical ID) and display name
    • Resolve policy from cached array by environment ID
    • If policy exists:
    • Call the BAP Governance Configuration API: https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments/{environmentName}/governanceConfiguration?api-version=2021-04-01
    • Parse properties.settings.inactivityTimeoutEnabled (boolean) and properties.settings.inactivityTimeoutDuration (ISO 8601). For backward compatibility with older API responses, also accept sessionTimeoutEnabled / sessionTimeoutInactivityDuration.
    • Convert ISO 8601 duration to minutes (handles PT60M, PT2H, PT1H30M formats)
    • Evaluate compliance:
      • If timeout not explicitly enabled (disabled or null) → Non-Compliant
      • If timeout enabled but duration is null (indeterminate) → Unknown
      • If timeout duration > required max → Non-Compliant
      • Otherwise → Compliant
    • Write immutable compliance record to fsi_inactivitytimeoutcompliances table
    • If policy missing:
    • Write Unknown compliance record
    • Log MissingPolicy error to fsi_inactivitytimeouterrorlogs table
    • If BAP API error:
    • Write Unknown compliance record
    • Log API error with HTTP status code to error log table
  15. Error Isolation: Individual environment failures do not abort scan

  16. Summary Reporting:

  17. Query compliance records by scan run ID:
    • Non-Compliant records (fsi_compliancestatus eq 100000001)
    • Unknown records (fsi_compliancestatus eq 100000002)
    • Compliant count (fsi_compliancestatus eq 100000000)
  18. Guarded Notification: Only send email if Non-Compliant count > 0 OR Unknown count > 0
  19. Build HTML email with:
    • Scan summary (compliant/non-compliant/unknown counts)
    • Detailed issues table (environment, zone, status, timeout enabled, actual duration, required max, notes)
  20. Send email with High importance to configured recipients

  21. Error Handling:

  22. Outer scope catch for unexpected flow failures
  23. Send CRITICAL email notification with flow run ID for investigation

Configuration Parameters:

Variable Name Type Example Value Description
fsi_ITE_NotificationRecipients String security@contoso.com;compliance@contoso.com Semicolon-separated email addresses for compliance alerts

Note: The flow reads environment variables using Power Automate's @environmentVariables() function at initialization. The BAP Admin API base URL is sourced from the fsi_ITE_BapApiBaseUrl environment variable (defaults to https://api.bap.microsoft.com for commercial cloud); it is not shown in the table above because it is optional with a built-in default. The Dataverse connection uses the connection reference. Email send actions are guarded: if fsi_ITE_NotificationRecipients is empty, emails are silently skipped rather than causing a flow error. Loop concurrency is hardcoded to 5 in the flow's runtimeConfiguration.

Email Alert Format:

Subject (Non-Compliant):

[NON-COMPLIANT] Inactivity Timeout Compliance Scan — 3 issue(s) detected

Body (HTML):

Inactivity Timeout Compliance Scan Results

Scan Date: 2026-02-14T06:15:32Z
Scan Run ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Compliant:        47
Non-Compliant:     2
Unknown:           1

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Issues Requiring Attention
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Environment         | Zone | Status         | Timeout  | Actual  | Req Max | Notes
                    |      |                | Enabled  | (min)   | (min)   |
────────────────────┼──────┼────────────────┼──────────┼─────────┼─────────┼───────────────────────
Finance-Prod        | Enterprise | Non-Compliant  | True     | 180     | 60      | Duration 180m exceeds maximum 60m
HR-Team-Sandbox     | Team       | Non-Compliant  | False    | 0       | 120     | Inactivity timeout is disabled
Legal-Dev           |      | Unknown        | False    | 0       | 0       | No explicit policy found for environment

Data Model

Dataverse Tables

1. fsi_environmentpolicies (Environment Policies)

Master registry of environment-to-zone mappings with required timeout policies.

Implementation status (v1.1.0): The Power Automate flow described in this document reads fsi_environmentpolicies to resolve the per-environment policy. The PowerShell scanner shipped in scripts/governance/Get-ExpectedTimeoutPolicy.ps1 does not read Dataverse — it derives the zone from environment-name heuristics (Default- → Personal, *-Sandbox* → Team, all others → Enterprise) and applies the same hardcoded zone limits (Personal=120, Team=120, Enterprise=60). When zone classification needs to be data-driven, populate fsi_environmentpolicies and use the flow rather than the standalone scanner. A future release will reconcile the two paths.

Column Name Type Description
fsi_environmentid String(100) Canonical Power Platform environment name (primary key for policy lookup)
fsi_environmentdisplayname String(200) Human-readable environment display name
fsi_zone Choice (fsi_ITE_zone global option set) Governance zone: 100000001=Personal, 100000002=Team, 100000003=Enterprise. Use the integer values directly in OData filters ($filter=fsi_zone eq 100000002).
fsi_requiredmaxduration Number Required maximum inactivity timeout duration in minutes (e.g., 60, 90, 120)

Example Records:

┌──────────────────────────────────┬────────────────────────┬──────┬─────────────────────┐
│ fsi_environmentid                │ fsi_environmentdisplay │ fsi_ │ fsi_requiredmax     │
│                                  │ name                   │ zone │ duration            │
├──────────────────────────────────┼────────────────────────┼──────┼─────────────────────┤
│ Default-aaaaaaaa-bbbb-cccc-dddd  │ Finance-Prod           │ 3    │ 60                  │
│ Development-bbbbbbbb-cccc-dddd   │ Legal-Dev              │ 1    │ 120                 │
│ Sandbox-cccccccc-dddd-eeee       │ HR-Team-Sandbox        │ 2    │ 120                 │
└──────────────────────────────────┴────────────────────────┴──────┴─────────────────────┘

2. fsi_inactivitytimeoutcompliances (Compliance Records)

Immutable audit trail of inactivity timeout compliance evaluations.

Column Name Type Description
fsi_inactivitytimeoutcomplianceid GUID Primary key
fsi_compliancename String(200) (required) Auto-generated by the runbook as ITE-{EnvironmentName}-{RunId} (truncated to 200 chars). Required by the schema.
fsi_environmentid String(100) Canonical environment name
fsi_environmentname String(200) Environment display name
fsi_zone Choice (fsi_ITE_zone) Governance zone from policy: 100000001=Personal, 100000002=Team, 100000003=Enterprise
fsi_inactivitytimeoutenabled Boolean Whether inactivity timeout is enabled
fsi_timeoutduration String(50) Raw ISO 8601 duration returned by the BAP API (e.g., PT2H, PT60M). Empty when timeout is disabled.
fsi_timeoutdurationminutes Whole Number Parsed duration in minutes (-1 when not parseable, 0 when disabled). Use this for numeric comparisons in flows.
fsi_requiredmaxduration Whole Number Required maximum duration in minutes from policy
fsi_compliancestatus Choice (fsi_ITE_compliancestatus) 100000000=Compliant, 100000001=NonCompliant, 100000002=Unknown. Use the integer values directly in OData filters.
fsi_notes Memo Human-readable compliance evaluation notes
fsi_lastscandate DateTime Scan execution timestamp (UTC)
fsi_scanrunid String(50) Correlation ID for batch scan (GUID)

Compliance Status Mapping (fsi_ITE_compliancestatus global option set): - 100000000 (Compliant): Timeout enabled and duration ≤ required max - 100000001 (NonCompliant): Timeout disabled OR duration > required max - 100000002 (Unknown): Missing policy OR BAP API error OR timeout enabled but duration null (indeterminate state)

3. fsi_inactivitytimeouterrorlogs (Error Logs)

Diagnostic logs for API errors and missing policy issues.

Column Name Type Description
fsi_inactivitytimeouterrorlogid GUID Primary key
fsi_errorname String(200) (required) Auto-generated by the runbook as ITE-ERR-{EnvironmentName}-{RunId} (truncated to 200 chars).
fsi_environmentid String(100) Canonical environment name where error occurred
fsi_errortype Choice (fsi_ITE_errortype) (required) 100000000=MissingPolicy, 100000001=Unauthorized, 100000002=Forbidden, 100000003=NotFound, 100000004=Throttled, 100000005=ParseError, 100000006=DataverseError. The runbook always populates this column.
fsi_errorraw Memo Raw error response from BAP API or policy lookup. Security note: may contain internal URLs, tenant identifiers, and correlation IDs — configure Dataverse column-level security to restrict read access to authorized roles.
fsi_timestamp DateTime Error occurrence timestamp (UTC)

Error Type Mapping (fsi_ITE_errortype global option set): - 100000000 MissingPolicy: No fsi_environmentpolicies record exists for environment - 100000001 Unauthorized (401): MSI lacks Power Platform Admin permissions - 100000002 Forbidden (403): Access denied to environment privacy settings - NotFound (404): Environment not found or deleted - Throttled (429): BAP API rate limit exceeded - ParseError: Unable to parse BAP API response or ISO 8601 duration, or any other unrecognized HTTP error (e.g., 500, 503) - DataverseError: HTTP call succeeded (200) but a subsequent action within the scope failed (Dataverse write, JSON parse, or type conversion)

Data Security Recommendations

Row-Level Security: Configure Dataverse business-unit or team-based security roles to restrict access to the fsi_inactivitytimeoutcompliances and fsi_inactivitytimeouterrorlogs tables. Only compliance administrators and auditors should have read access to scan results and error logs.

Column-Level Security: Enable Dataverse column-level security profiles on sensitive columns (particularly fsi_errorraw) to prevent exposure of internal URLs, tenant identifiers, and correlation IDs to non-administrative users.

Configuration and Prerequisites

Prerequisites

Microsoft 365 Licensing: - Power Automate Premium (for cloud flow with HTTP actions and Dataverse) - Power Platform Admin permissions (for BAP Admin API access)

Permissions:

Role Required For Permission Level
Power Platform Admin Flow deployment, BAP API access Admin or Global Admin
Dataverse Admin Table creation, security roles System Administrator
Exchange Online Mailbox Email notification sending Licensed mailbox for notification recipients

Service Connections:

The solution requires the following connection references:

Connection API Purpose
fsi_cr_dataverse_inactivitytimeout Dataverse Read/write compliance records and policies
fsi_cr_office365_inactivitytimeout Office 365 Outlook Send email alerts for compliance issues

Managed Service Identity (MSI):

The flow uses Managed Service Identity for BAP Admin API authentication. Ensure: - MSI is enabled for the Power Platform environment - MSI service principal is added as a member of the Power Platform Admin role in Microsoft 365 Admin Center → Roles → Power Platform Admin → Members

Configuration Steps

Important: Complete Step 1 (MSI setup) before importing the flow. The flow uses MSI for BAP Admin API authentication — skipping this step causes 401 Unauthorized errors on first run.

Step 1: Configure Managed Service Identity

  1. Enable MSI for the Power Platform environment:
  2. Navigate to Azure Portal → Managed Identities → Create
  3. Assign identity to Power Platform environment
  4. Grant Power Platform Admin role to MSI:
  5. Navigate to Microsoft 365 Admin Center → Roles → Power Platform Admin → Members
  6. Add the MSI service principal as a member
  7. Verify the role assignment is active before proceeding to Step 2

Step 2: Create Dataverse Tables

Execute the following in Dataverse (via Power Apps maker portal → Tables → New table):

  1. Create fsi_environmentpolicies table:
  2. Display Name: Environment Policies
  3. Plural Name: Environment Policies
  4. Primary Column: fsi_environmentid (Text, 100 characters)
  5. Add columns per Data Model section
  6. Create choice field fsi_zone from global option set fsi_ITE_zone: 100000001=Personal, 100000002=Team, 100000003=Enterprise

  7. Create fsi_inactivitytimeoutcompliances table:

  8. Display Name: Inactivity Timeout Compliances
  9. Plural Name: Inactivity Timeout Compliances
  10. Primary Column: Auto-number (e.g., ITC-{SEQNUM:5})
  11. Add columns per Data Model section
  12. Create choice field fsi_compliancestatus from global option set fsi_ITE_compliancestatus: 100000000=Compliant, 100000001=NonCompliant, 100000002=Unknown

  13. Create fsi_inactivitytimeouterrorlogs table:

  14. Display Name: Inactivity Timeout Error Logs
  15. Plural Name: Inactivity Timeout Error Logs
  16. Primary Column: Auto-number (e.g., ERR-{SEQNUM:5})
  17. Add columns per Data Model section

Step 3: Build the Cloud Flow

  1. Navigate to Power Automate → Cloud flows → + New → Scheduled cloud flow
  2. Build the flow manually following the configuration steps in the sections below
  3. The flow should follow the architecture pattern described in the Architecture Overview above

Step 4: Configure Connection References

  1. Open flow in edit mode
  2. Navigate to Data → Connection References
  3. Create connections:
  4. Dataverse: Use Entra ID authentication (service account or current user)
  5. Office 365 Outlook: Use current user authentication
  6. Map connections to connection references:
  7. fsi_cr_dataverse_inactivitytimeout → Dataverse connection
  8. fsi_cr_office365_inactivitytimeout → Office 365 connection

Step 5: Set Environment Variables

Create environment variables in Power Platform:

Variable Name Type Example Value Description
fsi_ITE_NotificationRecipients String security@contoso.com;compliance@contoso.com Semicolon-separated email addresses
fsi_ITE_ConcurrencyLimit (removed) n/a This environment variable is not provisioned by create_ite_environment_variables.py and is not read by the flow. Parallel degree is hardcoded to 5 in the flow's runtimeConfiguration. To change concurrency, modify the flow JSON directly.
fsi_ITE_ScanFrequencyHours Number 24 Informational only — not read by the flow. The trigger uses a hardcoded daily recurrence. To change scan frequency, modify the flow trigger directly.

Step 6: Populate Environment Policies

Add environment policies to fsi_environmentpolicies table with zone-based max durations:

Example Policy Records:
┌──────────────────────────────────┬────────────────────────┬──────┬─────────────────────┐
│ fsi_environmentid                │ fsi_environmentdisplay │ fsi_ │ fsi_requiredmax     │
│ (Power Platform Env Name)        │ name                   │ zone │ duration (minutes)  │
├──────────────────────────────────┼────────────────────────┼──────┼─────────────────────┤
│ Default-12345678-abcd-1234-abcd  │ Finance Production     │ 3    │ 60                  │
│ Sandbox-87654321-bcde-2345-bcde  │ Finance UAT            │ 2    │ 120                 │
│ Development-abcdefgh-cdef-3456   │ Developer - John Doe   │ 1    │ 120                 │
│ Default-aaaaaaaa-bbbb-cccc-dddd  │ HR Production          │ 3    │ 60                  │
└──────────────────────────────────┴────────────────────────┴──────┴─────────────────────┘

Note: To get canonical environment names, navigate to Power Platform Admin Center → Environments → Select environment → Settings → Details. The Environment URL contains the canonical name.

Step 7: Activate Flow

  1. Open flow in edit mode
  2. Click "Turn on" to activate
  3. Verify trigger configuration: Daily recurrence at 06:00 UTC
  4. Save flow

Deployment Validation

Test 1: Manual Flow Run

  1. Open flow → Run → Confirm success
  2. Check Dataverse fsi_inactivitytimeoutcompliances table for compliance records
  3. Verify scan run ID is consistent across all records for this execution
  4. Check email inbox for notification (only sent if issues detected)

Test 2: Policy Resolution

  1. Create test policy in fsi_environmentpolicies table:
  2. Environment ID: Test-Environment-12345
  3. Display Name: Test Environment
  4. Zone: 2 (Team)
  5. Required Max Duration: 120 minutes
  6. Verify flow resolves policy during next run
  7. Check compliance record has correct zone and required max values

Test 3: Compliance Detection (Non-Compliant Scenario)

  1. Identify test environment with timeout > 120 minutes (or disabled)
  2. Add policy for test environment to fsi_environmentpolicies table (required max: 120)
  3. Run flow manually
  4. Verify compliance record status = Non-Compliant (1)
  5. Verify email notification sent with environment details

Test 4: Error Handling (Missing Policy)

  1. Remove policy for a known environment from fsi_environmentpolicies table
  2. Run flow manually
  3. Verify compliance record status = Unknown (2)
  4. Check fsi_inactivitytimeouterrorlogs table for MissingPolicy error entry
  5. Verify email notification includes Unknown environment in issues table

Operational Guidance

Daily Operations

Monitoring: - Review email alerts each morning after 06:00 UTC scan - Prioritize Non-Compliant environments (timeout disabled or exceeding max) - Investigate Unknown environments (missing policies or API errors) - Target: Resolve all Non-Compliant environments within 2 business days

Policy Management: - Add fsi_environmentpolicies records for new environments within 24 hours of creation - Review zone classifications quarterly (environments may change purpose/tier) - Adjust required max durations based on regulatory guidance updates - Document policy exceptions with business justification

Compliance Remediation:

Automated remediation: Set-InactivityTimeout.ps1 in the FSI-AgentGov repository (scripts/governance/) can apply timeout settings programmatically across multiple environments. Remediation scripts are maintained separately in FSI-AgentGov and are not included in this solution package. Manual steps are documented below.

For Non-Compliant environments (timeout disabled): 1. Navigate to Power Platform Admin Center 2. Environments → Select environment → Settings → Privacy + Security 3. Enable Inactivity timeout 4. Set duration to required maximum (60 or 120 minutes per zone) 5. Verify next scan shows Compliant status

For Non-Compliant environments (timeout exceeds max): 1. Navigate to Power Platform Admin Center → Environment Settings 2. Reduce Inactivity timeout to required maximum or lower 3. Example: Zone 3 (Enterprise) requires ≤ 60 minutes → Set to 60 minutes or lower 4. Verify next scan shows Compliant status

For Unknown environments (missing policy): 1. Determine appropriate zone classification (Personal/Team/Enterprise) 2. Add policy record to fsi_environmentpolicies table: - Environment ID: Canonical environment name (from PPAC) - Display Name: Environment display name - Zone: 1/2/3 (Personal/Team/Enterprise) - Required Max Duration: 120/120/60 minutes per zone 3. Verify next scan evaluates environment and removes Unknown status

For Unknown environments (API error): 1. Check fsi_inactivitytimeouterrorlogs table for error type 2. Unauthorized (401): Verify MSI has Power Platform Admin role 3. Forbidden (403): Verify MSI permissions on specific environment 4. NotFound (404): Environment may have been deleted → Remove policy record 5. Throttled (429): BAP API rate limit exceeded → Contact Microsoft Support 6. ParseError: Investigate flow run history for malformed API response

Troubleshooting

Issue: Flow fails with "Unauthorized" error

Cause: Managed Service Identity lacks Power Platform Admin role

Resolution: 1. Navigate to Microsoft 365 Admin Center → Roles → Power Platform Admin 2. Add MSI service principal as member 3. Wait 15 minutes for role propagation 4. Re-run flow to verify success

Issue: Email notifications not sent

Cause: Guarded notification logic (no issues detected) or connection error

Resolution: 1. Verify Non-Compliant count > 0 OR Unknown count > 0 in scan run - If all environments Compliant → No email sent (expected behavior) - If issues exist but no email → Check Office 365 connection 2. Open flow → Data → Connection References → Verify Office 365 connection valid 3. Test Office 365 connection with manual "Send Email" action 4. Verify fsi_ITE_NotificationRecipients environment variable contains valid email addresses

Issue: Compliance records show incorrect zone

Cause: Policy record has wrong zone classification or environment ID mismatch

Resolution: 1. Query fsi_environmentpolicies table for affected environment 2. Verify fsi_environmentid matches canonical environment name (not display name) 3. Correct zone classification if incorrect (1=Personal, 2=Team, 3=Enterprise) 4. Update policy record and re-run flow to verify correct zone

Issue: ISO 8601 duration parsing error

Cause: Unsupported duration format from BAP Privacy Settings API

Resolution: 1. Check flow run history for Parse_Duration_Minutes action failure 2. Review fsi_errorraw field in fsi_inactivitytimeouterrorlogs table for actual duration string 3. Supported formats: PT60M (60 minutes), PT2H (2 hours), PT1H30M (1 hour 30 minutes) 4. If unsupported format → Log support case with Microsoft for BAP API

Issue: Concurrency throttling (HTTP 429)

Cause: BAP Admin API rate limit exceeded due to high concurrency

Resolution: 1. Reduce concurrency by editing the Apply_to_Each_Environment action's runtimeConfiguration.concurrency.repetitions value in the flow JSON (default: 5 → reduce to 3). Note: the fsi_ITE_ConcurrencyLimit environment variable is informational only and does not control actual concurrency. 2. Re-run flow to verify throttling resolved 3. If issue persists → Contact Microsoft Support for rate limit increase

Audit and Evidence Export

Evidence Collection:

For regulatory examinations, export compliance records and policy configurations:

-- Dataverse FetchXML query for compliance evidence (last 90 days)
<fetch>
  <entity name="fsi_inactivitytimeoutcompliances">
    <filter>
      <condition attribute="fsi_lastscandate" operator="last-x-days" value="90"/>
    </filter>
    <order attribute="fsi_lastscandate" descending="true"/>
  </entity>
</fetch>

Export Format:

Evidence files should include: - Compliance records with status, actual duration, required max, notes (CSV or Excel) - Policy configurations from fsi_environmentpolicies table (CSV or Excel) - Error logs from fsi_inactivitytimeouterrorlogs table (CSV or Excel) - Email notification history (forward alerts to compliance archive mailbox)

Retention:

  • Compliance records: Retain for 7 years (SEC Rule 17a-4 requirement)
  • Policy configurations: Retain for 7 years (audit trail requirement)
  • Error logs: Retain for 3 years (operational history)
  • Email notifications: Retain for 3 years (compliance evidence)

Automated Data Retention / Cleanup:

This solution does not include an automated retention or cleanup mechanism. The fsi_inactivitytimeoutcompliances and fsi_inactivitytimeouterrorlogs tables accumulate immutable records from each daily scan. Organizations must implement their own retention automation to enforce the periods listed above. Recommended approaches:

  1. Scheduled Power Automate flow: Create a companion flow that runs weekly or monthly. Use a Dataverse ListRecords action filtered by fsi_lastscandate lt <cutoff_date> and delete records exceeding the retention period (7 years for compliance records, 3 years for error logs).
  2. Dataverse bulk delete jobs: Configure recurring bulk delete jobs in the Power Platform Admin Center targeting records older than the retention threshold. Schedule during off-peak hours to minimize Dataverse API impact.
  3. Azure Data Factory / Synapse pipeline: For tenants already exporting Dataverse data to a data lake, implement retention policies at the lake layer and use truncation jobs for the source Dataverse tables.

Whichever approach is chosen, ensure deleted records have already been exported to long-term archival storage (see Export Format above) before purging, to maintain SEC Rule 17a-4 compliance.


Appendix: Compliance Status Reference

Compliant (Code: 0)

Description: Environment has inactivity timeout enabled with duration at or below required maximum for its zone.

Criteria: - inactivityTimeoutEnabled = true - timeoutDuration ≤ requiredMaxDuration

Example:

Environment: Finance Production
Zone: 3 (Enterprise)
Timeout Enabled: true
Actual Duration: 55 minutes
Required Max: 60 minutes
Status: Compliant
Notes: Compliant: 55m within 60m maximum

Non-Compliant (Code: 1)

Description: Environment has inactivity timeout disabled OR timeout duration exceeds required maximum for its zone.

Criteria: - inactivityTimeoutEnabled = false (timeout disabled) - OR timeoutDuration > requiredMaxDuration (exceeds maximum)

Example 1 (Timeout Disabled):

Environment: HR Team Sandbox
Zone: 2 (Team)
Timeout Enabled: false
Actual Duration: 0 minutes
Required Max: 120 minutes
Status: Non-Compliant
Notes: Inactivity timeout is disabled

Example 2 (Exceeds Maximum):

Environment: Legal Production
Zone: 3 (Enterprise)
Timeout Enabled: true
Actual Duration: 240 minutes
Required Max: 60 minutes
Status: Non-Compliant
Notes: Duration 240m exceeds maximum 60m

Remediation: - If disabled: Enable inactivity timeout in Power Platform Admin Center - If exceeds max: Reduce timeout duration to required maximum or lower

Unknown (Code: 2)

Description: Unable to evaluate compliance due to missing policy or BAP API error.

Criteria: - No fsi_environmentpolicies record exists for environment - OR BAP Privacy Settings API call failed - OR inactivityTimeoutEnabled = true but inactivityTimeoutDuration is null (indeterminate state — API reports timeout as enabled but provides no duration)

Example 1 (Missing Policy):

Environment: Developer Sandbox
Zone: null
Timeout Enabled: false
Actual Duration: 0 minutes
Required Max: 0 minutes
Status: Unknown
Notes: No explicit policy found for environment
Error Log: MissingPolicy - No fsi_environmentpolicy row exists for EnvironmentName: Development-abc123

Example 2 (API Error):

Environment: External Sandbox
Zone: 2 (from policy)
Timeout Enabled: false
Actual Duration: 0 minutes
Required Max: 120 minutes
Status: Unknown
Notes: BAP API call failed: Forbidden
Error Log: Forbidden (403) - Access denied to privacy settings for environment

Example 3 (Null Duration):

Environment: Finance Staging
Zone: 3 (Enterprise)
Timeout Enabled: true
Actual Duration: 0 minutes
Required Max: 60 minutes
Status: Unknown
Notes: Inactivity timeout is enabled but duration is null — indeterminate state classified as Unknown

Remediation: - Missing Policy: Add policy record to fsi_environmentpolicies table with appropriate zone and required max - API Error: Investigate error type in fsi_inactivitytimeouterrorlogs and resolve permissions or API issues - Null Duration: Re-save the inactivity timeout settings in Power Platform Admin Center to ensure the duration value is populated, or investigate BAP API data inconsistency


Appendix: ISO 8601 Duration Parsing

The solution parses ISO 8601 duration strings from the BAP Privacy Settings API response (inactivityTimeoutDuration field) and converts them to minutes for compliance evaluation.

Supported Formats:

Format Example Parsed Value (minutes) Description
PTnM PT60M 60 Minutes only
PTnH PT2H 120 Hours only (converted to minutes: 2 × 60 = 120)
PTnHnM PT1H30M 90 Hours + minutes (1 × 60 + 30 = 90)

Parsing Logic:

  1. If timeout disabled: Return 0 minutes
  2. If format contains both H and M: Extract hours and minutes, convert to total minutes
  3. If format contains only H: Extract hours, multiply by 60
  4. If format contains only M: Extract minutes directly
  5. If format is invalid: Log ParseError to error log table

Example Conversions:

Input: "PT60M"   → Output: 60 minutes  (1 hour)
Input: "PT120M"  → Output: 120 minutes (2 hours)
Input: "PT2H"    → Output: 120 minutes (2 hours)
Input: "PT1H30M" → Output: 90 minutes  (1.5 hours)
Input: "PT0M"    → Output: 0 minutes   (disabled or zero; if timeout is enabled and raw duration was null, classified as Unknown before parsing)

Appendix: Regulatory Alignment

The Inactivity Timeout Enforcement solution supports compliance with the following regulatory requirements:

GLBA Section 501(b) — Safeguards Rule

Requirement: Financial institutions must implement administrative, technical, and physical safeguards to protect customer information, including access controls and session management.

ITE Support: - Enforces inactivity timeout controls across all Power Platform environments - Provides audit trail of timeout configurations and compliance status - Generates evidence of continuous monitoring for regulatory examinations

SOX Section 302 — Internal Controls over Financial Reporting

Requirement: Management must establish and maintain adequate internal controls to ensure reliability of financial reporting, including IT controls for session management.

ITE Support: - Zone-based policy enforcement helps verify financial production environments (Zone 3) meet 60-minute maximum timeout - Immutable compliance records provide audit trail for internal control effectiveness - Daily monitoring enables timely detection of control deficiencies

FINRA Rule 4511(a) — General Requirements (Books and Records)

Requirement: Member firms must make and preserve books and records as required under FINRA rules, the Exchange Act, and applicable SEC rules, including records of technology controls and compliance monitoring.

ITE Support: - Continuous monitoring helps verify inactivity timeout controls remain effective - Non-compliant environment detection prevents unauthorized access through unattended workstations - Email alerting enables timely supervisory review and remediation

NIST 800-53 AC-11 — Session Lock

Requirement: Information systems must prevent further access by initiating a session lock after a period of inactivity (recommended: ≤ 15-120 minutes based on risk).

ITE Support: - Enforces maximum 60-minute timeout for production environments (Zone 3) - Zone-based tiering allows risk-appropriate timeout durations (120/120/60 minutes) - Compliance detection identifies disabled or excessive timeouts

NIST 800-53 AC-12 — Session Termination

Requirement: Information systems must automatically terminate user sessions after a defined condition or trigger.

ITE Support: - Validates inactivity timeout termination is enabled across all environments - Supports verification that termination occurs within regulatory timeframes (≤ 120 minutes) - Provides evidence of automated session termination enforcement


Known Limitations

  1. BAP Admin API version (List_Environments): The List_Environments action uses api-version=2016-11-01. This is the original API version and has been stable for years. Upgrading to a newer version (e.g., 2021-04-01) may unlock additional response fields but carries runtime regression risk. Test thoroughly in a non-production environment before upgrading.

  2. Condition_Has_Issues run-after configuration: The Condition_Has_Issues action runs after Query_NonCompliant_Records, Query_Unknown_Records, and Query_Compliant_Count with ["Succeeded", "Failed"] run-after condition. All expressions that reference query result bodies use coalesce(..., json('[]')) to return an empty array when a query fails, ensuring graceful handling of partial query failures without crashing the flow.

  3. List_Environments pagination: The List_Environments HTTP action retrieves only the first page of environments from the BAP Admin API. Tenants with environments exceeding the default API page size (~500) should implement nextLink pagination or partition environment scanning across multiple flow runs.


Support and Maintenance

Solution Version: 1.0.5 Release Date: April 2026 License: MIT License

Change Management: - Test environment policy changes in non-production first - Document zone classification decisions in change tickets - Review compliance trends monthly to identify recurring issues - Coordinate timeout policy updates with user communication (advance notice recommended)

Version History: - v1.0.2 (March 2026): Fix false-compliant classification when timeout enabled but duration null (indeterminate → Unknown); add pagination to all Dataverse ListRecords operations; update Map_Compliance_Status_Value to handle Unknown; document known limitations (API version, Condition_Has_Issues run-after, List_Environments pagination) - v1.0.1 (February 2026): Fix null inactivityTimeoutEnabled false-compliant bug; remove unused ConcurrencyLimit variable; HTML-escape environment names in emails; align Zone 2 timeout to ≤120min; version bump - v1.0.0 (February 2026): Initial release with zone-based policy enforcement, daily compliance detection, and guarded email alerting


This solution supports compliance with GLBA Section 501(b), SOX Section 302, FINRA Rule 4511(a), and NIST 800-53 AC-11/AC-12. Consult with your compliance and legal teams for applicability to your organization's regulatory requirements.