All mutating DFNS API requests require User Action Signing: get a challenge, sign it, exchange it for a User Action Token, and include the token in your request.
User Action Signing is required for all state-changing API calls. It produces a cryptographically-signed audit trail, available via the Audit Logs API.
A cryptographically-signed audit-trail is available using the Audit Logs API for you to review who requested and validated every single action taken on DFNS.
Check out the API Reference to get details about how to implement the different signing flows.
A signing challenge is returned from a call to: Get a User Action ChallengeYou will receive an object with the following properties (additional properties exist for signing with WebAuthn):
field
description
challenge
A string that will be signed with your private key
challengeIdentifier
A JWT that identifies the signing session
allowCredentials
The list of private key credentials that are enabled for the user
2
Sign the challenge
This step differs depending on the type of credential you are using:
Human users often use passkeys, with which the signing process is all managed by their OS and browser in the frontend (website, mobile app, etc).
Machine users use asymmetric keys that you need to use in the backend with a crypto library.
You will need to format the challenge into a Client Data object, convert the object into a JSON string and sign the string using one of the credentials listed in allowCredentials.See the example flow below.
3
Submit the User Action Signature to DFNS
Call the endpoint: Create User Action SignatureProvide the base64url-encoded signed challenge, the base64url-encoded client data, and the credential ID used to sign.You receive a User Action Token in return. This token is single-use.
4
Include the User Action Token in your API call
Pass the User Action Token as the X-DFNS-USERACTION header on the actual request you needed to make.
Example with a Fido2 passkey, where the use signs the challenge in your frontend:See how to implement this Fido2 signing flow in the API Reference.You can test this flow with the delegated wallets tutorial.
Your backend can use a service account to call the DFNS API, but the service account will also be required to sign its sensitive requests.When creating a service account, you will have to generate a key pair and register its public key with DFNS.The private key is used to sign the challenges.See how to implement this asymmetric keys signing flow in the API Reference.Example of what the backend needs to do to sign the challenge. In the flow above this is represented by the “KMS”, a recommended secure storage for your credentials.
When using any backend SDK with a configured signer, this signing process is handled automatically. The examples below show the manual implementation for reference, alongside the SDK-based approach.
const signChallenge = async (challenge: UserActionSignatureChallenge) : Promise<SignedChallenge> => { // The data being signed includes information that is important for validating the request originated from a valid location. const clientData: Buffer = Buffer.from( JSON.stringify({ type: 'key.get', challenge: challenge.challenge, origin: origin, crossOrigin: false, } as ClientData) ) // Signing can be done locally or by calling an external signer (like AWS KMS). const signature = crypto.sign( undefined, clientData, apiKeyPrivateKey ) // Pass back the signature, and the data that was signed so both can be parsed and validated properly. return { clientData: clientData.toString('base64url'), credId: challenge.allowCredentials.key[0].id, signature: signature.toString('base64url'), }}