How to allow “Run Only User” to cancel a desktop flow trigger from cloud?
Use Case
In many organizations, business users are not granted owner/co-owner access but are allowed to run or trigger flows by granting ‘Run Only User‘ access permission. Business users can’t cancel the flow due to this restriction. To address this limitation, we can leverage SharePoint list & power automate cloud flows to allow them to cancel the flow on need basis.
In the below example, business users trigger desktop flow from cloud with some input values. The desktop flow runs in unattended mode on machine.
The cloud flow has been shared with 2 business users with “Run Only Users” access:
Solution
Set up SharePoint List
Firstly, lets create a SharePoint list ‘Flow Runs’ that holds the details of desktop flow along with parent cloud flow instacne details:
Column structure of the SharePoint list ‘Flow Runs’ is as follows:
Column Display Name | Type | Remarks |
Title | Single line of text | Name of the parent cloud flow |
Status | Single line of text | |
Start Time | Date and Time | Toggle on include time setting |
End Time | Date and Time | Toggle on include time setting |
Wait Duration(mins) | Single line of text | |
Run Duration(mins) | Single line of text | |
Machine CPU Usage(%) | Single line of text | |
Machine Ram Usage(%) | Single line of text | |
Machine HostName | Single line of text | |
Session UserName | Single line of text | |
Environment Id | Single line of text | |
Cancelled On | Date and Time | Toggle on include time setting |
Cancelled By | Person or Group | |
Flow Session Id | Single line of text | Toggle on ‘Enforce unique values’ setting |
Parent Workflow Id | Single line of text | |
Parent Workflow Instance Id | Single line of text |
Automate Flow to Save data in SharePoint List
Secondly, get the Id of the parent cloud flow that triggers desktop flow. Go to flow details screen and grab the Id from the web address or URL. You need to pick the text visible after flows parameter in the URL as mentioned below:
We need this Id when we query the ‘Flow Session‘ entity to make sure that flow will trigger only for this desktop flow. You may include other parent cloud flows in this framework by appending their Id in ‘Filter rows’ of ‘When a row is added, modified or deleted’ trigger.
1. Create automated flow with “When a row is added, modified or deleted” trigger. Choose change types as ‘Added or Modified’. Select ‘Flow Sessions’ as table name. As we want to monitor run instances of particular cloud flow(s) so we will use ‘Filter rows’ parameter to restrict this flow trigger for other cloud flows. Enter ‘statuscode’ in ‘Select columns’ to make sure that flow triggers on status change only (Waiting, Running etc.):
Filter query used in above screenshot:
contains('2d0acb01-bc1d-4a47-880c-1008a2171493',parentworkflowid)
Here, 2d0acb01-bc1d-4a47-880c-1008a2171493 is the Id of parent cloud flow that trigger desktop flow. In this framework, you may include additional cloud flows but you need to create a single comma separated string of all cloud flow Ids:
contains('<comma separated cloud flows id>',parentworkflowid)
2. Next, add “Compose” action to get the value of context object from the trigger body. Use expression to convert string to JSON object. Expression needs to be added in the expression box:
json(triggerOutputs()?['body/context'])
3. Add another “Compose” action to get the workflow object. We need this to get the Environment Id and this will be used in cancelling the run instance of the cloud flow. Use below expression in the compose action:
workflow()
4. Now, add “Condition” action to check if the record in ‘Flow Session’ table is created or updated & accordingly we will create an item or update item in SharePoint list in “Yes/No” branches. Enter below expression for the left side textbox in the Condition action:
triggerOutputs()?['body/sdkMessage']
In “Yes” branch, add “List rows” action to get the name of the parent cloud flow. Select ‘Processes’ in table name dropdown. Enter below filter query to get the record of parent cloud flow:
resourceid eq '@{triggerOutputs()?['body/parentworkflowid']}'
Just copy & paste above filter query directly in the “List rows” action.
Note: Process table stores the details of solution aware flow or flows stored inside solutions. This action will return no record for non-aware solution parent cloud flow. So, store parent cloud flow in solution to get the name of it.
Just below “List rows” action, add “Create item” action to insert an item in SharePoint list. Choose SharePoint site URL & List Name from the drop down:
Copy & paste below expression in the SharePoint columns:
Flow Session Id | @{triggerOutputs()?[‘body/flowsessionid’]} |
Title | @{if(greater(length(outputs(‘List_rows’)?[‘body/value’]),0),first(outputs(‘List_rows’)?[‘body/value’])?[‘name’],”)} |
Status | @{triggerOutputs()?[‘body/_statuscode_label’]} |
Start Time | @{triggerOutputs()?[‘body/createdon’]} |
Environment Id | @{outputs(‘Compose_2’)?[‘tags’]?[‘environmentName’]} |
Parent Workflow Id | @{triggerOutputs()?[‘body/parentworkflowid’]} |
Parent Workflow Instance Id | @{triggerOutputs()?[‘body/parentcloudflowrunsequenceid’]} |
Add “List Flow Run-Only Users” action to get the run only user list of the cloud flow. Pass the Environment Id & Parent workflow id dynamically as shown below:
Add “Apply to each” action, pass the value object from the output of previous action. Inside “Apply to each” block, add “Get user profile” action to get the email address of run only user based on the id. Pass the object Id from the output of previous action:
Inside “Apply to each 2” action block, add compose action & dynamically pass the Mail property from the output of ‘Get user profile’ action:
To grant item permission action, add ‘Grant access to an item or a folder’ action. Select the SharePoint URL & List Name from the dropdown. Pass the ID from the output of “Create item” action. Enter below expression for setting the Recipients. Select ‘Can view’ in ‘Roles’ parameter:
join(outputs('Compose_3'),';')
Next go back to step 4, we will add actions in “No” branch. Add “Get items” action to search item based on the flow session id using filter query. Select SharePoint site URL & List name from the dropdown. Enter below query in ‘Filter query’ parameter:
FlowSessionId eq '@{triggerOutputs()?['body/flowsessionid']}'
Just copy & paste above query directly in “Get items” action.
Add “Apply to each” action & pass value object from the output of “Get items” action. Inside apply to each block, add “Update item” to modify the values. Select SharePoint site URL & List name from the dropdown. Pass the ID from the output of “Get items” action as shown below. Copy & paste the below expression in columns mentioned below:
Flow Session Id | @{triggerOutputs()?[‘body/flowsessionid’]} |
Status | @{triggerOutputs()?[‘body/_statuscode_label’]} |
End Time | @{triggerOutputs()?[‘body/completedon’]} |
Wait Duration(mins) | @{if(empty(string(triggerOutputs()?[‘body/runwaitduration’])),null,div(triggerOutputs()?[‘body/runwaitduration’],60000))} |
Run Duration(mins) | @{if(empty(string(triggerOutputs()?[‘body/runduration’])),null,div(triggerOutputs()?[‘body/runduration’],60000))} |
Machine CPU Usage(%) | @{triggerOutputs()?[‘body/machinepercentcpuusage’]} |
Machine Ram Usage(%) | @{triggerOutputs()?[‘body/machinepercentramusage’]} |
Machine HostName | @{outputs(‘Compose’)?[‘hostName’]} |
Session UserName | @{triggerOutputs()?[‘body/sessionusername’]} |
Instant cloud flow to cancel the flow run instance
We will set up a cloud flow to cancel the cloud flow run instance. Create ‘Instant flow’, name it as ‘Cancel Run’ and set trigger as ‘For a selected item’.
Note: The trigger ‘For a selected item’ can only be setup on default environment so you need to design this flow in default environment.
1. Select the SharePoint site URL & list name from the drop down:
2. Add “Get item” action & pass Id from the trigger. Choose SharePoint site URL & List name from the dropdown:
3. Next, add “Cancel Flow Run” action to cancel the flow instance. Pass value of ‘Environment Id’, ‘Parent Workflow Id’ & ‘Parent Workflow Instance Id’ from the output of “Get item” action as shown below:
4. Finally, update the columns values using “Update Item” action. Dynamically pass the Id & Flow session id from the output of “Get item” action. Enter expression for ‘Cancelled On’ & ‘Cancelled By’ columns:
Expression used for ‘Cancelled On’ parameter:
utcNow()
Expression used for ‘Cancelled By’ parameter:
concat('i:0#.f|membership|',decodeBase64(triggerOutputs()['headers']['x-ms-user-email-encoded']))
Configuration & Sharing flow
We need to share ‘Cancel Run’ cloud flow to users so that they can trigger it from the SharePoint list. Go to ‘Flow details’ page & scroll down to ‘Run only users‘ and click Edit button:
Add email of business users who are supposed to cancel the flow runs from SharePoint list:
As business users can’t cancel flow runs so select static connection for ‘Cancel a flow’ action. Set static connection for SharePoint connection as business users can’t update list items too.
With this configuration, update SharePoint list & cancel flow run operation will run under higher privilege account:
Click ‘Save’ to save the changes.
Output
Business user triggers parent cloud flow with input parameters:
Automate cloud flow saves the details in the SharePoint list when desktop flow runs on the machine:
The cloud flows correctly set item level view permission for run only users or business users.
Business user triggers cancel flow run request by clicking ‘Cancel Run’ button from the sub menu:
The ‘Cancel Run’ flows cancel the parent cloud flow based on the details saved in the SharePoint item:
As it takes a while to cancel the desktop flow instance so list item status will be updated as ‘Cancelled’ after some time:
The details of ‘Cancelled by’ & ‘Cancelled On’ are also updated along with other details:
Conclusion
You can allow ‘Run only users’ to cancel the flow run instances by leveraging SharePoint list & cloud flows with power automate admin connector.
You can easily add other parent cloud flow(s) in this reusable framework by:
- Adding cloud id in the ‘Filter rows’ action of automated flow
- Share ‘Cancel Run’ flow with run only users of parent cloud flow
- Framework support for both attended/unattended runs trigger from cloud