Lewati ke konten utama

Autentikasi HMAC

Endpoint server-to-server Kesles tertentu menggunakan HMAC-SHA256 untuk autentikasi + integrity check. Guide ini menjelaskan pattern signature dari sisi client.

catatan

Sebagian endpoint Partner API memakai Bearer JWT (lihat API Partner). Untuk endpoint berbasis HMAC sign per request, URL dan payload spec lengkap di-share per partner via Perjanjian Partner / channel onboarding terenkripsi (bukan dokumen publik). Tipe partner integrasi yang memerlukan HMAC ditentukan saat onboarding.

Header yang Wajib

Setiap request HMAC harus include 4 header wajib. Endpoint event tambahan wajib sertakan X-Idempotency-Key:

HeaderValuePurposeWajib?
X-API-Key-IDIdentifier publik (aman di-log)Server lookup secretSemua endpoint
X-TimestampUnix seconds saat ini (UTC)Replay protection — window 5 menit (300 detik)Semua endpoint
X-Signaturehmac-sha256=<hex>Integrity + authSemua endpoint
X-Request-IDUUID v4Distributed tracingSemua endpoint
X-Idempotency-KeyUUID v4 (dibuat caller, per-event)Idempotent event delivery — server return HTTP 200 {"status":"duplicate_skipped"} kalau event sudah pernah diterimaEndpoint event saja (/psp/v1/events)

Canonical String-to-Sign

Format 4-baris, dipisah newline \n:

{timestamp}\n{METHOD}\n{path-with-query}\n{body}
  • timestamp — unix seconds (contoh 1716452580)
  • METHOD — uppercase (GET, POST, PATCH, DELETE)
  • path-with-query — path full + query string (mis. <endpoint-path-from-partner-agreement>?param=value). Jangan include scheme atau host
  • body — raw JSON body persis seperti yang dikirim (byte-for-byte). Kosong untuk GET/DELETE — trailing newline tetap ada

Contoh GET

1716452580
GET
<path-endpoint-partner-specific>?query=value

(baris ke-4 kosong — body kosong, tapi newline tetap dihitung)

Contoh POST

1716452580
POST
<path-endpoint-partner-specific>
{"external_event_id":"evt-123","event_type":"transaction.success",...}
catatan

Path endpoint spesifik yang memerlukan HMAC di-share per partner via Partner Agreement, bukan dokumen publik.

Hitung Signature

Node.js

import crypto from 'crypto';

const secret = process.env.KESLES_HMAC_SECRET;
const timestamp = Math.floor(Date.now() / 1000).toString();
const method = 'POST';
const path = '<endpoint-path-from-partner-agreement>';
const body = JSON.stringify({ external_event_id: 'evt-123', event_type: 'transaction.success' });

const stringToSign = `${timestamp}\n${method}\n${path}\n${body}`;
const signature = 'hmac-sha256=' + crypto
.createHmac('sha256', secret)
.update(stringToSign)
.digest('hex');

// Header request:
// X-API-Key-ID: <key-id>
// X-Timestamp: ${timestamp}
// X-Signature: ${signature}
// X-Request-ID: <uuid-v4>

Go

mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(stringToSign))
signature := "hmac-sha256=" + hex.EncodeToString(mac.Sum(nil))

Python

import hmac, hashlib

sig = hmac.new(secret.encode(), string_to_sign.encode(), hashlib.sha256).hexdigest()
signature = f"hmac-sha256={sig}"

Catatan Keamanan

  1. Timestamp window: 5 menit (300 detik). Kalau server clock skew lebih dari itu, sync pakai NTP.
  2. Replay protection: timestamp window (5 menit) mencegah signature yang di-replay. Untuk endpoint event, field external_event_id dari request body dicek terhadap psp.event_log — event duplikat return HTTP 200 {"status":"duplicate_skipped"} di body (bukan ditolak atau error). Event tidak di-proses ulang. Header X-Idempotency-Key wajib dikirim per konvensi protokol dan nilainya harus sama dengan external_event_id.
  3. Constant-time compare: server pakai hmac.Equal — tidak vulnerable timing attack.
  4. IP allowlist: untuk integrasi server-to-server tertentu, endpoint juga di-gate IP allowlist per credential. Kalau IP partner berubah, koordinasi dulu via security@kesles.com.
  5. Never log the secret: log hanya X-API-Key-ID, X-Timestamp, dan X-Signature (sudah hashed). Jangan pernah log KESLES_HMAC_SECRET plain.

Rotasi Secret

  • Secret di-rotate oleh tim Kesles maksimal setiap 90 hari.
  • Saat rotation, ada grace period 7 hari — kedua key aktif simultan. Siapkan app untuk dual-key fallback.
  • Kalau curiga secret bocor, request revoke segera via security@kesles.com.

Langkah Berikutnya

  • Referensi API Partner — endpoint API Partner standar
  • Untuk endpoint server-to-server berbasis HMAC, hubungi tim integrasi Kesles via Perjanjian Partner