How do I secure my DocuSign Connect https listener so that only requests from DocuSign are accepted?
I have read the Connect service guide and am uncleared on whether the following setting can be used for this purpose:
Sign Message with X509 Certificate
Does this setting apply to both the SOAP and HTTPS listener interfaces?
Can this setting be used to secure my listener so that only DocuSign requests will be accepted?
How do I set up my service to validate the signed message as valid?
Does this setting apply to both the SOAP and HTTPS listener interfaces?
Yes, it does indeed apply to both listener interfaces.
Can this setting be used to secure my listener so that only DocuSign requests will be accepted?
Yes, that's what using the X509 certificates accomplishes.
How do I set up my service to validate the signed message as valid?
It is dependent on the encryption technology you decide to use. If you have something chosen already you should be able to go through its documentation to find out how to verify the messages. Often times it will be binary security token in the header.
More Info
Additionally, please note that DocuSign uses the standard WSE3 BinarySecurityToken
in the SoapHeader to pass the certificate.
From Page #9 of the DocuSign Connect Service Guide
Related
Context
I'm using mTLS to secure Docusign Webhooks (Docusign Connect Service). I'm able to make a successful mTLS connection to get certificate fingerprint, according to the documentation.
The next suggested step is to do access control by validating the certificate fingerprint and possibly the Distinguished Name (DN) but I'm confused what should the correct way to do so.
Questions
How do we know which client certificate is going to be sent by DocuSign to our listener in live environment (theoretically can be one of these and which logic is used to determine which one is sent? Should we validate which certification is sent by the DN (e.g. connect.docusign.net)?
What information should we validate from the certificate message? The fingerprint, DN, both or more?
With the above, how can we know all possible fingerprints to validate from server side, assuming different webhooks messages can send different client certificates? Should we compute the fingerprint of all public connect certificates to get a full list?
What is the best way to handle expirations of client certificates?
Re:
Q. How do we know which client certificate is going to be sent by DocuSign to our listener in live environment (theoretically can be one of these and which logic is used to determine which one is sent? Should we validate which certification is sent by the DN (e.g. connect.docusign.net)?
A. Best is to validate based on the certificate's fingerprint matching a fingerprint of one of the expected certificates. DocuSign uses different certificates depending on the platform. But there's a limited set of certs used, so it should not be a big deal to check to see if the offered cert matches one of the expected certs.
Q. What information should we validate from the certificate message? The fingerprint, DN, both or more?
A. I'd recommend the fingerprint since it is more specific than the DN. With the DN, you're trusting the CAs to not issue a cert with a DocuSign DN to a bad guy. It should never happen but it has in the past (not to DocuSign though). See Rogue certificates
Q. With the above, how can we know all possible fingerprints to validate from server side, assuming different webhooks messages can send different client certificates? Should we compute the fingerprint of all public connect certificates to get a full list?
A. DocuSign uses a limited set of five certificates for webhook notifications, see the list on the trust center in the Connect Certificates section. Checking the incoming certificate against five or ten (see below) fingerprints is not a big deal.
Q. What is the best way to handle expirations of client certificates?
A. When the new certificates are announced, compute their fingerprints and add them to your system.
Then test by switching your DocuSign account to use the new certificates. Once the test succeeds, you can delete the fingerprints of the old certs.
I am using RabbitMQ with SSL/TLS in order to allow confidentiality, integrity and authentication. The message sent is encrypted using sender and broker certificates between sender and broker and then encrypted using broker and receiver certificates between broker and receiver.
My configuration file looks like this:
{ssl, [{versions, ['tlsv1.2']}]},
{rabbit, [
{ssl_listeners, [5671]},
{ssl_options, [{cacertfile, "...ca_certificate.pem"},
{certfile, "...certificate_signed.pem"},
{keyfile, "...private_key.pem"},
{password, "pass"},
{verify, verify_peer},
{fail_if_no_peer_cert, true},
{versions, ['tlsv1.2']}]}
]}
However this is not enough because I need that a receiver/consumer to be able to assure the sender/publisher identification, like described in here. At the receiver I only can access certificate information from the broker certificate.
A solution to that would be to use user-id message property, like i found in the documentation.
This property, sent in every message, will make sure that a message will only be published successfully if the user-id property is equal to the username used for that user to login in the RabbitMQ broker. Since I am already using certificates for SSL I will probably use them also to serve as user authentication with the broker as described here
My problem:
I am using RabbitMQ for communication between agents in a simulation platform and agents are created dynamically, so I would need for dynamic user creation at RabbitMQ which seems not to be possible.
Does someone know if I can do dynamic user creation somehow? Or suggest another approach to my authentication problem?
Thanks
The user-id property is not a security feature. It just sets information in the message header so that you can know who produced the message.
If you want authentication and autorization using certificates, you can follow the directives in the article you linked (https://weblogs.asp.net/jeffreyabecker/Using-SSL-client-certificates-for-authentication-with-RabbitMQ), especially in the section "Configuring Client authentication via certificates".
In short, you need to install the rabbitmq-auth-mecanism-ssl plugin (see here https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl/blob/master/README.md) and configure it following the documentation. You also need to create a passwordless internal user in RabbitMQ that has the same CN (common name) as your certificate to be able to give it authorizations.
If you want everything to be automated (as it should be), each time you want to create a new agent, you have to :
Generate a client key/certificate pair using openssl (see : https://superuser.com/questions/226192/avoid-password-prompt-for-keys-and-prompts-for-dn-information). Your key needs to be trusted by the same certificate authority that RabbitMQ trusts (in your SSL setup).
Create a user in RabbitMQ using rabbitmqctl (https://www.rabbitmq.com/management.html)
In my view, this is a very secure setup if you protect the generated keys so that only the agents have access to them.
On this page: https://developers.docusign.com/esign-rest-api/code-examples/webhook-status, the last section is called: There’s more. And there you can read that there are 3 ways to check that DocuSign is making the web hook request:
you can check the SSL/TSL certificate of the webhook caller (DocuSign).
set DocuSign to digitally sign the data
DocuSign publishes the IP address ranges
If we examine all these options we have:
This is false, you can't check the SSL certificate of who is making the request to you. SSL certs are designed to be used by clients connecting to servers to check that there is no man in the middle attack. And only the client can verify the cert of a server, not the other way around.
I can't find on the page any mention how to set the signature, and most importantly, how to check it.
The link provided to the Public IPs: https://trust.docusign.com/en-us/trust-certifications/ip-ranges/, does not work.
My questions are:
Where can I find some documentation about the signature process?
Where is the page with the public IPs?
The best way to do that is to create an HMAC key and use that to confirm that the calls are authentic.
Here is a full article on how to do that - https://developers.docusign.com/esign-rest-api/guides/connect-hmac
Thank you for reporting the out of date documentation. I've filed an internal bug report, DEVDOCS-1565, to have it updated.
As Inbar says in his answer, these days, the best solution is HMAC. You can also combine it with Basic Authentication if you're using DocuSign webhooks at the account level.
HMAC gives you the guarantees that the message did originate from DocuSign and that the message was not altered in transmission.
Don't set up a server on the Internet
The old way of receiving webhook messages was to set up a server that is accessible on the public internet. Due to the costs and Information Security issues creating and maintaining a service on the Internet, these days I suggest that you skip it.
Instead, use a cloud PAAS (AWS, Azure, Google Cloud, etc etc) to receive and queue the messages. Then, from behind your firewall, you can dequeue and process them. (With no changes to your firewall.)
See the Connect- series of code examples.
Mutual TLS for checking the client's certificate
Note that you can check the certificate of a client. This feature of the TLS (ne SSL) protocol is called Mutual TLS and is supported by DocuSign webhooks.
But HMAC is better since it also guarantees message integrity.
Is it possible to have a custom B2C policy call a REST API that uses a self-signed cert?
Currently, using the Web.TPEngine.Providers.RestfulProviderRestfulProvider to call a HTTPS REST API that uses a self-signed cert, I get the following errors in the Application Insight logs...
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
The remote certificate is invalid according to the validation procedure.
Is there a metadata item I can use to have it ignore TLS verification?
If not, how to I add my cert to a B2C trust store?
When I receive a Docusign custom connect POST message at my httpS server. How can I verify that it has in fact come from Docusign?
Does docusign have a list of IP addresses that they will send the post message from?
Is there some other recommended method to verify that the POST message was sent by DocuSign?
You have a few options to validate that the message is coming from Docusign depending on your requirements.
See this great Docusign Blog post about securing connect webhook listener
Use a Pre-shared Secret
Use Mutual TLS to authenticate the client(Docusign)
Check the SSL/TLS certificate of the webhook caller (DocuSign).
Set DocuSign to digitally sign the data in the notification XML
(Not recommended)Whitelist Docusign's IP addresses on your server that is listening to the connect messages.
More info here(Scroll to the bottom of the page. There's more section)