About Authentication

This page describes the necessary pieces needed for authentication.

Log in to see your API keys
API KeyLabelLast Used

Signature Logic

Signature is used to ensure that the JWT issuer truly knows the JSON Web Token (JWT) requestor. Since JWTs grant access to data and behavior representing a specific organization or merchant, they can be requested only when a value is known to each server.

🚧

Server Side Only

Your signature should never be sent to a client side application. Always execute this logic on your server, where the secret can be encrypted and stored securely.

A JSON Web Token (JWT) contains a lot of information and must be trusted when used. Each of these steps is intended to ensure that the JWT can only be created in a truly trusted manner, protecting against easily decrypted signatures, replay attacks, etc.

Here is a pseudocode summary of the logic used to generate the signature. If you want to double-check your logic, you can use this tool.

1. Random Value

Generate a random string of at least 32 characters, with longer values encouraged. We suggest 64 characters.
Example: rMC%aeVO$&jH3oM4LkijKsz$MS533SZ7f%qLdHZyrB71!7xRQAq!2si&$nBV!Ypm

2. Current Time

Get the current time in seconds (GMT), which must be within 5 seconds of the current EPOCH.
Example: 1565870400

3. Build Signature Input

Combine your random string, the length of that string, and the timestamp in a string, with dots separating each value.
Example: rMC%aeVO$&jH3oM4LkijKsz$MS533SZ7f%qLdHZyrB71!7xRQAq!2si&$nBV!Ypm.64.1565870400

4. Create Signature

HMAC 256 encodes the value created using the shared secret (secret key) and outputs it in Base64.
Example: BJY6fZBoq84Fo5JKFoQh6XpeQgeKz1kVz2DrErIp6sU=

📘

I don't know my Secret Key

Your Client ID & Secret Key are provided to you when you are granted access to the Authvia API. If you feel you should have one but do not, please contact us - [[email protected]].

📘

Gotchas

Make sure your base 64 encoding includes the padding characters (base64encode.org) or your signature will be considered invalid.

Another thing we've noticed, is machines out of sync with the atomic clock. Make sure your server/local machine is not to far out of sync, or JWTs will never be issuable. You can check your machine's time here.

Code Examples

const crypto = require('crypto');

// 1. Create random string for value.
const signatureValue = crypto.randomBytes(64).toString('hex');

// 2. Get current timestamp in seconds.
const timestamp = Math.floor(Date.now() / 1000);

// 3. Assemble
const signatureString = `${signatureValue}.${signatureValue.length}.${timestamp}`;

// 4. Generate HMAC and output Base64
const signature = crypto.createHmac('SHA256','{your_shared_secret}').update(signatureString).digest('base64');
import base64
import hmac
import hashlib
import uuid
import time

# 1. Use GUID for our 'random' string value.
signature_value = str(uuid.uuid4())

# 2. Get current timestamp in seconds.
timestamp = int(time.time())

# 3. Assemble
signature_string = f"{signature_value}.{len(signature_value)}.{timestamp}"

# 4. Generate HMAC and output Base64
key = b"{your_shared_secret}"
message = signature_string.encode("utf-8")

digest = hmac.new(key, message, hashlib.sha256).digest()
signature = base64.b64encode(digest).decode("utf-8")
using System;
using System.Text;
using System.Security.Cryptography;

// 1. Use GUID for our 'random' string value.
var signatureValue = Guid.NewGuid().ToString();

// 2. Get current timestamp in seconds.
int secondsSinceEpoch = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();

// 3. Assemble
var data = $"{signatureValue}.{signatureValue.Length}.{secondsSinceEpoch}";

// 4. Generate HMAC and output Base64
using var hashObject = new HMACSHA256(Encoding.UTF8.GetBytes("{your_shared_secret}"));
var signatureHmac = hashObject.ComputeHash(Encoding.UTF8.GetBytes(data));
var signature = Convert.ToBase64String(signatureHmac);
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.UUID;

public class SignatureExample {
    public static void main(String[] args) throws Exception {

        // 1. Use GUID for our 'random' string value.
        String signatureValue = UUID.randomUUID().toString();

        // 2. Get current timestamp in seconds.
        long timestamp = System.currentTimeMillis() / 1000;

        // 3. Assemble
        String signatureString = signatureValue + "." + signatureValue.length() + "." + timestamp;

        // 4. Generate HMAC and output Base64
        String secret = "{your_shared_secret}";
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        sha256_HMAC.init(secretKey);

        byte[] hash = sha256_HMAC.doFinal(signatureString.getBytes(StandardCharsets.UTF_8));
        String signature = Base64.getEncoder().encodeToString(hash);

        System.out.println("Signature: " + signature);
    }
}
import crypto from "crypto";

// 1. Create random string for value.
const signatureValue = crypto.randomBytes(64).toString("hex");

// 2. Get current timestamp in seconds.
const timestamp = Math.floor(Date.now() / 1000);

// 3. Assemble
const signatureString = `${signatureValue}.${signatureValue.length}.${timestamp}`;

// 4. Generate HMAC and output Base64
const secret = "{your_shared_secret}";
const signature = crypto
  .createHmac("sha256", secret)
  .update(signatureString)
  .digest("base64");

console.log("signatureValue:", signatureValue);
console.log("timestamp:", timestamp);
console.log("signature:", signature);

Scopes

📘

What are my scopes?

The list of scopes available to you depends on your account with Authvia. You will receive the scopes you have when you get API access. Think you need more scopes? Let us know!

The JSON Web Token (JWT) must contain the correct permissions for the call to be authorized and executed successfully. Permissions are defined in the scope claim of the JWT, which is granted during the creation of the JWT by the JWT issuer. You will only be granted a scope for the application requesting the JWT. It's best practice to only ask for what is needed principle of least privilege. So, when creating your JWT, specify a scope that limits the JWT's abilities to the specific use case it is intended for.

For each endpoint, we will document which scope must be granted on the JWT to access that API call. If you have trouble figuring out what scopes are necessary or available to you, please contact us.

📘

JWT Spec

RFC-7519


Credentials
Click Try It! to start a request and see the response here!