Blog series: Building a CLM–Power Automate custom connector: Considerations
If you have attempted an integration between two systems, you know that several questions emerge when building the integration. Which user will perform the integration: a normal user or a system user? What administrative burdens will each normal user carry, such as logging into each system? How will the integration handle exceptions, such as authentications that time out? Which authentication methods will the integration use to connect to DocuSign? How can the authentication credentials be securely stored? Best practice is to confront and answer these questions before designing an integration.
This article will equip you with the knowledge and questions necessary to design an integration that reliably meets business needs while imposing the least burden possible on those who use the integration. My Part 1 post set the foundation for creating a safe, simple, and versatile Power Automate custom connector for use with DocuSign CLM. This post will equip you to answer design questions for the connector. The next section details the two primary integration types, while the following section details the two primary authentication flows used by DocuSign.
Stop right now and consider an integration you plan to build. Who will be using the integration? Will it be used individually by normal users or will it operate silently in the background without user involvement?
Integrations fall broadly into two categories: per-user and system-wide.
Per-user integrations operate with the knowledge and cooperation of each normal user, i.e., human. Integrations such as browser plugins that connect to other software are per-user integrations. The user is aware of the integration, taking active steps to enable and configure the integration. Generally, if the user does not take action to configure the integration, then the integration will not exist for that user.
Per-user integrations have several advantages:
- Typically less complex
- More transparent to each user
- Allow users to opt in and out of integrations
At the same time, per-user integrations have several disadvantages:
- Require administrative effort from each user
- No assurance of uniformity across users
- More difficult to support
- Will fail when users do not maintain integration connections; for example, when they change their passwords
Consider a per-user integration when the primary purpose is to serve only the user and not the wider organization. For example, there might be an integration to send an SMS text message to a mobile telephone when a software build completes. Some users may prefer the integration while others may not. This integration does not serve the wider organization directly; instead serving each user. In this scenario, a per-user integration makes the most sense, giving each user fine-grained control over whether or not to activate the integration.
Avoid a per-user integration when the purpose is to serve the wider organization through a standardized workflow. For example, there might be an integration to update a spreadsheet whenever a change takes place within a CRM database, supporting an organizational policy. The workflow depends on the spreadsheet being updated to reflect CRM changes. A per-user integration would task all users with yet another administrative burden to make sure that they enable the integration and maintain the connection. Since this integration does not enhance the user’s experience, each user likely will be less inclined to make sure that the integration continues to function. Since the integration is less visible to the users, they may not be aware when it is failing.
Next, consider a system-wide integration.
System-wide integrations operate without the knowledge and cooperation of each normal user. Integrations such as data synchronization are typically system-wide. Each user may or may not be aware that the integration is taking place, and each user has no administrative burden to configure the integration. System-wide integrations make use of a system user, which is a user defined to each system of the integration, but the system user does not correlate to an actual human user.
System-wide integrations have several advantages:
- No administrative burden on each user
- Assurance of uniformity across users
- Easier to support
- Will continue to operate without effort from each user
At the same time, system-wide integrations have several disadvantages:
- Typically more complex
- Less transparent to each user, often opaque
- Users cannot opt in and out of integrations
- Requires more error checking and recovery
Consider a system-wide integration when the purpose is to serve the wider organization through a standardized workflow. For example, there might be an integration to archive completed CLM documents to a SharePoint folder. A system-wide integration could silently ensure that the latest version of each completed document is archived safely in the right place without each user needing to take any action.
Avoid a system-wide integration when the primary purpose is to serve the user and not the wider organization. For example, there might be an integration to notify a user if an upcoming meeting has attendees who have not responded. Some users may prefer the integration, while others may not. This integration does not serve the wider organization directly, but serves each user. In this scenario, a system-wide integration might create more problems than it solves.
Choosing the appropriate integration type drives the choice of authentication flow, covered in the next section.
DocuSign supports multiple authentication flows, but only two are relevant for our purposes: Authorization Code Grant and JWT Grant. Regardless of the authentication type chosen, the user, whether a normal user or a system user, must grant consent to the integration interacting with DocuSign, a topic outside the scope of this series. As you might have guessed, one authentication flow is more suited to a per user integration while the other is more suited to a system side integration.
Authorization Code Grant
The Authorization Code Grant flow is well defined as part of OAuth 2.0 and widely supported. This flow starts by the integration’s sending the user to a web page owned by the desired resource (such as a DocuSign API server) that authenticates the user: i.e., it confirms that the user is who they claim to be, then redirects the user’s web browser to a predefined redirect URI, along with an authorization code that the integration can use to obtain an access token to the resource the user has authorized. For DocuSign integrations, the access token is what ultimately enables API calls to DocuSign.
The Authorization Code Grant flow might seem convoluted, and it is. The reason is that this standardized flow is designed to be modular, separating the authentication process (confirming user identity) from the authorization process (allowing the user to access API resources). To make this happen, the user must leave the integration and go to a web browser where the user is sent to the authenticator, then the user is redirected back to the integration, which will attempt to gain access using the supplied authorization code.
To recap the Authorization Code Grant flow:
- Integration sends user to web page of authenticator.
- Authenticator verifies the user and redirects to a redirect URI of the integration, embedding an authorization code.
- Integration sends the embedded authorization code and stored integration secret key to DocuSign to obtain an access token.
- Integration makes API calls using the access token.
The Authorization Code Grant flow has several important properties to keep in mind:
- This flow is supported by Power Automate and is the easiest to implement.
- The standard access token lasts for 8 hours and can be refreshed in 8 hour intervals for up to 30 days total.
- The extended access token lasts for 30 days and can be refreshed indefinitely.
- The flow requires the user to be present with their web browser for authentication.
- It requires a public endpoint for the redirect URI.
- It requires managing the integration secret key.
- The integration should provide an alert on connect failure, since the user will need to be involved in re-authenticating.
- The user must grant consent.
You probably noticed that the Authorization Code Grant flow is an ideal fit for per-user integrations. For a good example of creating a Power Automate custom connector using Authorization Code Grant flow, make sure to read Mohamed Ali’s blog post, Get into the flow of sending DocuSign Envelopes with Microsoft Power Automate.
It’s worth noting that the authorization code and access token are themselves JSON web tokens (JWTs), defined below. The most robust way to connect to DocuSign for a system-wide integration is the JWT Grant flow, discussed next.
The JWT Grant flow (not to be confused with user consent grant) provides a robust and reliable facility for accessing DocuSign resources silently and in the background, without requiring user presence of any kind, except for the initial consent grant. Unlike the Authorization Code Grant flow, the JWT Grant flow is not a standard flow that is well defined. Instead, DocuSign reused components of OAuth 2.0 to make the JWT Grant flow possible. Before continuing, let’s define JWT.
According to RFC 7519, “JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties.” In short, JWT is a standardized format to represent data (claims), optionally with proof that the JWT is not forged. For the purposes of this blog series, think of a JWT as a tiny database of names and values combined with a signature to prevent forging. The JWTs used by DocuSign include the expiration date and time. As noted above, the authorization code returned from authentication is a JWT. You can view the values of any JWT, including the authorization code or even an access token, at https://jwt.io. JWTs are not private and not encrypted. Anyone is welcome to view the contents, but because of the forgery detection, you cannot successfully create your own JWT authorization code or access token and then submit to DocuSign for API access. JWTs provide a way to pass a package of values from one system to another with confidence that the package has not been forged, making them an ideal way for an integration to log into the DocuSign API.
The JWT Grant flow leverages JWTs as a package of data about the user logging into the DocuSign API. To generate a valid JWT, the integration must use an RSA key pair, uploaded to (or generated by) DocuSign in the Apps and Keys section of the Settings tab. The integration must securely store the private key, ensuring that it is never exposed, not even in diagnostic logs. The integration must then generate JSON output, perform URL-safe Base64 transformations, and use the private key to sign the JWT. The signed JWT is exchanged for an access token.
To recap the JWT Grant flow:
- Integration generates a valid JWT (This is the tricky part).
- Integration sends the JWT to DocuSign to obtain an access token.
- Integration makes API calls using the access token.
The JWT Grant flow has several important properties to keep in mind:
- This flow is more difficult to implement, primarily because of the need to:
- Encode the JWT with URL-safe Base64
- Store the RSA private key securely
- Use cryptographic software to sign the JWT
- The access token expires in one hour.
- There is no way to refresh the access token.
- But new access tokens can be generated at will with a valid JWT!
- The flow requires the ability to store an RSA private key securely.
- It requires encryption software to sign the JWT.
- The user must grant consent.
- The flow can operate without any user interaction at all once initial consent has been granted.
- This flow is not supported by Power Automate custom connectors!
You probably noticed that the JWT Grant flow is an ideal fit for system-wide integrations, but the last bullet point above creates a real problem for using JWT Grant flow with Power Automate custom connectors. For those with the technical chops and the time, it is possible to create custom endpoints in Azure Functions that provide JWT Grant connectivity, but that approach does not leverage the flexibility of Power Automate custom connectors, which is the whole point of this blog series. At first, it appears that the choices available are a per-user integration with Authorization Code Grant flow that requires the user to reauthenticate, or a system-wide integration with JWT Grant flow that is not supported by Power Automate custom connectors. The two options boil down to: require ongoing user involvement, or abandon Power Automate custom connectors. There is a third choice. This series will present a novel approach that enables a system-wide integration using Power Automate custom connectors without the need for ongoing user involvement.
This installment covered an overview of the two main types of integrations and the two primary authentication flows. You are now armed with the rationale for using each, their key features, and their pitfalls. In the next installment, you are going to build a robust and safe Power Automate custom connector that can be reused for system-wide integrations, yet the connection never expires.