DocuSign JWT/Signing Security - docusignapi

I'm writing a Python/Django integration with DocuSign, where users will be sent from another application to DocuSign to sign a document, and then be sent back to the initial application. These users do not have DocuSign accounts.
I am currently using "request_jwt_user_token" alongside our service account generate the an envelope, attach a document, and create a recipient view. At the end this returns us a url like:
https://demo.docusign.net/Signing/MTRedeem/v1/[random_string]?slt=[random_long_string]
I'm pretty sure the first random string is an identifier and the latter is an access token?
What I'm trying to understand is how secure this info is to pass on to arbitrary users. I'm keeping the jwt expiration low and setting the jwt scope to ["signature", "impersonation"]. But can the slt token be used to access other envelopes or do other signature api calls? I assume it can't be used for anything outside of signing due to the scope.

The URL you posted here has nothing to do with JWT. It's an embedded signing URL that you can redirect your user in order to complete signing. They can then be redirected back to your app after they're done.
This URL expires in 5 minutes (or 2 minutes) and so it's very secure. It is also a URL that can be used only by one user (the one you set as the user signing the envelope and generated with the clientUserId)
The access token can be used to access other envelopes etc, but that access token is NOT in this URL and should never be shared etc.

Related

Docusign - generate Authorization code for getting Auth token

I am trying to create a embeded sign in url from backend webservice and open that url in the mobile application for signing.
For that in backend first of all i need to get Auth token.
To fetch auth token i need to get Auth code. For this i need to build a url with redirect url and when i open this url it will be redirected to given redirect url with auth code.
https://account-d.docusign.com/oauth/auth?
response_type=code
&scope=YOUR_REQUESTED_SCOPES
&client_id=YOUR_INTEGRATION_KEY
&state=YOUR_CUSTOM_STATE
&redirect_uri=YOUR_REDIRECT_URI
&login_hint=YOUR_LOGIN_HINT
But this process is manual and auth code from this is valid for 2 minutes only. So each time i have to build url and get auth code.
Is there any automated programmatical way to fetch auth code or generate auth code which will not expire.
If the signer is also the DocuSign account user, then Authorization Code Grant is the right way to go.
It sounds like you're not implementing authorization code grant correctly:
You redirect the user's browser to the DocuSign OAuth service (account.docusign.com for production, account-d.docusign.com for development).
After the user finishes authenticating with DocuSign, the authentication service will redirect the user's browser to your redirect_uri, which you supplied earlier.
Your application, initiated via the redirect_uri then exchanges the authorization code for an access token. There's nothing "manual" about this process other than manually entering the email/password for authentication.
JWT Grant when the DocuSign account user is not present
It could also be that the signer does not have an account on the DocuSign system. (This is the more common situation.) Signers do not need DocuSign accounts, only senders do.
In this case, your application should use the JWT Grant flow to impersonate a DocuSign account user--either a real person or a "system account" such as "Payroll Department."
The JWT Grant flow is used to obtain an access token. Then your server-side software would use the API to send the envelope, and then to obtain an embedded signing ceremony URL. Next, redirect the user's browser (on the phone) to the signing ceremony URL. After the signer signs, the DocuSign signing ceremony software will redirect the user's browser back to your application.

Since DocuSign legacy header auth is no longer supported, and OAuth authentication with the end user does not make sense for us, what are our options?

We currently use the legacy header method of authenticating with the DocuSign REST API for embedded signing ceremonies, and are looking to migrate our method of authentication to one that is fully supported by DocuSign. The signer, however, should not need to authenticate with DocuSign to sign this document. It is not a legally binding contract, but a document in which we collect information in order to perform a background check of the signer. The signature is simply for attesting that the information they have provided is accurate, and a paper or eSignature is required for this in the state of Illinois. What are our options?
EDIT: Based on similar questions I've seen here and in other forums, it seems that the documentation for this could be better. The part I was hung up on was obtaining consent for the JWT Grant authentication process. The impression is that the end user (either the signer or the sender), via the client application or service, would need to grant their consent via authenticating with DocuSign each time something needed to be signed or sent for signature. If you are using an integration such as ours, attempting to keep DocuSign as invisible as possible, this would not be an option. This is not the case. The URL constructed in Step 1 of this process is actually meant to be constructed manually, by the developer, as part of the development process, and navigated to in a browser, where the developer will log in with the DocuSign account that is meant to be used for the integration.
You can use JSON Web Tokens Authentication (JWT) and with JWT you only need a single system user that would be use to make API calls.
End-users won't need to log-into your application.
On other notes, since you wrote "The signature is simply for attesting that the information they have provided is accurate," I would suggest you look into using DocuSign Click. A clickwrap is exactly what you need for this and you won't even need to make API calls from the server once you set it up.

DocuSign Recipient sign url expire

I need to add DocuSign to my chat app (iOS, Android, Windows) in order to ask to sign documents to all the chat group members.
I want to implement DocuSign signing flow without Server implementation: only Sender and Recipients client side implementation (is it possible?).
Flow that I imagined:
An authenticated Sender create the envelope with Envelopes: create REST call.
Other members must sign the document (no DocuSign account needed)...
...so I need to generate a "recipient url" for every member using the REST call EnvelopeViews: createRecipient (who call this endpoint?)
I tested this flow with Postman and I've some questions:
EnvelopeViews: createRecipient require X-DocuSign-Authentication header, so this request must be called from Sender side, is it?
EnvelopeViews: createRecipient return an url that can be used once, why? The second time I use this url I get 404 as response.
So what I notice is the Recipient can't use the url (provided by the Sender) twice but he can't generate a new url every time because it isn't authenticated (no X-DocuSign-Authentication).
How can I implement this flow properly?
Lots of good questions:
EnvelopeViews: createRecipient require X-DocuSign-Authentication header, so this request must be called from Sender side, is it?
Do not use the X-DocuSign-Authentication header. That's "legacy authentication" and DocuSign does not support it for new REST eSignature apps. Instead, use OAuth. Probably the OAuth JWT grant flow since that flow enables your application to impersonate a DocuSign user (such as the sender), when the user is not present.
You can call EnvelopeViews: createRecipient from your server or from your browser app. If you call from your browser then you'll need to implement a private CORS gateway.
Either way, when the signer is ready to sign, you obtain the signing ceremony URL from the EnvelopeViews: createRecipient API call, then redirect the signer's browser to the URL.
EnvelopeViews: createRecipient return an url that can be used once, why?
For security reasons. That's part of our information security architecture. And not only is the signing ceremony URL only usable once, it is also time limited. It should be used within a minute or two from when you receive it from DocuSign. It will expire 5 minutes after it was created.
The second time I use this url I get 404 as response.
Yes, that's as designed. You get the URL, then you immediately redirect the signer to the URL. Then they sign. Then they're redirected back to your application.
If you want to provide a URL to a signer that the signer can use later on, you can implement that flow yourself. I've described how in other answers.
So what I notice is the Recipient can't use the url (provided by the Sender) twice but he can't generate a new url every time because it isn't authenticated (no X-DocuSign-Authentication).
How can I implement this flow properly?
You're almost there. Implement the JWT grant flow in your application. That way your app can impersonate the sender even when they're not around. When the signer wants to sign, your app gets the signing ceremony URL from DocuSign, and then redirects to enable signing.
An alternative which also works fine is for the sender to sign in to DocuSign by using the standard OAuth Authorization Code grant. This provides your app with an access token and a refresh token.
Your app enables the sender to send the enveloper by using the access token.
Later, when the signer wants to sign, your app uses the refresh token that it stored to generate a new access token. Use the access token with the EnvelopeViews: createRecipient API method to obtain the signing ceremony URL.
X-DocuSign-Authentication header is legacy authentication, please don't use this as it's not as secure as modern OAauth.
Again, security. Every time you want someone to sign your code should generate the URL. Also, note you cannot generate two URLs. Only one is valid at a time. You need your app to have some logic to ensure that only one user is signing and only at that point in time the URL is generated.

DocuSign API integrator & private key, with multiple users

I am using the DocuSign API to authenticate, create, and send envelopes from within my application. This applications needs to allow multiple users to use their own DocuSign sign account with the application. For each DocuSign User that will use with this application, do I need to have a separate integrator key and private key? Or is there a better way? Requiring each user to setup an API key doesn't scale very well as a business workflow. I'm hoping there is a better way, so that I can setup an integrator key and private key once.
No you do not need to create a separate integrator key for each user! You only need one integrator key (also called clientId) per DocuSign integration. The key helps identify which integration the requests are coming from, though these requests can indeed be coming from different accounts.
Your integration simply needs to initiate the OAuth handshake based on which method you are using (Auth Code Grant, Implicit Grant, JWT Token) and while "under the hood" the request will contain your integrator key the end-user does not see that (or even know about it).
See the Authentication Overview for more info.
Once you make the initial auth request the user will be redirected to a browser where they will login through the standard DocuSign login page using their username and pwd. Upon successful login they will be redirected to the redirectUri that was supplied in the API request and the resulting URL will have a query parameter attached to it which has their auth code.
Again, read the overview above based on which method you are using, but as stated you only need ONE integrator key per integration which is a private ID that you should never share with the end-user.

how to secure azure mobile service / html - javascript

When I call an oauth provider like gmail and I get the token back, how can I make sure that all future calls I make are from that same client that did the authentication? that is, is there some kind of security token I should pass pack? Do I pass that token back everytime?
For example, if I have a simple data table used for a guest book with first,last,birthdate,id. How can I make sure that the user who "owns" that record is the only one who can update it. Also, how can I make sure that the only person who can see their own birthday is the person who auth'd in.
sorry for the confusing question, I'm having trouble understanding how azure mobile services (form an html client) is going to be secure in any way.
I recently tried to figure this out as well, and here's how I understand it (with maybe a little too much detail), using the canonical ToDoList application with server authentication enabled for Google:
When you outsource authentication to Google in this case, you're doing a standard OAuth 2.0 authorization code grant flow. You register your app with Google, get a client ID and secret, which you then register with AMS for your app. Fast forwarding to when you click "log in" on your HTML ToDoList app: AMS requests an authorization code on your app's behalf by providing info about it (client ID and secret), which ultimately results in a account chooser/login screen for Google. After you select the account and log in successfully, Google redirects to your AMS app's URL with the authorization code appended as a query string parameter. AMS then redeems this authorization code for an access token from Google on your application's behalf, creates a new user object (shown below), and returns this to your app:
"userId":"Google:11223344556677889900"
"authenticationToken":"eyJhbGciOiJb ... GjNzw"
These properties are returned after the Login function is called, wrapped in a User object. The authenticationToken can be used to make authenticated calls to AMS by appending it in the X-ZUMO-AUTH header of the request, at least until it expires.
In terms of security, all of the above happens under HTTPS, the token applies only to the currently signed-in user, and the token expires at a predetermined time (I don't know how long).
Addressing your theoretical example, if your table's permissions has been configured to only allow authenticated users, you can further lock things down by writing logic to store and check the userId property when displaying a birthday. See the reference docs for the User object for more info.

Resources