Signature
This section defines the specification for providing credentials to authenticate a client with the API gateway and access REST APIs. It describes how to generate Signature V2 and the Authorization
header, along with examples of signing an API request.
Obtain access key
Working as the credentials for open APIs, the access key is a pair, including an access key ID and an access key secret:
- Access key ID (AccessKeyID): used to identify the API caller, bound with the SwiftFederation account ID.
- Access key secret (AccessKeySecret): used in the encryption algorithm to generate the signature.
The customer could create and obtain the access key on the SwiftFederation portal:
- Log in to the SwiftFederation portal.
- Click the account name to open Access Keys.
- Click Create Access Key to create a new access key.
- Move the mouse over the Show button to copy the access key secret.
Generate signature
To sign an API request, the client needs to generate a signature with the API request information by following the algorithm:
- Concatenate the canonical header string
- Concatenate the canonical request information to be signed
- Generate the signature
1. Concatenate the canonical headers
To enhance the uniqueness and security of the signature, canonical headers must be concatenated as follows:
- Append a linefeed (
\n
, character0x0A
) after theHost
header, withHost
converted to lowercase. - Sort all headers with names starting with
X-SFD-
, then append each in the formatheadername:headervalue
, whereheadername
is lowercase. Append a linefeed (\n
, character0x0A
) after each header entry.
# i.e., assume that 3 common headers (X-SFD-Date, X-SFD-Nonce, X-SFD-Signature-Version) and 1 custom header (X-SFD-FZone) have header names starting with "X-SFD-" in the API request
# 1. X-SFD-Date
# 2. X-SFD-Nonce
# 3. X-SFD-Signature-Version
# 4. X-SFD-FZone
# After sorting 4 headers above, we could concatenate these 4 headers along with the header of "Host" in the order of:
# 1. Host
# 2. X-SFD-Date
# 3. X-SFD-FZone
# 4. X-SFD-Nonce
# 5. X-SFD-Signature-Version
CanonicalHedersStr =
"host:" + request.getHeader("Host") + "\n" +
"x-sfd-date:" + request.getHeader("X-SFD-Date") + "\n" +
"x-sfd-fzone:" + request.getHeader("X-SFD-FZone") + "\n" +
"x-sfd-nonce:" + request.getHeader("X-SFD-Nonce") + "\n" +
"x-sfd-signature-version:" + request.getHeader("X-SFD-Signature")
2. Concatenate the canonical request information to be signed
To construct the canonical string to be signed, concatenate the following request components in order:
- Append the HTTP method in uppercase with a linefeed (
\n
, character0x0A
). Example:GET\n
,POST\n
- Append the URI with a linefeed (
\n
, character0x0A
). Example:/v1.1/customer/35394\n
- Append the canonical headers generated in step 1 with a linefeed (
\n
, character0x0A
). - Append the access key ID with a linefeed (
\n
, character0x0A
). Example:O80ybSq26xUE383u\n
- Append the request body. Use an empty string (
""
) if the HTTP method isGET
.
CanonicalStringToBeSigned =
uppercase(${HTTPMethod}) + "\n" +
${URI} + "\n" +
${CanonicalHeaders}$ + "\n" +
${AccessKeyID}$ + "\n" +
${RequestBody}$
3. Generate the signature
To generate the signature, sign the canonical request string using the HMAC-SHA256 algorithm with the client’s secret key:
SignatureBytes = hmacSha256(${AccessKeySecret}, ${CanonicalStringToBeSigned});
Signature = Hex.encodeHex(SignatureBytes);
Form Authorization
header
After generating the signature, construct the Authorization
HTTP header in the following format:
Authorization: SMAC-SHA256 ${AccessKeyID}:${Signature}
Among the header values of Authorization
above,
- AccessKeyID: the access key ID obtained from the SwiftFederation Portal.
- Signature: the signature generated in step 3.
Sign the API request
Add the Authorization
header in the API request to complete the signing process.
Example
Assume: Original API request
The following API request is an example of signature generation:
GET /v1.1/customer/35394 HTTP/1.1
Host: open-api.swiftfederation.com
Content-Type: application/json; charset=utf-8
X-SFD-FZone: SG
X-SFD-Date: 20250806T045529Z
X-SFD-Nonce: 15121
X-SFD-Signature-Version: 2
1. Obtain access key
For an example purpose, we assume that the access key below was obtained from SwiftFederation Portal.
Access key ID (AccessKeyID) is: O80ybSq26xUE383u
Access key secret (AccessKeySecret) is: q738531SV3s0yFC2I3p7QJ49og37yIat
2. Generate signature V2
Concatenate canonical headers:
CanonicalHeders = "host:open-api.swiftfederation.com" + '\n' + "x-sfd-date:20250806T045529Z" + '\n' + "x-sfd-fzone:SG" + '\n' + "x-sfd-nonce:15121" + '\n' + "x-sfd-signature-version:2"
Concatenate canonical request information:
CanonicalStringToBeSigned = "GET" + '\n' + "/v1.1/customer/35394" + '\n' + "host:open-api.swiftfederation.com" + '\n' + "x-sfd-date:20250806T045529Z" + '\n' + "x-sfd-fzone:SG" + '\n' + "x-sfd-nonce:15121" + '\n' + "x-sfd-signature-version:2" + '\n' + "O80ybSq26xUE383u" + '\n + ""
Generate the signature:
SignatureBytes = hmacSha256(${AccessKeySecret}, ${CanonicalStringToBeSigned});
# Here AccessKeySecret is: q738531SV3s0yFC2I3p7QJ49og37yIat
# CanonicalStringToBeSigned is: "GET" + '\n' + "/v1.1/customer/35394" + '\n' + "host:open-api.swiftfederation.com" + '\n' + "x-sfd-date:20250806T045529Z" + '\n' + "x-sfd-fzone:SG" + '\n' + "x-sfd-nonce:15121" + '\n' + "x-sfd-signature-version:2" + '\n' + "O80ybSq26xUE383u" + '\n + ""
Signature = Hex.encodeHex(SignatureBytes);
# Signature is: 3ebba5b79c247db566d957638ecc9d085d4805a957f84ad8114af721635a41a7
3. Form "Authorization" header
With the generated signature, construct the Authorization
header:
Authorization: HMAC-SHA256 O80ybSq26xUE383u:3ebba5b79c247db566d957638ecc9d085d4805a957f84ad8114af721635a41a7
4. Sign the API request
By adding the HTTP header of Authorization
, the client can get the signed API request:
GET /v1.1/customer/35394 HTTP/1.1
Host: open-api.swiftfederation.com
Content-Type: application/json; charset=utf-8
Authorization: HMAC-SHA256 O80ybSq26xUE383u:3ebba5b79c247db566d957638ecc9d085d4805a957f84ad8114af721635a41a7
X-SFD-FZone: SG
X-SFD-Date: 20250806T045529Z
X-SFD-Nonce: 15121
X-SFD-Signature-Version: 2