How to Enable Programmatic Interaction with Azure Blockchain Workbench APIs

In this guide, we’ll walk through creating our own API with Azure Functions, and giving that API the ability to call the Azure Blockchain Workbench APIs. This is quite a common scenario when we want to prove out a business value by connecting different existing services (3rd party or not) to the blockchain and having it reflected in Blockchain Workbench.

Requirements

You will need to have the following installed on either PC or Mac:

  • .NET Core SDK and Azure Functions SDK
  • VSCode or Visual Studio
  • Postman

Azure Function Code

Feel free to use/modify this code sample on GitHub to your liking. Keep in mind you still have to follow a few instructions as outlined in the rest of this post!

https://github.com/malirezai/WorkbenchAzureFunctionAPI

There you’ll find a Postman collection containing all the API calls to Blockchain Workbench as well.

There’s also a walkthrough using Powershell to create an Azure Service Principal, as well as a postman collection that has everything you need for making authenticated requests to the API. You can modify the pre-request script to ensure you always have a valid token when interacting with the API.


Primer

I like to describe Azure Blockchain Workbench as a blockchain app in a box. With it, you can focus on creating your smart contract and not have to worry about all the underlying infrastructure, UI/UX and plumbing it takes to have a real working application.

First off — Workbench uses Parity’s Ethereum PoA template as the private blockchain and you can either create a new one or target an existing one. For a great intro on the way Ethereum works, please read the Ethereum whitepaper and specifically, this subsection.

We know that in order to interact with smart contracts in Ethereum, there needs to be an Ethereum account from which transactions are signed and sent.

What workbench does under the hood is create a mapping between the users defined in Azure Active Directory with an Ethereum address. This allows us to log in with our username/password pair and interact with contracts by creating transactions. Below you can see a screenshot from my instance of Workbench, and I’ve highlighted my contract address for the current logged in user:

The user is identified from the bearer token in the request, and as mentioned before, there is a mapping internal to Workbench between every user to an Ethereum account address. This address is used to interact with contracts and post transactions.

In the documentation located here, you’ll note that there are two main methods of interacting with Workbench outside of the web application.

  1. Authenticating via Azure AD with a username/password pair and retrieving a bearer token, which we use to call the Workbench API
  2. Messaging integration — this facilitates interaction with systems, services, and devices where an interactive login is not possible or desirable

These are both great, but the only problem is that with the first option — we’re limited to actual users within our AD and we have to prompt for a username/password pair. And with the second option, formatting the messages and putting them onto the service bus while using the GUI within the Azure portal can be complicated, error-prone and difficult to debug.

Motivation and End Result

What if you want to manage your own API and give that API the ability to call into Workbench to create a new contract, or post an update to a transaction? Currently, this is only doable if you use Logic Apps (or something else) to create an HTTP endpoint that has the “logic” to create the service bus message and drop it in the ingress queue, and then call that endpoint within your own API. This adds even more complexity and can get confusing…

What if we could use the different Workbench SDKs and make a call via an HTTP request? We can have our code written in an IDE, and as a developer that’s MUCH easier to write, debug and deploy.

Thankfully, there is an answer, and it works great!

GIF of invoking a local Azure Function (debugging from VSCode) from Postman

It requires a little bit of work, so let's get started!

Step 1: Setting up Azure Active Directory

Navigate to the Active Directory you’re using for Workbench and double check for a few things in the app manifest corresponding to your current registration for Workbench. This is the step that you completed during setup.

My registration is called “Workbench Blockchain Client”

Click on “Manifest”, and we’re going to make sure the JSON under the AppRoles section has one type — an Administrator. It should look like what we have below:

Make sure we have both “Application” and “User” in the allowedMemberTypes section

Next, let's create a new Web/API app registration in Active Directory. We’re going to use this for our API. Give it a name and a sign-on URL — the URL doesn’t matter at this point, it just needs to be a valid URL. Click Create.

Navigate to our newly created app registration, and click on Settings > Required Permissions

I called my registration “workbench function api test”

Click on Add -> Select an API-> Search for your Workbench client:

We can optionally give our Service Principal administrator privileges in Workbench. By being an administrator, our API can:

  • View all applications even if the role isn’t assigned to one
  • Assign and remove application users roles
  • Modify and upload applications

You can skip this step if you don’t want the service principal to have Admin privileges.

In the “Select Permissions” tab, under “Application Permissions”, click on “Administrator”, then click Select

This part is IMPORTANT — click “Grant Permissions”

Great! At this step, we have now granted our new app registration access to Workbench. Now let's check to make sure it’s there.

Navigate back to your Active Directory and click on “Enterprise Applications”, then click on “All Applications”. Select your Workbench Blockchain registration (NOT the new registration we just created):

Navigate to “Users and Groups” and you should see a list of all users for your application and now, your newly created app registration with an object type of unknown. Don’t worry about the object type.

Select it, and you should see a page similar to this one. Make note of the GUID displayed in the URL box because we will use this in the next step:

Make a note of this GUID!

Lastly — let's navigate back to our newly created app registration (this was under “App Registrations” in the Active Directory) and create a new Key with a duration of “never expires”. Once you save the Key, COPY THE VALUE.

COPY THE VALUE OF THE KEY ONCE YOU SAVE IT. YOU WON’T BE ABLE TO SEE IT AGAIN.

Step 2: Invoking the Workbench API to create a new User for our API

Go to the URL of your workbench deployment and add a “-api” at the end of the url prefix to get the swagger definition and explore the API collection. We’re going to be using the “USERS” and “APPLICATIONS” endpoints:

In order to interact with the Workbench API we need a valid Bearer token. There are a few tools already included in the workbench Github repo including a full Postman Collection as well as a few auth samples that make interaction with the API simple.

Alternatively, in Chrome, open up a new browser window and navigate to your workbench deployment. Right-click anywhere on the screen and click “Inspect”. This will bring up the Chrome developer tools window. Click on “Network” and you’ll see all the requests that are being made by Workbench. Click on some of the requests until you find something in the Headers portion — specifically under Request Headers. We’re looking for the Bearer token that we’ll use in Postman.

Copy this value (MINUS the “Bearer” Part)

Let’s go to Postman now and start interacting with the Workbench APIs.

First, let's create a new GET request at {yourAPIEndpoint}/api/v1/users to see a list of users. In the “Authorization” field, select the “Bearer token” type and paste the token you copied from chrome. Hit SEND and you should get a response back!

GET request on {yourAPIEndpoint}/api/v1/users

Now, we're going to hit the same endpoint but with a POST request, and the content of the body is going to contain a few things that this API endpoint needs. You can view the details in the swagger definition, but we need to have:

  • The “external id” — this is the GUID from the active directory page we copied earlier
  • First name, last name, and email address, which can be anything

Once you have formulated the body — click send, and the API will return an integer corresponding to the “user” we just created in Workbench for our API!

What does this step do? It creates a new Ethereum account and stores that keypair in Key Vault. Now, when we access the Workbench API with the bearer token corresponding to this API “user”, we have an account to sign transactions with!

*** MAKE A NOTE OF THE ID THE API RETURNS, WE’LL USE IT SOON***

SUCCESS! MAKE A NOTE OF THE ID THAT’S RETURNED

Lets hit the GET endpoint once more to verify we now have a user:

Great! The last user is our Blockchain API!

We can also verify this by logging into Workbench and clicking the “Membership” tab — you should see your user show up:

Awesome!

Step 3: Assigning our newly created “API User” to an Application

Normally when we want to assign users to applications in Workbench, we do so via the “Membership” option in the web application. We can’t use this option with our API because the membership tab actually looks through the MSGraph API to find users as we type in their names in the search box.

Therefore, in order to assign our “APIUser” to the role we want, we’re going to have to do it through the Workbench API:

First, let's find the ApplicationID for the app we want to assign the user to. You can find that directly in the URL box when navigating workbench. In this case, it's 29:

AppID is 29 for this “Asset Transfer” scenario

Next, let's find what the RoleID of the role we want is. The roles were defined in our Application JSON file when we created the solidity contract. In the simple “AssetTransfer” sample on Github — we know that ONLY the “Owner” role has the ability to create new contracts.

If I want my API to have the ability to create a new contract, I need to assign that user the role of “Owner”.

Back in Postman, let's do a GET on our Workbench API on /applications/29 to see what the application role ID’s are:

GET request on {yourAPIEndpoint}/api/v1/applications/{appID}

NOTE: if you get a 401 it means your token has likely expired. Just follow the steps above and get a new token again to interact with the API.

Great! We know that the “Owner” role for my “AssetTransfer” application is role ID 67.

Lets go back to Postman again and this time, make a POST API call to {yourAPIEndpoint}/api/v1/applications/{appID}/roleAssignments with the following body containing the ApplicationRoleID as well as the UserID we copied in the last step:

Success! We have now assigned our API user to the “Owner” Role

If all goes well — you should get a 200 response, and can go into your Workbench deployment to view our API user with the role of Owner! You can also modify their role at this point:

Awesome! Now our API has the role of Owner and can create new contracts!

Final Step — Creating our Azure Function, and using the ADAL Library to get a bearer token and interact with the Workbench API from our own API

For this step — please refer to my Azure function sample on Github that uses the Workbench .NET SDK as well as the ADAL libraries for active directory authentication. It’s written in C# but you could adapt it for other languages as well.

Note — I packaged the .NET SDK into a NuGet package for this demo, and I’m referencing it in the Function code. Feel free to use it if you’d like. You can also just reference the source code for the SDK.

In order to use the sample, you will need to have an IDE that can debug local Azure functions like VSCode or Visual Studio

Link to Github project containing Azure Function code: https://github.com/malirezai/WorkbenchAzureFunctionAPI

When you view the code — you’ll notice we have a few static properties at the very top

and a few more things in the “GetAuthToken” method that we require:


FIRST — Let’s get a few Properties from our Active Directory :

We need the following:

  • The TenantID of our directory we’re using for Workbench
  • The AppID of the Workbench blockchain client registration
  • The AppID of our newly created app registration
  • The AppSecret (the key we copied before Step 2 way above)

These values can all be found in your Active Directory -> App Registrations page:

The App IDs we want
The Directory ID

SECOND — let's find a few more IDs from Workbench:

We need a few things:

  • The Workflow ID of the workflow we want to interact with
  • The WorkflowFunctionID of the function we want to invoke from our API. In this case, we want to create new contracts so we’ll need to know the “constructor ID”

Back in postman — let's do a GET request on {yourAPIEndpoint}/api/v1/applications/{appID}/workflows

Copy the constructorID and also the workflowID of the workflow you want to call from our API

Paste these values into the function code above:

VSCode on mac

Next — in the method “GetAuthToken”, paste the corresponding values for Authority, ResourceID, ClientSecret and ClientID.

The code here just creates a new Authentication context for the DirectoryID we’ve provided and Asks for a NEW authentication token for the client ID and client Secret that we provide.

Our Azure Function is now acting as the Application Registration we created.

The Workbench SDK is quite easy to understand and well documented on the GitHub page. In a nutshell, you simply set the base Workbench API endpoint and authentication Token on the singleton GatewayAPI object.

And lastly, let's fill out whatever we need for the “AssetTransfer” contract in order to “create” a new instance. There are two parameters we need — a string for “description” and an integer for “price”

The parameters are read from the request body

That’s it!

We can now insert breakpoints in our function code and debug it locally. The function runtime will output the endpoint on localhost where you can hit your API from:

Debugging Local Functions with VSCode is Awesome!

To test, let's create a request in Postman with the body corresponding to the parameters we’re expecting on the function side — a “description” and a “price”:

Our function expects a body with a “description” and “price”

And Voila — We can create a new contract by invoking our API!

Invoking our local Function creates a new contract in Workbench!

At this point — you can publish your function to Azure Functions for auto-scaling and high availability. There are other security considerations that we should remember — We don’t want to hardcode most of the values in the Function code but rather use Environment Variables to keep them safe.


That’s It! I hope you enjoyed this Walk-through!

We now have the ability to interact with our Azure Blockchain Workbench instance via the API instead of using the messaging service and Logic Apps.