Flow: The Sweetest Graph Call You've Ever Seen – Hiding Data in Flow

Hi everyone. Calling APIs from Microsoft Flow is a key part of what I use it for, as it allows me to harness data from the cloud and do useful things with it. More often than not, it helps with the creation of automated processes linked to Office 365, SharePoint and Azure, that I do so much with. Whilst doing my thing in the Flow Community Forum, I stumbled across a post from community member Roger365.

He names his post "HTTP OAuth with Client Secret" and goes on to say.

"Why do i see the client-secret as plaintext in the "Secret" field? If i would share my FLOW the other users, they will also get the client-secret. Why is that field not of type "password"? (So the value will not shown as plain-text.). At now, the secret can be reused and for me its a security issue."

Here is the post

He makes a valid point, although these fields are not password fields as they are able to take dynamic data and expressions so it is likely for that reason they are the way they are. There is no obvious way to hide data in Flow, but when I read a post from everyone's favourite #FlowNinja he put me well and truly on the scent for hiding data. Kudos to John Liu for all his wonderful insight relating to Flow generally.

So here is how I now approach hiding values and in this example I will use it to make "The Sweetest Graph Call You've Ever Seen", for now anyway.

In this post, I will assume you have an existing App in the Azure Active Directory on V1.0. If you don't or want to know more please see Register an App in the Azure Active Directory Oauth v1.0.

So here is the Flow:

Yes, you see correctly, there is a "Compose" action there called "Compose BlankVariable" and on the face of it it is blank. As you now look at the HTTP request all the values are populated though. We haven't spoken yet about what is in there but clearly, Authority, Tenant, Audience, Client ID and Secret have something populated as values and when I run the Flow, this happens.

To help us understand what is going on here we will first look into action() from The Functions reference for Workflow Definition Language.

What this means is that the somewhat hidden "Tracked Properties" can be utilised and returned in your Flow. When the penny dropped for me on this one I didn't bother to bend down and pick it up. I put my mobile phone down and ran swiftly to my desktop PC in order to get Flowing and hiding data. Here is my approach.

When you click the ellipses on "Compose BlankVariable" you choose settings, when you do this you see the "Tracked Properties". Use the following expression with the things you want to hide.

@concat('<Your Expression or String>', action().outputs)

My example with some of the values Xd and Yd out for security of my data.

@concat('586XXXd6-XXXX-YYYY-XXXX-1d15a8XXX6d5', action().outputs)

I am basically concatenating a text string with "action().outputs" and that happens to be blank at this time. There is no value in the Compose on the front end and Flow seems happy to leave it that way when there are "Tracked Properties" populated. This is part of the magic behind hiding the data.

The values within Authority & Audience are not private, although I still prefer to load them in this way so here is the expression for each below.

Authority

@concat('https://login.microsoft.com/', action().outputs)

Audience

@concat('https://graph.microsoft.com', action().outputs)

Populate what you want to hide, then once you run the Flow with just a button and the "Compose" actions for now(no need to add HTTP just yet), you will see the following output from the "BlankVariable".

So what exactly are we working with here if the output is blank. Let's move on to consider each expression used within the above featured HTTP action.

TenantID

actions('Compose_BlankVariable').trackedProperties['TenantID']

ClientID

actions('Compose_BlankVariable').trackedProperties['ClientID']

SecretID

actions('Compose_BlankVariable').trackedProperties['SecretID']

Authority

actions('Compose_BlankVariable').trackedProperties['Authority']

Audience

actions('Compose_BlankVariable').trackedProperties['Audience']

Referencing the links to the WDL reference will help you understand the method of creating these expressions but you will be able to copy and paste what is above in this example. As you can see, I am making an extremely simple Microsoft Graph call and below shows that it returns data successfully.

You can now move on do more with this model and hide a whole lot more(as I do) when you are building and planning your Flows. So I hope you find this useful and helpful and if you need any help or assistance with it you can reach me on Twitter or through the Flow Community Forum but posting issues in the threads.

Thanks for reading, Alan.