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:
- Initialization:
- Generate unique scan run ID (GUID) for correlation
-
Read environment variables via
@environmentVariables():fsi_ITE_NotificationRecipients— Semicolon-separated email addresses
-
Policy Loading:
- Query
fsi_environmentpoliciestable from Dataverse - Extract environment-to-zone mappings with required maximum durations
-
Cache policy array in memory for fast lookup
-
Environment Enumeration:
- Call BAP Admin API:
https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments - Use Managed Service Identity (MSI) authentication
-
Retrieve all environments in tenant
-
Per-Environment Evaluation (Parallel):
- Concurrency: Hardcoded to 5 parallel evaluations (configured in flow's
runtimeConfiguration) - 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) andproperties.settings.inactivityTimeoutDuration(ISO 8601). For backward compatibility with older API responses, also acceptsessionTimeoutEnabled/sessionTimeoutInactivityDuration. - Convert ISO 8601 duration to minutes (handles
PT60M,PT2H,PT1H30Mformats) - 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_inactivitytimeoutcompliancestable - If policy missing:
- Write Unknown compliance record
- Log
MissingPolicyerror tofsi_inactivitytimeouterrorlogstable - If BAP API error:
- Write Unknown compliance record
- Log API error with HTTP status code to error log table
-
Error Isolation: Individual environment failures do not abort scan
-
Summary Reporting:
- 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)
- Non-Compliant records (
- Guarded Notification: Only send email if Non-Compliant count > 0 OR Unknown count > 0
- Build HTML email with:
- Scan summary (compliant/non-compliant/unknown counts)
- Detailed issues table (environment, zone, status, timeout enabled, actual duration, required max, notes)
-
Send email with High importance to configured recipients
-
Error Handling:
- Outer scope catch for unexpected flow failures
- 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 thefsi_ITE_BapApiBaseUrlenvironment variable (defaults tohttps://api.bap.microsoft.comfor 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: iffsi_ITE_NotificationRecipientsis empty, emails are silently skipped rather than causing a flow error. Loop concurrency is hardcoded to 5 in the flow'sruntimeConfiguration.
Email Alert Format:
Subject (Non-Compliant):
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_environmentpoliciesto resolve the per-environment policy. The PowerShell scanner shipped inscripts/governance/Get-ExpectedTimeoutPolicy.ps1does 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, populatefsi_environmentpoliciesand 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
- Enable MSI for the Power Platform environment:
- Navigate to Azure Portal → Managed Identities → Create
- Assign identity to Power Platform environment
- Grant Power Platform Admin role to MSI:
- Navigate to Microsoft 365 Admin Center → Roles → Power Platform Admin → Members
- Add the MSI service principal as a member
- 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):
- Create
fsi_environmentpoliciestable: - Display Name: Environment Policies
- Plural Name: Environment Policies
- Primary Column:
fsi_environmentid(Text, 100 characters) - Add columns per Data Model section
-
Create choice field
fsi_zonefrom global option setfsi_ITE_zone:100000001=Personal,100000002=Team,100000003=Enterprise -
Create
fsi_inactivitytimeoutcompliancestable: - Display Name: Inactivity Timeout Compliances
- Plural Name: Inactivity Timeout Compliances
- Primary Column: Auto-number (e.g.,
ITC-{SEQNUM:5}) - Add columns per Data Model section
-
Create choice field
fsi_compliancestatusfrom global option setfsi_ITE_compliancestatus:100000000=Compliant,100000001=NonCompliant,100000002=Unknown -
Create
fsi_inactivitytimeouterrorlogstable: - Display Name: Inactivity Timeout Error Logs
- Plural Name: Inactivity Timeout Error Logs
- Primary Column: Auto-number (e.g.,
ERR-{SEQNUM:5}) - Add columns per Data Model section
Step 3: Build the Cloud Flow
- Navigate to Power Automate → Cloud flows → + New → Scheduled cloud flow
- Build the flow manually following the configuration steps in the sections below
- The flow should follow the architecture pattern described in the Architecture Overview above
Step 4: Configure Connection References
- Open flow in edit mode
- Navigate to Data → Connection References
- Create connections:
- Dataverse: Use Entra ID authentication (service account or current user)
- Office 365 Outlook: Use current user authentication
- Map connections to connection references:
fsi_cr_dataverse_inactivitytimeout→ Dataverse connectionfsi_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
- Open flow in edit mode
- Click "Turn on" to activate
- Verify trigger configuration: Daily recurrence at 06:00 UTC
- Save flow
Deployment Validation¶
Test 1: Manual Flow Run
- Open flow → Run → Confirm success
- Check Dataverse
fsi_inactivitytimeoutcompliancestable for compliance records - Verify scan run ID is consistent across all records for this execution
- Check email inbox for notification (only sent if issues detected)
Test 2: Policy Resolution
- Create test policy in
fsi_environmentpoliciestable: - Environment ID:
Test-Environment-12345 - Display Name:
Test Environment - Zone:
2(Team) - Required Max Duration:
120minutes - Verify flow resolves policy during next run
- Check compliance record has correct zone and required max values
Test 3: Compliance Detection (Non-Compliant Scenario)
- Identify test environment with timeout > 120 minutes (or disabled)
- Add policy for test environment to
fsi_environmentpoliciestable (required max: 120) - Run flow manually
- Verify compliance record status = Non-Compliant (1)
- Verify email notification sent with environment details
Test 4: Error Handling (Missing Policy)
- Remove policy for a known environment from
fsi_environmentpoliciestable - Run flow manually
- Verify compliance record status = Unknown (2)
- Check
fsi_inactivitytimeouterrorlogstable forMissingPolicyerror entry - 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.ps1in 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:
- Scheduled Power Automate flow: Create a companion flow that runs weekly or monthly. Use a Dataverse
ListRecordsaction filtered byfsi_lastscandate lt <cutoff_date>and delete records exceeding the retention period (7 years for compliance records, 3 years for error logs). - 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.
- 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:
- If timeout disabled: Return
0minutes - If format contains both H and M: Extract hours and minutes, convert to total minutes
- If format contains only H: Extract hours, multiply by 60
- If format contains only M: Extract minutes directly
- If format is invalid: Log
ParseErrorto 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¶
-
BAP Admin API version (List_Environments): The
List_Environmentsaction usesapi-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. -
Condition_Has_Issues run-after configuration: The
Condition_Has_Issuesaction runs afterQuery_NonCompliant_Records,Query_Unknown_Records, andQuery_Compliant_Countwith["Succeeded", "Failed"]run-after condition. All expressions that reference query result bodies usecoalesce(..., json('[]'))to return an empty array when a query fails, ensuring graceful handling of partial query failures without crashing the flow. -
List_Environments pagination: The
List_EnvironmentsHTTP action retrieves only the first page of environments from the BAP Admin API. Tenants with environments exceeding the default API page size (~500) should implementnextLinkpagination 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.