{"id":7343,"date":"2023-08-04T19:15:36","date_gmt":"2023-08-04T18:15:36","guid":{"rendered":"https:\/\/rakhesh.com\/?p=7343"},"modified":"2023-08-04T19:16:17","modified_gmt":"2023-08-04T18:16:17","slug":"storing-api-keys-in-power-platform-custom-connectors","status":"publish","type":"post","link":"https:\/\/rakhesh.com\/azure\/storing-api-keys-in-power-platform-custom-connectors\/","title":{"rendered":"Storing API keys in Power Platform custom connectors"},"content":{"rendered":"

I was working with a colleague on creating a custom connector to talk to Fresh Service<\/a>. He did most of the hard work, I got involved towards the end to figure out some authentication stuff.<\/p>\n

With Fresh, for instance, to authenticate you need to send an API key<\/a>.<\/p>\n

curl -v -u apikey:X -H \"Content-Type: application\/json\" -X GET 'https:\/\/domain.freshservice.com\/api\/v2\/tickets'<\/pre>\n

The username is the API key you get from their website, the password is X (capital X).<\/p>\n

The equivalent of the above in PowerShell would be:<\/p>\n

$apiKey = \"whatever\"\r\n$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes((\"{0}:{1}\" -f $apiKey,\"X\")))\r\n\r\n$freshHeaders = @{\r\n    \"Authorization\" = \"Basic $base64AuthInfo\"\r\n    \"Content-Type\" = \"application\/json\"\r\n}\r\n\r\nInvoke-RestMethod -Headers $freshHeaders -Method 'GET' -Uri \"${freshBaseUrl}\/api\/v2\/tickets\"<\/pre>\n

Basically you have to convert the “API Key:X” bit to Base64 and then send it along.<\/p>\n

So far so good. But how about when using a custom connector? When creating one you can select Basic authentication but that just prompts the user to add the API Key and X when creating a connection using the custom connector. Which might be fine too, coz you’d want each user to use their own API key after all.<\/p>\n

\"\"<\/p>\n

But we wanted to provide the connector as something users can use without entering their key. We have a “service account” in Fresh and want to use its API key as that’s got additional rights. But at the same time we don’t want to open it up for everyone. A custom connector is perfect in that respect because we can expose just the API actions we need… if only we could figure a way of putting this key somewhere!<\/p>\n

The trick is to set the authentication as “No authentication”.<\/p>\n

\"\"<\/p>\n

And then, in the Definition section, under Policies, create a new policy.<\/p>\n

\"\"<\/p>\n

And here, give it a name, then choose the “Set HTTP header” template.\"\"<\/p>\n

After that fill as follows:<\/p>\n

\"\"<\/p>\n

Replace the bit after “Basic” with the Base64 encoded value of <username>:<password><\/code>. Which in the case of Fresh is APIKey:X<\/code>.<\/p>\n

That’s it. Now your custom connector won’t prompt users for an API key.<\/p>\n

If you export the connector, this info isn’t exported. When you import it elsewhere you will have to add it again. Which is good.<\/p>\n

There is a small catch in this though, in that when you publish the custom connector in an environment with View rights, even though the edit icon is grayed out:<\/p>\n

\"\"<\/p>\n

Someone can still click the three dots, go to View properties:<\/p>\n

\"\"<\/p>\n

And notice the “Edit” button there? Yeah… they can click it to see everything! <\/em><\/p>\n

\"\"<\/p>\n

Users can’t change anything, but this leaves the API key you added above visible to them.<\/p>\n

Which is a bummer of course. I’ve raised a ticket with Microsoft to see if we can do something about this. There’s no reason why someone with View rights should be able to see inside<\/em> the custom connector. Technically, I understand, they are still only viewing<\/em> the information.. but still, that’s not what one was expecting.<\/p>\n

Another weird behaviour with custom connectors.<\/p>\n

If you add it within an environment it respects the share permissions. As in, only those whom you make it available to as View or Edit or View & Share can actually see it (albeit also see inside it as above). On the other hand, if you add the custom connector to a solution in the environment – be it adding directly, or adding to the environment and then importing into the solution – then everyone can now see the custom connector and also edit\/ delete it. Crazy!<\/em><\/p>\n

So, always import custom connectors into your environment and not solution.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"

I was working with a colleague on creating a custom connector to talk to Fresh Service. He did most of the hard work, I got involved towards the end to figure out some authentication stuff. With Fresh, for instance, to authenticate you need to send an API key. curl -v -u apikey:X -H “Content-Type: application\/json” … Continue reading Storing API keys in Power Platform custom connectors<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[887],"tags":[182,1037],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/posts\/7343"}],"collection":[{"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/comments?post=7343"}],"version-history":[{"count":2,"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/posts\/7343\/revisions"}],"predecessor-version":[{"id":7353,"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/posts\/7343\/revisions\/7353"}],"wp:attachment":[{"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/media?parent=7343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/categories?post=7343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rakhesh.com\/wp-json\/wp\/v2\/tags?post=7343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}