{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition","Steps","Step"]},"type":"markdown"},"seo":{"title":"Webhook over mTLS for clients","description":"Welcome to the Upvest API documentation. Here you will find all the information you need to integrate with our API.","siteUrl":"https://docs.upvest.co/","image":"/assets/upvest-logo-card.ee25ccc59849324b0b73151a5c972c87639419556344db0b6dcf518151cb4c3c.925ff8b2.png","keywords":"documentation, api","lang":"en-US","meta":[{"name":"description","content":"Welcome to the Upvest API documentation. Here you will find all the information you need to integrate with our API."},{"name":"image","content":"/assets/upvest-logo-card.ee25ccc59849324b0b73151a5c972c87639419556344db0b6dcf518151cb4c3c.925ff8b2.png"},{"name":"twitter:card","content":"summary_large_image"},{"name":"twitter:title","content":"Welcome to the Upvest API Documentation"},{"name":"twitter:image","content":"/assets/upvest-logo-card.ee25ccc59849324b0b73151a5c972c87639419556344db0b6dcf518151cb4c3c.925ff8b2.png"},{"name":"twitter:description","content":"Welcome to the Upvest API documentation. Here you will find all the information you need to integrate with our API."},{"name":"og:url","content":"https://docs.upvest.co/"},{"name":"og:title","content":"Welcome to the Upvest API Documentation"},{"name":"og:description","content":"Welcome to the Upvest API documentation. Here you will find all the information you need to integrate with our API."},{"name":"og:image","content":"/assets/upvest-logo-card.ee25ccc59849324b0b73151a5c972c87639419556344db0b6dcf518151cb4c3c.925ff8b2.png"}],"llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"webhook-over-mtls-for-clients","__idx":0},"children":["Webhook over mTLS for clients"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"introduction","__idx":1},"children":["Introduction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This page explains how webhook delivery over mTLS works, why you should use it with HTTP signatures, and how to manage certificate setup and rotation for sandbox and live environments."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"mtls-overview","__idx":2},"children":["mTLS overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Mutual Transport Layer Security (mutual TLS, or mTLS) is a security protocol that provides ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["two-way authentication"]}," between Upvest and your webhook endpoint. Unlike standard HTTPS, mTLS requires both sides to present valid certificates during the TLS handshake."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upvest offers three approaches to implement mTLS. You can select the method that works best for your setup. We describe the process for each approach in the sections below."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#method-1-client-generates-the-certificates"},"children":["Clients generate certificates"]},": You create the required certificates and provide them to Upvest to implement."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#method-2-upvest-generates-certificatesigned-by-digicert"},"children":["Upvest generates certificate/signed by DigiCert"]},": Upvest creates the required certificates and uses our Certificate Authority (CA) provider, DigiCert, to provide them to the client."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#method-3-upvest-generates-certificatesigned-by-client"},"children":["Upvest generates certificate/signed by client"]},": Upvest creates the required certificates and provides them directly to the client."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"benefits-of-using-mtls","__idx":3},"children":["Benefits of using mTLS"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you enable mTLS for webhook delivery, you add:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Strong endpoint authentication"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Connection-level security"]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["mTLS is an additional security layer on top of HTTP signature verification."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use both mechanisms together for defence in depth: mTLS authenticates the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["connection"]},", while HTTP signatures authenticate the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["payload content"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":4},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before Upvest can deliver webhooks over mTLS, configure your webhook endpoint to:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Run HTTPS with TLS 1.2 or later"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Request a client certificate"]}," during the TLS handshake"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Validate the client certificate"]}," against your trust store"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Reject connections"]}," that do not present a valid certificate"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["mTLS is configured per client. After mTLS is enabled, all webhook deliveries for that client use mTLS."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"certificate-requirements","__idx":5},"children":["Certificate requirements"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To enable mTLS, provide Upvest with the following files in PEM format if you are generating your own certificates:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Private key"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Client certificate"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your certificate must meet these requirements:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key algorithm:"]}," RSA, 4096-bit"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Signature algorithm:"]}," SHA-256"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Send both files using your agreed secure transfer mechanism, for example password-protected encrypted bundles. Label each bundle clearly by environment. Upvest reviews and stores the files securely before enabling integration."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"initial-key-configuration","__idx":6},"children":["Initial key configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Choose the mTLS method that matches your setup, then follow the steps below."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"method-1-client-generates-the-certificates","__idx":7},"children":["Method 1: Client generates the certificates"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Follow the steps below to generate and provide the required certificates to Upvest."]},{"$$mdtype":"Tag","name":"Steps","attributes":{},"children":[{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Generate certificate bundle"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Generate a certificate bundle that contains both the private key and client certificate in PEM format."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Prepare environment-specific bundles"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Provide separate bundles for sandbox and live, and label each bundle clearly."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Submit bundles securely"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can send the bundles directly to the Upvest security team or work with your Upvest account manager to deliver the files."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Upvest review and confirmation"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upvest reviews and securely stores the bundles, then confirms when integration testing can begin."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Integration and validation"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can start integration testing by calling our ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/test"]}," webhook endpoint and confirm successful webhook integration testing."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"method-2-upvest-generates-certificatesigned-by-digicert","__idx":8},"children":["Method 2: Upvest generates certificate/signed by DigiCert"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Follow the steps below to receive and process the required certificates via Upvest's Certificate Authority (CA) provider, DigiCert."]},{"$$mdtype":"Tag","name":"Steps","attributes":{},"children":[{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Upvest generates a certificate signing request (CSR)"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upvest generates a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["certificate signing request"]}," (CSR) that contains the public key and Upvest's identifying details (our organisation name, our locality/country, and our webhook's website address)."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Upvest provides the CSR to DigiCert"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upvest provides the CSR to DigiCert."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Upvest review and confirmation"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upvest reviews and securely stores the file from DigiCerts. We then send the certificates to the client and confirm when integration testing can begin."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Integration and validation"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can start integration testing by calling our ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/test"]}," webhook endpoint and confirm successful webhook integration testing."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"method-3-upvest-generates-certificatesigned-by-client","__idx":9},"children":["Method 3: Upvest generates certificate/signed by client"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Follow the steps below to receive and process the required certificates directly from Upvest."]},{"$$mdtype":"Tag","name":"Steps","attributes":{},"children":[{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Upvest generates the certificate bundle"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upvest generates a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Certificate Signing Request"]}," (CSR) file that contains the public key and Upvest's identifying details (our organization name, our locality/country and our webhook's website address)."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Upvest provides the CSR file to the client"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upvest provides the CSR file to the client for processing."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"You sign the CSR and deliver the certificate"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Process the CSR with your private certificate authority (CA), then send the signed certificate to Upvest."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Upvest review and confirmation"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upvest reviews and securely stores certificates, then confirms when integration testing can begin."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Integration and validation"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can start integration testing by calling our ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/test"]}," webhook endpoint and confirm successful webhook integration testing."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"planned-certificate-rotation","__idx":10},"children":["Planned certificate rotation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When generating the certificates, Upvest configures then with a one-year validity period. For clients that generate their own certificates, Upvest also recommends setting up certificates with at least a one-year validity period."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Start planned rotation ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["three months before expiry"]}," to reduce the risk of delivery disruption. For planned rotation, follow the same process as initial key configuration:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Generate a new certificate bundle"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Provide environment-specific bundles (sandbox and live)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Submit bundles securely for review"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Complete integration validation before final cutover"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"emergency-certificate-rotation","__idx":11},"children":["Emergency certificate rotation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you suspect that a private key or certificate has been exposed or compromised, perform an emergency rotation immediately."]},{"$$mdtype":"Tag","name":"Steps","attributes":{},"children":[{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Contain and assess impact"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Treat the key as compromised. Identify affected environments and endpoints, and begin incident handling according to your internal security process."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Generate replacement certificates"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Generate a new private key and certificate bundle for each affected environment."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Notify Upvest immediately"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Contact Upvest through your established secure support channel and flag the request as an emergency certificate rotation."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Submit new bundles securely"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Send the replacement bundles using the agreed secure transfer mechanism, with clear environment labels."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Validate and cut over"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Coordinate with Upvest to validate webhook delivery over mTLS and complete cutover to the new certificates."]}]},{"$$mdtype":"Tag","name":"Step","attributes":{"title":"Revoke and retire old material"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Revoke and retire compromised certificates and keys according to your incident response policies."]}]}]}]},"headings":[{"value":"Webhook over mTLS for clients","id":"webhook-over-mtls-for-clients","depth":1},{"value":"Introduction","id":"introduction","depth":2},{"value":"mTLS overview","id":"mtls-overview","depth":2},{"value":"Benefits of using mTLS","id":"benefits-of-using-mtls","depth":2},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"Certificate requirements","id":"certificate-requirements","depth":2},{"value":"Initial key configuration","id":"initial-key-configuration","depth":2},{"value":"Method 1: Client generates the certificates","id":"method-1-client-generates-the-certificates","depth":3},{"value":"Method 2: Upvest generates certificate/signed by DigiCert","id":"method-2-upvest-generates-certificatesigned-by-digicert","depth":3},{"value":"Method 3: Upvest generates certificate/signed by client","id":"method-3-upvest-generates-certificatesigned-by-client","depth":3},{"value":"Planned certificate rotation","id":"planned-certificate-rotation","depth":2},{"value":"Emergency certificate rotation","id":"emergency-certificate-rotation","depth":2}],"frontmatter":{"seo":{"title":"Webhook over mTLS for clients"}},"lastModified":"2026-06-08T08:37:04.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/products/byol/getting_started/implementing_webhooks/implementing_mtls","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}