How to set up mTLS

Lean Data API illustration

Introduction

Calls from your backend to Lean are required to be made over Mutual Transport Layer Security (mTLS). mTLS is a certificate based authentication protocol that replaces oAuth public / private keys. Instead of sending a private key, you send your certificate with your calls to the Lean servers to authenticate.

If you'd like to learn more about what mTLS does and how it works you can learn more here.


Getting your certificates

When you create application at dev.leantech.me you will be able to download two files from the authentication section of the developer portal. By clicking 'generate new certificate' a zip folder containing my_app_private_key.pem file and a my_app_cert.crt file will be downloaded.

Within the UI on dev.leantech.me you should also download the Lean certificate chain. To do this click the button labelled 'Certificate chain'. This should trigger a further download of a zipped folder containing lean_public_cert_chain.pem.

With the above complete you should now have three files.


Node example

javascript

const fs = require('fs')
const https = require('https')
const axios = require('axios')
const httpsAgent = new https.Agent({
// This is your application certificate
cert: fs.readFileSync('cert.crt'),
// This is your private key associated with application certificate
key: fs.readFileSync('key.pem'),
// This is Lean's public certificate chain.
ca: fs.readFileSync('ca.pem'),
})
const start = async () => {
try {
const request = await axios({
method: 'post',
headers: {
'lean-app-token': 'LEAN_APP_TOKEN',
},
httpsAgent,
// You can change the end point per your need. This endpoint is good for
// testing mTLS
url: 'https://api.leantech.me/customers/v1',
withCredentials: true,
jar: true,
})
console.log(request)
} catch (error) {
console.log(error)
}
}
start()

Go example

go

package main
import (
"crypto/tls"
"crypto/x509"
"flag"
"io/ioutil"
"log"
"net/http"
)
var (
certFile = flag.String("cert", "cert.crt", "Your application certificate provided by Lean")
keyFile = flag.String("key", "key.pem", "Your private key attached to application certificate")
caFile = flag.String("CA", "ca.pem", "Lean's public certificate chain")
)
func main() {
flag.Parse()
// Load client cert
cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
if err != nil {
log.Fatal(err)
}
// Load CA cert
caCert, err := ioutil.ReadFile(*caFile)
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Setup HTTPS client
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
tlsConfig.BuildNameToCertificate()
transport := &http.Transport{TLSClientConfig: tlsConfig}
client := &http.Client{Transport: transport}
// Please change the end point as required.
res, err := client.Get("https://api.leantech.me/customers/v1")
if err != nil {
log.Fatal(err)
}
contents, err := ioutil.ReadAll(res.Body)
log.Print(string(contents))
}

Python example

python

import json
import requests
getBanksUrl = 'https://api.leantech.me/banks/v1/'
headers = {'lean-app-token': 'YOUR_APP_TOKEN', 'Content-Type': 'application/json'}
result = requests.get(
getBanksUrl,
headers=headers,
cert=('your_apps.crt', 'your_apps.pem'), # Use the path to your own certificate and private key here
verify='lean_certificate_chain.pem'
)
if (result.status_code == 200) :
print (result.json())
else :
print (f"Error - {result.json()['status']}: {result.json()['message']}")

Testing

While your application does not have Production access, you can check your mTLS configuration by making a GET request to https://api.leantech.me/banks/v1.

If your application is configured correctly the API will respond with an INSUFFICIENT_ACCESS_LEVEL error. If it doesn't you'll get a connection error that depends on your programming language / framework.