Read Only Sharing in Power Automate
Tags: powerautomate, powerplatform, lowcode, rpa
Published: 2023-12-04 07:30:34

One of the big things missing in Power Automate is read only roles. At the moment if you want to share a flow for someone to look at or see the logs, you have to give them full edit access.

Not only is this a pain, it opens you up to being hacked ([hacked-by-power-automate](https://dev.to/wyattdave/hacked-by-power-automate-and-how-to-avoid-it-3052)) and it means that you cant see what's happening in your production environments (if you have proper separation of duty, and you should).

Fortunately there is a clever workaround, but its not quite perfect because:

- It only works on your production environments (i.e nothing can be created new in the environment)
- Requires pre configuration of your Solutions (so you cant retrospectively add it)

---

The magic happens because of 3 key things:

1. Managed Solutions stop you editing the flows
2. Allow Customizations false stops editing through solution layers
3. Basic Security Role allows access but no ability to make

And if you want to it is quite easy to automate it, leveraging the updating zip technique here [update-contents-of-a-zip-file-with-power-automate](https://dev.to/wyattdave/how-to-update-contents-of-a-zip-file-with-power-automate-3b1b), as a solution is just a zip.

## 1. Managed Solutions
This one is easy, when exporting the solution ensure it is set to managed (it is by default).

![managed solution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m3vcs6nvgy5rgojltqdf.png)

To automatically do, you need to update the **Solution.xml** file. It looks something like below:

Part of the solution.xml file
``` xml
<ImportExportXml version="9.2.23082.190" SolutionPackageVersion="9.2" languagecode="1033" generatedBy="CrmLive" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SolutionManifest>
    <UniqueName>TextBasedGame</UniqueName>
    <LocalizedNames>
      <LocalizedName description="Text Based Game" languagecode="1033" />
    </LocalizedNames>
    <Descriptions />
    <Version>1.0.0.0</Version>
    <Managed>0</Managed>
    <Publisher>
      <UniqueName>WyattDave</UniqueName>
      <LocalizedNames>
        <LocalizedName description="WyattDave" languagecode="1033" />
      </LocalizedNames>
      <Descriptions />
```

`<Managed>0</Managed>` needs to be updated `<Managed>1</Managed>`

## 2. Allow Customizations to false 
The Power Platform allows something could 'Solution Layers' which just allow updates to managed flows and other components. It keeps the original flow but adds any edits on top. The main reason is for hotfixes (though I'm not a fan of any direct prod edits), as it allows you to remove the fix later (almost like version control). 
What I don't like about this is it can trick people into thinking it is read only, as managed states that (not good for citizen developers who don't have time to read all the documentation).

Each component needs to be set individually from within the solution, under managed properties.

![managed properties](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6n6gpnw4nmarrie0jf5h.png)

![customization false](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5a0kixybwnoyd60c6xgb.png)

This is also pretty easy to automatically update as its another plain text xml file, this time the **Customizations.xml**.

The customizations.xml lists all of the components of the solution (e.g. flows, Apps, Environment Variables, Connection References). Solution components are basically rows from each of the different Dataverse tables, so the customizations.xml file lists the kind of metadata for them in relation to the solution.

Flow Example
``` xml
<ImportExportXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Entities></Entities>
  <Roles></Roles>
  <Workflows>
    <Workflow WorkflowId="{f65502d4-6758-ee11-be6f-000d3a5a7615}" Name="Canyon Escape">
      <JsonFileName>/Workflows/CanyonEscape-F65502D4-6758-EE11-BE6F-000D3A5A7615.json</JsonFileName>
      <Type>1</Type>
      <Subprocess>0</Subprocess>
      <Category>5</Category>
      <Mode>0</Mode>
      <Scope>4</Scope>
      <OnDemand>0</OnDemand>
      <TriggerOnCreate>0</TriggerOnCreate>
      <TriggerOnDelete>0</TriggerOnDelete>
      <AsyncAutodelete>0</AsyncAutodelete>
      <SyncWorkflowLogOnFailure>0</SyncWorkflowLogOnFailure>
      <StateCode>1</StateCode>
      <StatusCode>2</StatusCode>
      <RunAs>1</RunAs>
      <IsTransacted>1</IsTransacted>
      <IntroducedVersion>1.0.0.0</IntroducedVersion>
      <IsCustomizable>1</IsCustomizable>
      <BusinessProcessType>0</BusinessProcessType>
      <IsCustomProcessingStepAllowedForOtherPublishers>1</IsCustomProcessingStepAllowedForOtherPublishers>
      <PrimaryEntity>none</PrimaryEntity>
      <LocalizedNames>
        <LocalizedName languagecode="1033" description="Canyon Escape" />
      </LocalizedNames>
    </Workflow>
  </Workflows>
```

Connection References Example

``` xml
<connectionreferences>
    <connectionreference connectionreferencelogicalname="wd_ConversionGame">
      <connectionreferencedisplayname>Conversion-Game</connectionreferencedisplayname>
      <connectorid>/providers/Microsoft.PowerApps/apis/shared_conversionservice</connectorid>
      <iscustomizable>1</iscustomizable>
      <statecode>0</statecode>
      <statuscode>1</statuscode>
    </connectionreference>
    <connectionreference connectionreferencelogicalname="wd_ExcelGame">
      <connectionreferencedisplayname>Excel-Game</connectionreferencedisplayname>
      <connectorid>/providers/Microsoft.PowerApps/apis/shared_excelonline</connectorid>
      <iscustomizable>1</iscustomizable>
      <statecode>0</statecode>
      <statuscode>1</statuscode>
    </connectionreference>
```

`<IsCustomizable>1</IsCustomizable>` needs to be updated to `<IsCustomizable>0</IsCustomizable>`,
Strangely Connection References use a different tag (`<iscustomizable>1</iscustomizable>`, so no capital c), but it doesn't matter if these are update to false.

## 3. Basic Security Role 
The Basic security role allows the user to see and edit rows they own, so for standard Dataverse tables they can create, read, update, delete their own entries. The other thing it gives is read only access to system rows they own (though they cant create, update, delete). And as solution components are just rows in Dataverse tables it means the role can give the read only access (as long as they are made the owner).

![basic role](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/al14joqcbn5gg802njl6.png)

---

And that's it, the developer can now see the flow but not edit, and they can't create anything new in the environment. Plus they can't see any solutions or other components to edit (like Environment Variables and Connections) so change control is protected.

![flow logs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gooq9cm40u4k4hft3z6m.png)

One big call out though is the use of 'Secure Outputs', as these will need to be set if the flow is passing any confidential data. Its a pain as every action that brings in data will need to been set to secure to hash the data (hopefully Microsoft will introduce a Flow/Environment level setting to turn it on).

![secure inputs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ad4zp3wdrhlspwjixsmm.png)