Authentication / JWT signature

Overview

When interacting with the Northstake API, it is crucial to ensure that all requests are authenticated using a combination of an API key and a JWT token. The JWT token must be signed with the RSA256 Key pair corresponding to the public key associated with your API key. Furthermore, each request must include a nonceand a base64 encoded representation of the request body, ensuring that the request is unique and secure.


📘

Use the Northstake SDK to handle the authentication

For NodeJS Development, we strongly recommend you check out our SDK which abstracts away much of the work involved in generating and signing payloads. Find it here.


Requirements for JWT Token

The JWT token must include the following information in its payload:

  • iat (Issued At): The timestamp when the token was issued, in UTC.
  • exp (Expiration Time): The timestamp when the token will expire, typically set to 30 seconds from the iat to ensure timely use. The Northstake API will automatically reject any requests issued more than 30 seconds before the request is received by the endpoint.
  • url: The specific URL endpoint you are requesting, ensuring that the token is valid for a single request path.
  • body: A base64 encoded string of the JSON-stringified request body. For GET or DELETE requests, where a body may not be present, this can be omitted or provided as an empty string.
  • nonce: A random integer between 0 and 99999, ensuring that each request is unique and idempotent. Also guards against

It is imperative that the JWT token does not include sensitive information and is signed with your private RSA256 key. Do not share or expose your private key.

Generating a JWT Token (Example)

Below is an example in Python/NodeJs that demonstrates how to generate a JWT token for a request. This script signs the token with a given RSA private key.

import jwt
from datetime import datetime, timedelta
import random
import base64
import json

# Path to your RSA private key file
private_key_path = 'path_to_your_private_key.pem'

# Load the private key from the file
with open(private_key_path, 'r') as file:
    private_key = file.read()

# Define the payload for the JWT
payload = {
    "iat": datetime.utcnow(),
    "exp": datetime.utcnow() + timedelta(seconds=60),
    "url": "/v1/account",
    "body": base64.b64encode(json.dumps({"test": "body"}).encode()).decode(),  # Example for a POST request
    "nonce": random.randint(0, 99999)
}

# Generate the JWT
token = jwt.encode(payload, private_key, algorithm="RS256")

print("JWT Token:", token)

const jwt = require('jsonwebtoken');
const fs = require('fs');

// Load your RSA private key from a file for security reasons
const privateKey = fs.readFileSync('path_to_your_private_key.pem', 'utf8');

const payload = {
  iat: Math.floor(Date.now() / 1000),  // Current time in seconds since epoch
  exp: Math.floor(Date.now() / 1000) + 60,  // Token expiration time (60 seconds from now)
  url: "/v1/account",
  body: Buffer.from(JSON.stringify({ test: "body" })).toString('base64'),
  nonce: Math.floor(Math.random() * 99999)
};

// Sign the token with your private key
const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });

console.log("JWT Token:", token);


Including JWT Token in Requests

When making a request to the Northstake API, include the generated JWT token in the Authorization header as a Bearer token. Additionally, include your API key in the x-api-key header:

Ensure the request body (if present) matches the base64 encoded string in the JWT token body claim, and that the url in the token matches the endpoint being called.

curl -X GET "https://api.northstake.com/v1/account" \
     -H "Authorization: Bearer your_jwt_token_here" \
     -H "x-api-key: your_api_key_here"
const axios = require('axios');

// Example JWT token and API key
const jwtToken = 'your_jwt_token_here';
const apiKey = 'your_api_key_here';

// Setting up the headers
const headers = {
    'Authorization': `Bearer ${jwtToken}`,
    'x-api-key': apiKey
};

// The API endpoint you're trying to access
const url = 'https://api.northstake.com/v1/account';

// Making the GET request
axios.get(url, { headers })
    .then(response => {
        console.log('Response:', response.data);
    })
    .catch(error => {
        console.error('Error:', error.response.data);
    });

import requests

# Example JWT token and API key
jwt_token = 'your_jwt_token_here'
api_key = 'your_api_key_here'

# Setting up the headers
headers = {
    'Authorization': f'Bearer {jwt_token}',
    'x-api-key': api_key
}

# The API endpoint you're trying to access
url = 'https://api.northstake.com/v1/account'

# Making the GET request
response = requests.get(url, headers=headers)

# Checking if the request was successful
if response.status_code == 200:
    print('Response:', response.json())
else:
    print('Error:', response.text)

By adhering to these guidelines, you can securely authenticate your requests to the Northstake API, leveraging JWT tokens to ensure the integrity and authenticity of each call.

🚧

Do not share your private key with Northstake or anybody else.