Path A: Dataverse-Only Implementation
Status: February 2026 - FSI-AgentGov v1.2.51 Estimated Effort: 4-6 hours for experienced Power Platform administrator Prerequisites: Architecture reviewed
Overview
Path A implements the complete Platform Change Governance solution using Dataverse as the sole system-of-record. This path provides full regulatory compliance without Azure DevOps integration.
When to use Path A:
- Organization does not use Azure DevOps for change execution
- Primary users are business/compliance stakeholders (not engineering)
- Simpler governance workflow is sufficient
- Minimal training investment desired
Prerequisites
- Power Platform environment (Developer, Sandbox, or Production)
- Dataverse System Admin or Power Platform Admin role
- Microsoft Entra app registration created (for Graph API access)
-
ServiceMessage.Read.Allapplication permission granted with admin consent - Microsoft 365 E3/E5 licenses
Step 1: Create Solution
All components should be created within a single solution for ALM and deployment purposes.
- Navigate to Power Apps Maker Portal
- Select your target environment
- Go to Solutions → New solution
- Configure solution:
- Display name: Message Center Governance
- Name: MessageCenterGovernance
- Publisher: Select or create your publisher
- Version: 1.0.0.0
- Click Create
Step 2: Create Dataverse Tables
Table 2.1: MessageCenterPost
- Open your solution → Add existing → Table (or New → Table)
- Select New table with these settings:
- Display name: Message Center Post
- Plural name: Message Center Posts
- Name: mc_messagecenterpost
- Primary column: mc_title
- Ownership: User or team
-
Enable auditing: Yes
-
Add columns:
| Display Name | Name | Type | Required | Notes |
|---|---|---|---|---|
| Message Center ID | mc_messagecenterid | Text (50) | Yes | Primary key, set as Alternate Key |
| Title | mc_title | Text (500) | Yes | Primary column |
| Category | mc_category | Choice | No | Values: preventOrFixIssue, planForChange, stayInformed |
| Severity | mc_severity | Choice | No | Values: normal, high, critical |
| Services | mc_services | Multiline Text | No | JSON array of affected services |
| Tags | mc_tags | Multiline Text | No | JSON array of tags |
| Start Date | mc_startdatetime | Date and Time | No | |
| End Date | mc_enddatetime | Date and Time | No | |
| Action Required By | mc_actionrequiredby | Date and Time | No | |
| Body | mc_body | Multiline Text (Rich) | No | Full HTML content |
| State | mc_state | Choice | Yes | Values: New, Triage, Assess, Decide, Closed |
| Impact Assessment | mc_impactassessment | Choice | No | Values: None, Low, Medium, High |
| Relevance | mc_relevance | Choice | No | Values: Not Applicable, Informational, Action Required |
| Decision | mc_decision | Choice | No | Values: Accept, Defer, Escalate, No Action Required |
| Decision Rationale | mc_decisionrationale | Multiline Text | No | |
| Owner | mc_owner | Lookup (User) | No | |
| Last Modified DateTime | mc_lastmodifieddatetime | Date and Time | No | From Graph API |
- Create Alternate Key on
mc_messagecenteridfor upsert operations
Table 2.2: AssessmentLog
- Create new table:
- Display name: Assessment Log
- Name: mc_assessmentlog
- Primary column: al_assessmentid (auto-number or GUID)
- Ownership: User or team
-
Enable auditing: Yes
-
Add columns:
| Display Name | Name | Type | Required |
|---|---|---|---|
| Message Center Post | al_messagecenterpost | Lookup | Yes |
| Assessed By | al_assessedby | Lookup (User) | Yes |
| Assessed On | al_assessedon | Date and Time | Yes |
| Impact Assessment | al_impactassessment | Choice | Yes |
| Notes | al_notes | Multiline Text | No |
| Recommended Action | al_recommendedaction | Choice | No |
| Affected Systems | al_affectedsystems | Multiline Text | No |
- Configure relationship to MessageCenterPost as Restrict Delete
Table 2.3: DecisionLog
- Create new table:
- Display name: Decision Log
- Name: mc_decisionlog
- Primary column: dl_decisionid (auto-number or GUID)
- Ownership: Organization-owned
-
Enable auditing: Yes
-
Add columns:
| Display Name | Name | Type | Required |
|---|---|---|---|
| Message Center Post | dl_messagecenterpost | Lookup | Yes |
| Decided By | dl_decidedby | Lookup (User) | Yes |
| Decided On | dl_decidedon | Date and Time | Yes |
| Decision | dl_decision | Choice | Yes |
| Decision Rationale | dl_decisionrationale | Multiline Text | Yes |
| External Ticket Reference | dl_externalticketreference | Text (200) | No |
- Configure relationship to MessageCenterPost as Restrict Delete
Organization-Owned for Immutability
DecisionLog must be organization-owned to prevent user modification after creation. This supports SEC 17a-4 requirements for immutable records.
Step 3: Enable Dataverse Auditing
- Go to Power Platform Admin Center
- Select your environment → Settings → Audit and logs → Audit settings
- Enable:
- Start Auditing
- Audit user access
- Read logs (optional, high volume)
- For each table (MessageCenterPost, AssessmentLog, DecisionLog):
- Open table settings → Advanced options → Audit changes to its data
- Enable auditing for all columns
Step 4: Create Security Roles
Role 4.1: MC Admin
- In your solution → Add existing → Security role → New security role
- Name: MC Admin
- Configure privileges:
| Entity | Create | Read | Write | Delete | Append | Append To |
|---|---|---|---|---|---|---|
| MessageCenterPost | Org | Org | Org | None | Org | Org |
| AssessmentLog | None | Org | None | None | None | Org |
| DecisionLog | None | Org | None | None | None | Org |
Role 4.2: MC Owner
- Create new security role: MC Owner
- Configure privileges:
| Entity | Create | Read | Write | Delete | Append | Append To |
|---|---|---|---|---|---|---|
| MessageCenterPost | None | User | User | None | User | User |
| AssessmentLog | User | User | User | None | User | User |
| DecisionLog | User | User | None | None | User | User |
Role 4.3: MC Compliance Reviewer
- Create new security role: MC Compliance Reviewer
- Configure privileges:
| Entity | Create | Read | Write | Delete | Append | Append To |
|---|---|---|---|---|---|---|
| MessageCenterPost | None | Org | None | None | None | Org |
| AssessmentLog | None | Org | None | None | None | Org |
| DecisionLog | Org | Org | Org | None | Org | Org |
Role 4.4: MC Auditor
- Create new security role: MC Auditor
- Configure privileges (read-only):
| Entity | Create | Read | Write | Delete | Append | Append To |
|---|---|---|---|---|---|---|
| MessageCenterPost | None | Org | None | None | None | None |
| AssessmentLog | None | Org | None | None | None | None |
| DecisionLog | None | Org | None | None | None | None |
Step 5: Create Power Automate Ingestion Flow
- Go to Power Automate → My flows → New flow → Scheduled cloud flow
- Configure schedule:
- Name: MC Ingestion - Message Center Posts
- Run every: 15 minutes
Flow Actions
Action 1: Initialize Variable - Last Run Timestamp
Name: varLastRunTimestamp
Type: String
Value: @{addMinutes(utcNow(), -30)}
Action 2: HTTP - Get Access Token
Method: POST
URI: https://login.microsoftonline.com/@{variables('TenantId')}/oauth2/v2.0/token
Headers:
Content-Type: application/x-www-form-urlencoded
Body: grant_type=client_credentials&client_id=@{variables('ClientId')}&client_secret=@{variables('ClientSecret')}&scope=https://graph.microsoft.com/.default
Action 3: Parse JSON - Extract Token
Content: @{body('HTTP_-_Get_Access_Token')}
Schema:
{
"type": "object",
"properties": {
"access_token": { "type": "string" },
"token_type": { "type": "string" },
"expires_in": { "type": "integer" }
}
}
Action 4: HTTP - Get Message Center Posts
Method: GET
URI: https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/messages?$filter=lastModifiedDateTime gt @{variables('varLastRunTimestamp')}&$orderby=lastModifiedDateTime asc
Headers:
Authorization: Bearer @{body('Parse_JSON_-_Extract_Token')?['access_token']}
Action 5: Apply to Each
For each item in body('HTTP_-_Get_Message_Center_Posts')?['value']:
Action 5a: Upsert Row (Dataverse)
Table name: Message Center Posts
Alternate Key: mc_messagecenterid = @{items('Apply_to_each')?['id']}
mc_title: @{items('Apply_to_each')?['title']}
mc_category: @{items('Apply_to_each')?['category']}
mc_severity: @{items('Apply_to_each')?['severity']}
mc_services: @{json(items('Apply_to_each')?['services'])}
mc_startdatetime: @{items('Apply_to_each')?['startDateTime']}
mc_enddatetime: @{items('Apply_to_each')?['endDateTime']}
mc_actionrequiredby: @{items('Apply_to_each')?['actionRequiredByDateTime']}
mc_body: @{items('Apply_to_each')?['body']?['content']}
mc_lastmodifieddatetime: @{items('Apply_to_each')?['lastModifiedDateTime']}
mc_state handling
Do not set mc_state on the upsert action — this would reset records that have progressed through the triage workflow back to New. Instead, configure a Dataverse business rule to default mc_state to New only on record creation.
Action 6: Send Notification (Optional)
Send email or Teams message on successful completion or errors.
Step 6: Create Model-Driven App
- In your solution → New → App → Model-driven app
- Name: Message Center Governance
- Add tables to navigation:
- Message Center Posts (with views and forms)
- Assessment Log (as subgrid in MessageCenterPost form)
- Decision Log (as subgrid in MessageCenterPost form)
Configure Views
Create these views for MessageCenterPost:
| View Name | Filter |
|---|---|
| New Posts - Awaiting Triage | mc_state = New |
| High Severity Posts | mc_severity IN (high, critical) |
| My Assigned Posts | mc_owner = current user |
| Posts by Category | Group by mc_category |
| All Open Posts | mc_state != Closed |
| Recently Closed | mc_state = Closed ordered by modified desc |
Configure Main Form
Tab 1: Overview
- Title, Category, Severity (header)
- Services, Tags, State
- Owner, Action Required By
Tab 2: Message Content
- Body (rich text, read-only)
Tab 3: Assessment
- Impact Assessment, Relevance
- AssessmentLog subgrid
Tab 4: Decision
- Decision, Decision Rationale
- DecisionLog subgrid
Tab 5: Audit Trail
- Timeline control
Step 7: Create Business Process Flow (Optional)
- In your solution → New → Automation → Business process flow
- Name: Message Center Governance Process
- Entity: Message Center Post
Stages:
- New - Trigger: Record created
- Triage - Required: Owner assigned
- Assess - Required: Impact Assessment, Relevance
- Decide - Required: Decision, Decision Rationale (min 50 char)
- Closed - Completion stage
Step 8: Configure Environment Variables
Create environment variables for deployment flexibility:
| Variable | Type | Default Value | Description |
|---|---|---|---|
| MCG_TenantId | Text | (tenant GUID) | Microsoft Entra ID tenant |
| MCG_ClientId | Text | (app GUID) | App registration client ID |
| MCG_ClientSecret | Secret | (stored in Key Vault) | App registration secret |
| MCG_PollingIntervalMinutes | Number | 15 | Ingestion polling interval |
Verification Checklist
- All three tables created with correct columns and settings
- Auditing enabled on all tables
- Alternate key created on MessageCenterPost for upsert
- Security roles created and assigned to test users
- Ingestion flow runs successfully and creates/updates posts
- Model-driven app accessible with correct views
- Business process flow guides users through workflow
- Decision rationale enforces minimum 50 character requirement
- Audit logs capture all field changes
Post-Implementation
After completing Path A:
- Assign roles to production users
- Monitor ingestion flow for errors
- Train users on triage and decision workflows
- Configure quarterly evidence export (see Evidence and Audit)
- Optionally proceed to Path B for ADO integration
FSI Agent Governance Framework v1.2.51 - February 2026