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 the platform for. 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 and 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 if you need any help or assistance with it you can reach me on Twitter or through the Get Help with Microsoft Flow threads by posting an issue referencing this post.
Thanks for reading, Alan.
Comments
-
The Sweetest Graph Call You've Ever Seen - Hiding Data in Flow
Hi @AlanPs1
I would say the correct way to secure secrets is to not have them in the flow as "magic strings" at all.
The place for these values to be is Azure Key Vault.
The basic flow would be to load the secrets from Key Vault using Azure Key Vault | Microsoft Power Automate
(not using the service principal in there - because that would lead to an infinte loop of not securing secrets 😉 ) but using the default AAD auth.Then feed the secrets retrieved from key vault to the respective actions.
Hope that makes sense.
-
The Sweetest Graph Call You've Ever Seen - Hiding Data in Flow
Hi @DanielAmico , you're right, I am only hiding it not securing it. This post is more of a conceptual look at ways to hide data and use actions() to access "trackedProperties". It makes it a little more tricky for user's to access then plain text and means there are no need for multiple Variables or Compose actions either, so a little neater of sorts.
You're right, they could still see the information if they were looking. I belive the best way to secure this type of data would be to use a nested Flow where your Team Flow, called a private Flow that held this information.
Some rough information here (I googled "microsoft flow nested flow") - http://www.sharepointpals.com/post/Step-by-Step-Procedure-to-create-Nested-Flow-Microsoft-Flow
Whilst I haven't had the need to do this as of yet, I expect this would be the best approach although posting the question in the forum may get you other suggestions and if it were I, this is were I would start if I wanted to secure the data.
Thanks, Alan
-
The Sweetest Graph Call You've Ever Seen - Hiding Data in Flow
Very good post! Congrats!
But as far as I understood, you are really only "hiding" the data and not "securing" it from unwanted access.
Let's say you share your flow w/ someone else, they will still be able to see the tracked properties, correct?
*This post is locked for comments