PieBox
Documentation

HMAC-SHA256 Authentication

High-security authentication for server-side integration

For server-side integration scenarios requiring higher security than API Key. For everyday use with tools like Claude Code, API Key authentication is sufficient.

Authentication Flow & Request Headers

Authentication Flow:

  1. Obtain appId and appSecret (select "Other" scenario when applying)
  2. Build the signature string
  3. Sign it with appSecret using HMAC-SHA256
  4. Include the authentication info in request headers

Request Headers:

HeaderDescription
X-App-IdApplication ID
X-TimestampUnix timestamp (seconds), valid for 5 minutes
X-NonceRandom string to prevent replay attacks — must be unique per request
AuthorizationHMAC-SHA256 {signature}

Signature Computation

Signature string format (fields joined with newline \n):

{HTTP_METHOD}\n{PATH}\n{TIMESTAMP}\n{NONCE}\n{APP_ID}

Field Descriptions:

FieldDescriptionExample
HTTP_METHODRequest method (uppercase)POST
PATHRequest path (no domain or query)/chat/completions
TIMESTAMPCurrent Unix timestamp (seconds)1706745600
NONCE32-char random hex stringa1b2c3d4e5f67890abcdef1234567890
APP_IDApplication IDapp_xxxxx

Steps:

  1. Concatenate the signature string using the format above (use actual newline characters \n, not literal backslash-n)
  2. Compute HMAC-SHA256 using appSecret as the key
  3. Convert the result to a lowercase hexadecimal string

Code Examples

Node.js

import { createHmac, randomBytes } from "crypto"

const APP_ID = "<your-app-id>"
const APP_SECRET = "<your-app-secret>"
const BASE_URL = "https://tokenhub.piegateway.me"

function computeSignature(
  method: string,
  path: string,
  timestamp: number,
  nonce: string,
  appId: string,
  appSecret: string,
): string {
  const signatureString = `${method}\n${path}\n${timestamp}\n${nonce}\n${appId}`
  return createHmac("sha256", appSecret).update(signatureString).digest("hex")
}

function generateAuthHeaders(method: string, path: string) {
  const timestamp = Math.floor(Date.now() / 1000)
  const nonce = randomBytes(16).toString("hex")
  const signature = computeSignature(method, path, timestamp, nonce, APP_ID, APP_SECRET)

  return {
    "X-App-Id": APP_ID,
    "X-Timestamp": timestamp.toString(),
    "X-Nonce": nonce,
    Authorization: `HMAC-SHA256 ${signature}`,
    "Content-Type": "application/json",
  }
}

// Usage example
const path = "/chat/completions"
const headers = generateAuthHeaders("POST", path)

const response = await fetch(`${BASE_URL}${path}`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    model: "claude-haiku-4-5",
    messages: [{ role: "user", content: "Hello" }],
    max_tokens: 100,
  }),
})

const result = await response.json()
console.log(result)

Bash

#!/bin/bash
APP_ID="<your-app-id>"
APP_SECRET="<your-app-secret>"
BASE_URL="https://tokenhub.piegateway.me"
METHOD="POST"
API_PATH="/chat/completions"
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)

# Build signature string
SIGNATURE_STRING=$(printf "%s\n%s\n%s\n%s\n%s" "$METHOD" "$API_PATH" "$TIMESTAMP" "$NONCE" "$APP_ID")

# Compute HMAC-SHA256 signature (compatible with macOS and Linux)
SIGNATURE=$(echo -n "$SIGNATURE_STRING" | openssl dgst -sha256 -hmac "$APP_SECRET" | sed 's/^.*= //')

curl -X POST "{BASE_URL}{API_PATH}" \
  -H "X-App-Id: ${APP_ID}" \
  -H "X-Timestamp: ${TIMESTAMP}" \
  -H "X-Nonce: ${NONCE}" \
  -H "Authorization: HMAC-SHA256 ${SIGNATURE}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-haiku-4-5",
    "messages": [{"role": "user", "content": "Hello"}],
    "max_tokens": 100
  }'

WebSocket Authentication

WebSocket connections also support HMAC-SHA256 signature authentication:

Method 1: Headers (Recommended)

const ws = new WebSocket("wss://tokenhub.piegateway.me/ws/...", {
  headers: generateAuthHeaders("GET", "/ws/..."),
})

Method 2: Query Parameters (for browser environments)

const params = new URLSearchParams({
  "X-App-Id": APP_ID,
  "X-Timestamp": timestamp.toString(),
  "X-Nonce": nonce,
  Authorization: `HMAC-SHA256 ${signature}`,
})
const ws = new WebSocket(`wss://tokenhub.piegateway.me/ws/...?${params}`)

Security Constraints & Error Codes

Security Constraints:

ConstraintDescription
Timestamp validity5 minutes (300 seconds) — expired requests will be rejected
Nonce replay guardSame nonce can be used at most 3 times, expires after 300s
Signature caseSignature must be a lowercase hexadecimal string

HMAC Authentication Error Codes:

StatusError TypeDescription
401missing_auth_headersRequired authentication headers are missing
401invalid_timestampTimestamp expired (more than 5 minutes)
401nonce_reusedNonce has been reused (replay protection)
401invalid_appappId does not exist
401invalid_signatureSignature verification failed — check appSecret and string format
403app_disabledApplication has been disabled