Authentication

Authentication

YGG Redeem provides two authentication options for your APIs. We strongly recommend Option B for enhanced security.

Authentication Options

Enhanced HMAC Signature Authentication

🔐

Recommended for production - provides request integrity and prevents tampering

HeaderDescriptionExample Value
X-API-KEYPartner generatedyour_api_key
X-API-REQUESTUnique UUID v7, YGG generated01987d64-6519-747b-9200-beba98700464
X-API-SIGNATUREHMAC Signature, YGG generated92aa703cc483ea2cc90488c05e699179...

Important Security Notes

🔑

Keep these secure:

  • SHARED_SECRET_KEY: Provided by YGG, used for HMAC signature generation
  • X-API-KEY: Generated by Partner, shared with YGG securely

Key Components

  • X-API-REQUEST: Random UUIDv7 to prevent duplicate transactions. Reject duplicate requests.
  • X-API-SIGNATURE: HMAC signature covering method, path, and body. Any modification invalidates the signature.

Two-Way HMAC Authentication

🔄

Important Update: Partners must generate X-API-SIGNATURE for both requests AND responses

When YGG Redeem calls your API, the flow involves two signature generations:

  1. YGG → Partner: YGG generates X-API-SIGNATURE and includes it in the request header
  2. Partner → YGG: Partner generates X-API-SIGNATURE and includes it in the response header

Response Signature Requirements

HTTP StatusSignature RequiredNotes
200 OKYESMust generate X-API-SIGNATURE in response headers
400 Bad Request❌ NoNo signature needed
401 Unauthorized❌ NoNo signature needed
404 Not Found❌ NoNo signature needed
429 Too Many Requests❌ NoNo signature needed
500 Internal Server Error❌ NoNo signature needed

HMAC Signature Generation

Step 1: Generate UUIDv7

Generate a new UUIDv7. Example: uuid7.com (opens in a new tab). The embedded timestamp in the UUIDv7 will serve as a nonce:

X-API-REQUEST = "01987d64-6519-747b-9200-beba98700464"

Step 2: Create Canonical Payload

Build a consistent string to sign:

payload = method + path + X-API-REQUEST + stringify(body)

Payload components:

📝

For GET requests, the body is an empty string ""

Step 3: Generate HMAC Signature

signature = hmac_sha256(SHARED_SECRET_KEY, payload)

Complete Example

Here's a full implementation example for a POST request:

const crypto = require('crypto')
const stringify = require('json-stable-stringify')
 
// Configuration
const API_KEY = 'your_api_key'
const SHARED_SECRET_KEY = 'shared_secret_key'
 
// Incoming Request
const method = 'POST'
const path = '/api/v1/deduct-points-by-address'
const uuidv7 = '01870603-f211-7b9a-a7ea-4a98f5320ff8'
const body = {"address":"0x123456","points":1000}
const headers = request.headers
 
// Validate API Key
if (API_KEY !== headers['X-API-KEY']) {
  return response.status(401).json({
    success: false,
    errorCode: 'ERR-AUTH-FAILED',
    errorMessage: 'Unauthorized'
  })
}
 
// Create payload to sign
const payload = method + path + uuidv7 + stringify(body)
 
// Generate signature
const signature = crypto.createHmac('sha256', SHARED_SECRET_KEY)
                        .update(payload)
                        .digest('hex')
 
// Validate signature
if (signature !== headers['X-API-SIGNATURE']) {
  return response.status(401).json({
    success: false,
    errorCode: 'ERR-INVALID-SIGNATURE',
    errorMessage: 'Invalid signature'
  })
}
 
// ✅ Valid signature - process request
console.log('✅ Request authenticated successfully')
 
// Execute business logic (e.g., deduct points)
const responseBody = {
  success: true,
  partnerTransactionId: "partner-generated-transaction-id"
}
 
// 🔑 GENERATE RESPONSE SIGNATURE (Required for 200 OK responses)
const responsePayload = method + path + uuidv7 + stringify(responseBody)
const responseSignature = crypto.createHmac('sha256', SHARED_SECRET_KEY)
                                .update(responsePayload)
                                .digest('hex')
 
// Set response headers including signature
response.set({
  'Content-Type': 'application/json',
  'X-API-SIGNATURE': responseSignature  // 🔑 Critical: Include in response
})
 
// Send response to YGG Redeem
response.json(responseBody)

Implementation Checklist

When implementing two-way HMAC authentication, ensure you:

Request Validation (Incoming)

  • Validate the X-API-KEY matches your stored value
  • Check for duplicate X-API-REQUEST values
  • Generate signature using the exact same payload format
  • Compare signatures using constant-time comparison
  • (Optional) Validate UUIDv7 timestamp for freshness

Response Signature (Outgoing)

  • For 200 OK responses: Generate X-API-SIGNATURE using response body
  • For error responses (4xx, 5xx): No signature required
  • Include X-API-SIGNATURE in response headers before sending
  • Use same payload format: method + path + uuidv7 + stringify(responseBody)
  • Ensure response body JSON is consistently stringified

Timestamp Validation (Optional): Extract the timestamp from UUIDv7 using this converter (opens in a new tab) to enforce short-lived requests.