Sign your requests
Learn how to sign requests to our Payment API.
All modification requests (for example, POST
, DELETE
) to our Payments APIs, authenticated with a client_credentials
token generated by TrueLayer's authentication server, must also be signed by including a valid Tl-Signature
HTTP header.
When you sign your requests to our APIs, you ensure a second layer of security on top of the authorisation bearer token, guaranteeing that the payload has not been tampered with.
Supported algorithms
We only support the ES512 signing algorithm for modification requests to our Payments APIs.
ES512 belongs to the family of Elliptic Curve Digital Signature Algorithms (ECDSA).
To sign an HTTP request using ECDSA you will need to generate an Elliptic Curve (EC) key pair. You will need:
- a public key, to be uploaded in the new Payments Settings page in our Console.
- a private key, to be used for signing requests, which you should not share with anyone outside of your organisation. ES512, in particular, requires a key pair that uses the P-521 family of elliptic curves (also known as
secpt521r1
).
Generate a signing key pair
You can generate a key pair using openssl
.
- To generate the private key, run:
docker run --rm -v ${PWD}:/out -w /out -it alpine/openssl ecparam -genkey -name secp521r1 -noout -out ec512-private-key.pem
- You can then obtain the public key by running:
docker run --rm -v ${PWD}:/out -w /out -it alpine/openssl ec -in ec512-private-key.pem -pubout -out ec512-public-key.pem
- Go to Console > Payments Settings and upload the file
ec512-public-key.pem
.
Sign your requests with our libraries
In our public repository we maintain libraries in a range of languages, which provide methods for signing and verifying according to the scheme described later. Our backend libraries also make use of these signing libraries for the API requests.
E.g. Java com.truelayer.truelayer-signing
// `Tl-Signature` value to send with the request.
String tlSignature = Signer.from(kid, privateKey)
.header("Idempotency-Key", idempotencyKey)
.method("post")
.path(path)
.body(body)
.sign();
Sign your requests without using libraries
Manual signing
We encourage the use of our signing libraries mentioned previously for easier integration.
To manually generate Tl-Signature
headers, or verify webhook signatures, it’s still recommended to refer to TrueLayer/truelayer-signing reference implementations & examples.
In particular see the document describing the signing scheme.
Test your signing logic
You can send a POST or DELETE request to our /test-signature
endpoint to verify that you have correctly implemented request signing. The /test-signature
endpoint will validate your Tl-Signature
header and return a 204 No Content
in case of success. It does not perform any kind of validation on the body schema.
curl -X POST \
-H "Authorization: Bearer ${access_token}" \
-H "Tl-Signature: ${signature}" \
--data '{"nonce":"9f952b2e-1675-4be8-bb39-6f4343803c2f"}' \
https://api.truelayer-sandbox.com/test-signature
Troubleshooting
- Ensure the
path
you are signing is the same path you are sending the request. So if testing againsthttps://api.truelayer-sandbox.com/test-signature
the path should be/test-signature
.
- Ensure all headers that are being signed are being sent with the request exactly as they were signed and none are missing. So if you sign
Idempotency-Key
you must also send exactly the same value in the request. Note:/test-signature
does not require any headers, so it is possible to test request signing without signing headers here (though headers are required for other endpoints).
- Ensure the body passed to the signing library exactly byte-for-byte matches the body sent with the request. E.g. it must not be formatted differently or have fields in a different order. Ensure the request body has no trailing newlines if it was not signed that way.
- Ensure the KID & private key you are signing with match the KID in console.truelayer.com & public key that was uploaded there.
- Try testing the endpoints using insomnia + insomnia-plugin-jws-by-truelayer plugin. The plugin generates
Tl-Signature
headers using the private key & kid environment variables, so can be used to check that the keys & console configuration are correct.
Import our Insomnia collection
Updated 3 days ago