Accessing other users signatures via REST API - docusignapi

I'm trying to make an app that would make CRUD operations on Users and their Signatures.
I'm able to make an Get request on admin user but on the another user I'll get error
"errorCode": "INVALID_USERID",
"message": "Invalid UserId. UserId specified in request uri does not match authenticated user."
I'm using Authorization Code Grant for getting Access token and API calls instead of SDK.

Your application can impersonate another user if you use the JWT grant.
But, as you've discovered, that user must first grant consent to be impersonated by your application.
To grant consent individually, you must be able to login as the user. (Eg, go through the email verification process used for new user accounts, create a password, etc.)
Consent can also be granted at the organization level if you have Organization Administration turned on and if you've "captured" a DNS domain. SSO is not needed.
When you impersonate someone you can't sign an envelope for them. -- You can't programmatically sign an envelope for yourself or anyone. Signing is only done by real humans.
Exception: the DocuSign Signature Appliance can programmatically digitally sign documents if it is equipped with the signer's public/private key pair. A use case for this feature is digitally signing (many) invoices that are being automatically sent.

Related

Docusign integration App not allowing to send cross account documents for eSign. INVALID_USER error

We have done one CRM integration where we as an CRM have our own docusign pro account.
We completed the GoLive process successfully and have all required data like Integration key, Account Id, Client Id and Secret Key for App.
Now this CRM integration will be used as an mediator for our clients who will have their own purchased docusign accounts.
So till now we have 2 accounts,
CRM Integration docusign account with GoLive status.
Client account to send their own documents for eSign through our CRM integration.
What we have achieved till now?
We completed the consent flow where we redirect our clients to docusign consent page where they provide consent to our app by login into their docusign account. In this flow we use CRM integration account id in URL which takes our client for consent page. On confirm the client will be redirected back to CRM with auth code attached in redirect URL.
We use this auth code to get access token for this client. We use CRMs account id, Integration App secret key and clients auth code to get the access token. We are successful in this too. We get clients access token. No Issues.
Now when our client is trying to send a document for eSign using the access token received in step 2 above, the docusign throws an error saying INVALID_USER.
I have referred to this post Simillar Issue it kind of approves of what we are trying to achieve but it is failing with error.
Let me try to explain and make sure it's clear.
The IK (Integration Key) is global for the entire environment. By environment I mean either the developer environment, or the production environment. When you went live and completed the process using a production environment - you made your IK available for any account and any user in the production environment.
Now, when you get an access token to make API calls, this token is for a specific userId. The userId can be a member of one ore more accounts as showed in this diagram:
The userId is provided by the user logging in when given the option to consent. So when you doing your consent flow, there's a web browser and user that logs in, that is the userId that consent.
Separately, when you request a token using JWT grant, you provide a userId, that userId is a GUID for a unique user in the system.
This GUID must be for the same exact production user that gave consent. That's first thing to confirm.
Now, if you already have an access token to make API calls, when you make a specific API call, you need to provide an accountID. That's another GUID representing an account, not a user. The userId that was provided to the JWT Grant flow must represent a user that has a membership (it is a member of) in the account for which you provided a GUID (a user can be a member of more than one account). That is the second thing to check.
Lastly, there's a baseURI that is used to make API calls and it can be different for different accounts. You need to also confirm you are using the correct one.

DocuSign authentication service for applications

I'm working on an integration with the DocuSign API. I want the users to log in to my app and then initiate the signing process from there. The users must not have a DocuSign account, they should be able to sign without log in to DocuSign. As I understand the JWT Grant flow is the best choice for this scenario by impersonating a system user and create envelopes and recipient view requests for the users who will sign. Please, correct me if I'm doing this wrong.
Many companies who offer electronic signature services also offer authentication services. For example OTP via email, SMS or some other eID. I would like that if the user could authenticate with DocuSign first before accessing my application. I haven't find a service like that at DocuSign. Is there a way to authenticate users without DocuSign accounts for my application with their service?
You first write:
The users must not have a DocuSign account
You later write:
I would like that if the user could authenticate with DocuSign first
before accessing my application
These two statement conflict. You can only authenticate if you have an account.
However, if what you mean is just get an SMS text there are two features you can use:
Send with SMS - sending the SMS as the means of obtaining a signature from user. User doesn't have to have an account with DocuSign.
SMS authentication - envelope is sent via email, SMS is used as a second factor auth. User doesn't have to have an account with DocuSign.
JWT or Auth Code Grant can either be used for the one user/account that does have the ability to send envelopes from DocuSign. Either one would work.

How should we go about allowing individual users of our web app to connect to their own DocuSign account?

For context, we are currently developing a DocuSign integration on our DMS web app product. So far what we have done is that the web app's admin (we assume this would be someone like our customer's IT) can set up the integration by entering API Account ID, Integration Key, Secret Key, Access Token & Refresh Token. All these information was taken/generated using a DocuSign admin account. With this, we see that any user using the DMS can send out signing requests (via API) without logging in to their own DocuSign account.
However, we realised this means that all signing requests will be sent using the common DocuSign admin account, i.e. the envelopes originate from the admin account and all signed documents also stored in the DocuSign admin account. This is not what we want as the DocuSign admin can see confidential signed documents.
I'm quite confused and would like to seek advise on how should we go about this? Ideally, it is that User A of the DMS can associate his DocuSign account with his DMS account. So that when User A sends out the signing request from our DMS, the signer receives the email from DocuSign showing it is from that user instead of the common admin account.
Also, it looks like the go-live process would have to take place for each customer that is using our DMS? Does it mean like each customer need to have their DocuSign developer account so that the integration key can get promoted to production environment? Or am I in the wrong direction & should look at Partner Integration as ISV?
If your DMS system is a SAAS system, then you can have 1 integration key (client id) for your integration with DocuSign. In other words, your individual customers would NOT have their own integration keys, secrets, etc.
One integration key is the best, if your application's architecture can support it. To do so, you'll want to have one or just a few Redirect URIs to enable your users (who also have DocuSign accounts) to authenticate with DocuSign.
Your app then stores the resulting access token, refresh token, and expiration date for each of your users who have authenticated with DocuSign.
This way, as you say, when your users send out an envelope for signing, it will belong to their own DocuSign account, and will show them as the sender.
When your customer wants to send via DocuSign, your app checks the expiration date for the person's access token. If the access token has expired, then use the refresh token to get a new access token and a new refresh token.
The refresh token is stored in your app's non-volatile storage (encrypted is best) so you can use it days or weeks later for the user. That way they don't have to re-authenticate with DocuSign. For this case, use scopes signature%20extended
For the account_id info, use the user's default account and enable them to switch to another account if they wish.
More information:
Getting started for ISVs
API integration guidelines

Who's credentials are used for the Authorisation Code Grant?

I implemented Authorisation Code Grant like the example code provided using passport and it is working fine.
One thing that is confusing me is that when obtaining a new token, passport required authentication.
Are these supposed to be the credentials of our admin account? or, once we go live, is it the credentials of our user who is trying to sign a document (using embedded signing).
Thanks!
When you say
our user who is trying to sign a document (using embedded signing)
note that signers do not need a DocuSign account. They can have one, but they don't need one.
If you want to use embedded signing for a signer who does not have a DocuSign account, use a system account (and JWT Grant) to obtain the Signing Ceremony URL. (A system account can also be used to create the envelope, if necessary.)
Added
A "system account" is a user account in your DocuSign account that represents a generic, system, sender. For example, create a user account "Sales department." Then use JWT Grant (on your backend web server) to impersonate the Sales department user. The result is an access token that your application can use to create envelopes and then have them signed by your website visitors.
The "Sales department" user will be created and controlled by your system administrator. But there is no need for the system administrator to login every morning -- once the system administrator gives consent for the application to impersonate the Sales department user, your application can create new access tokens as needed that impersonate the Sales Department user.
The latter. When using Auth Code Grant, every user of your application will have to log into DocuSign and their credentials will be used.
Read more over here - https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-code-grant

DocuSign - OAuth Authorization Code Grant - Multiple Users - Error while fetching Access and Refresh Token

We are trying to integrate DocuSign with our product.
Our Scenario: Our organization has a (partner) account. We created an Integrator Key (ClientID) and Secret. We want our clients to use their own accounts (which are not child accounts (Admin - user relationship) to our partner account) for the creation of envelopes and generate signing URLs along with our integrator key and secret.
Steps followed:
Created an account (Partner Account).
Created Integrator Key and Secret.
Our scenario is considered as User Application and using Authorization Code Grant Mechanism to get the auth code.
Clients are redirected to DocuSign portal for getting authenticated. (using authorization code grant mechanism by passing our integrator key as a parameter)
Client grant consent for our application to use their credentials for the creation of envelopes.
Receive the auth code.
Using clients authcode and Partner accounts Integrator Key & Secret, trying to fetch the refresh and access token. But DocuSign API (OAuth/token) is responding back with "Bad Request" (400) as response.
In place of the client account, if we are using same partner account credentials, then API (OAuth/token) is responding back with correct refresh token and access token.
Question: Can an integrator key and secret of one account be used along with the auth code of another account (both accounts doesn't have any relationship(Admin-User)) for fetching the Access token & Refresh Token.
API's Used:
Get Auth Code - https://account-d.docusign.com/oauth/auth (Partner Account (Integrator Key & Secret) & Client user credentials in DocuSign Portal)
Get Access / Refresh Token - https://account-d.docusign.com/oauth/token (Auth Code from previous response & base64(Integrator Key:Secret))
Reason: we don't want to store user credentials or ask users to log in every time when they want to use their DocuSign account in our application. So we want to get consent from a user and store their refresh token with us. Use their refresh token and our integrator key from next time for calling DocuSign API's.
Update
(I work at DocuSign.)
Via additional information supplied to DocuSign, we were able to find our internal logs for the OP's OAuth transaction that failed. We could see from the internal log that, indeed, the problem was that the Authorization Code had expired.
During an OAuth flow, as soon as an application receives an authorization code, it should immediately turn around and use it to get the Access and Refresh tokens, and related information. We will be updating our documentation to state this issue clearly.
Original answer
Everything you're doing sounds exactly right. Especially since the user is receiving the permission screen the first time after logging in to DocuSign via your application.
To answer your question directly: yes, a client id (Integration Key) can be used by an app for any DocuSign user on any DocuSign account.
One idea: is your application requesting the tokens immediately after receiving the authorization code? The authorization code itself times out after a couple of minutes.
You're saying that if User A logs in it works (User A belongs to the account that manages the Client ID), but if User B logs in it doesn't work? I haven't seen that issue before. I'd create a new demo developer sandbox with User C and have them try to login.
Is all of this on demo or production?

Resources