/

to search

Introducing Setu Changelog Check it out ↗

Please note that, due to changes on the Sandbox integration process for Setu Account Aggregator, this document is now outdated. Please refer to the updated quickstart to proceed.


#Request signing

According to ReBIT spec, each API call should be signed using a JSON Web Token to verify the source of the request. This is for all API calls made within the AA framework, be it a consent request or a health check.

The JWT implementation is of the the JWS (JSON Web Signature) flavour. This signature should be sent in the HTTP header “x-jws-signature” with each request or response.

The “detached” JWS is an approach that allows you to sign a request or response without modifying content body.


#How it works

A public-key-private-key pair is required for the request signing.

These keys would need to be generated once and do not have an expiry. These keys are used to verify the sanctity of request/response payloads between the FIU and Setu.


  • As an FIU, you should generate a signature using your private key and send it in the request/response. The public key is shared with Setu AA, via The Bridge FIU config, to verify the signature.
  • Setu AA generates a signature as well, using our private key and sends it in the request/response. The public key is shared with you on The Bridge FIU config to verify the signature.

#Generate keys for request signing

In the Setu Bridge, you can generate these keys with just a simple click of a button and download the keys in CSV format.

Setu will share its public key during the creation of app (available in the "grab credentials" step). Your app code will use this key to verify requests from Setu.


#Generate request signature

The Postman collection is configured to auto-generate JWS signatures for every request. Use these steps to generate *detached JWS signatures in your application code.

  • Create standard JWS with the header and payload
  • Split the JWS output with .
  • Replace the second element with an empty string “”, thus removing the payload.
  • Join the JWS back together with .

import jwt
private_key = b"""-----BEGIN PRIVATE KEY-----
MIIBIjANBgkqhkiG9w0BAQE..............
-----END PRIVATE KEY-----"""
def makeDetachedJWS(payload, key):
encoded = jwt.encode(payload, key, algorithm="RS256")
splittedJWS = encoded.split(".")
splittedJWS[1] = ""
return ".".join(splittedJWS)
request_body = {"body":"test"}
detached_jws = makeDetachedJWS(request_body, private_key)

#Verify request signature

Follow these steps to verify detached JWS signatures in your app code.

  • Split JWS with .
  • Replace the second element with the payload encoded using Base64 URL.
  • Rejoin the modified JWS with .

import jwt
import json
import base64
public_key = b"""-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQE..............
-----END PUBLIC KEY-----"""
def base64url_encode(input):
return base64.urlsafe_b64encode(input).replace(b"=", b"")
def validateDetatchedJWS(payload, signature, key):
splittedJWS = signature.split(".")
splittedJWS[1] = base64url_encode(json.dumps(payload, separators=(",", ":")).encode("utf-8"))
splittedJWS[1] = splittedJWS[1].decode("utf-8")
sig = ".".join(splittedJWS)
try:
jwt.decode(sig, key, algorithms=["RS256"])
return True
except Exception as e:
print(e)
return False
request_body = {"body":"test"}
print(validateDetatchedJWS(request_body, detached_jws, public_key))

Was this page helpful?