HTTP signature on Webhooks
A-Cube applies a digital signature to each http call directed to the customer's system
The signature implements the IETF HTTP Message Signatures draft standard
Here you can make some tests and you can also find a list of libraries to verify the signature with different languages.
Http headers added to each call
Every API call to your webhook will contain 3 headers related to the HTTP signature:
- signature
- signature-input
- content-digest
Example:
signature pyhms=:AaMvAaBdJ2cUFmbOphvpoNTyu0uXAaQjIZXTweRl6hseuHNRpdPYA14EDJCBnnBXbcaOjiZ9F137wP6fBhN6CA==: signature-input pyhms=("@method" "@authority" "@target-uri" "date" "content-digest");created=1677383376;keyid="acube";alg="ed25519" content-digest sha-256=:Qm/ATwS/j9tYMdw3u7bc9w9jo34FpoxupfY+ha5Xk3Y=:
Public key. Key id: acube
Use this public key to verify the content sent by A-Cube API platform to your webhook.
For sandbox:
Public key
Loading public key...
Public key
Loading public key...
For production:
Public key
Loading public key...
Public key
Loading public key...
Examples of signature verification
Python
bashpython
pip install "fastapi[all]"
pip install requests
pip install requests-http-signature
import requests
from fastapi import FastAPI, Request, HTTPException
from requests_http_signature import (
HTTPSignatureAuth,
InvalidSignature,
algorithms,
)
app = FastAPI()
class KeyResolver:
def resolve_public_key(self, key_id):
if key_id != "acube":
raise HTTPException(status_code=401, detail="Invalid http signature: key_id doesn't match")
return requests.get("https://common-sandbox.api.acubeapi.com/signature-public-key").json()["public_key"]
@app.post("/my_webhook")
async def my_webhook(request: Request):
class RequestData:
async def fill(self, request):
self.body = await request.body()
self.headers = request.headers
self.url = str(request.url)
self.method = request.method
return self
requestData = await RequestData().fill(request)
try:
HTTPSignatureAuth.verify(
requestData,
signature_algorithm=algorithms.ED25519,
key_resolver=KeyResolver(),
)
return {"message": "done"}
except InvalidSignature:
raise HTTPException(status_code=401, detail="Invalid http signature")
Typescript
We created a sample repository with a demo Typescript application that verifies the signature we apply to webhooks calls.