Authentication

SKUU Connect uses two mechanisms, and which one applies depends on the direction of the call and on whether the request has a body.

Which mechanism applies where
DirectionRequestWhat proves it
SKUU to the storeGET /productsAuthorization: Bearer <token>
SKUU to the storeAny request with a bodyBearer token plus X-SKUU-Signature
The store to SKUUAny eventX-SKUU-Signature

The store issues the bearer token SKUU sends. The HMAC secret is one random value per environment, shared by both sides.

The signature

X-SKUU-Signature: sha256=<lowercase hex of HMAC-SHA256(secret, raw body bytes)>

To verify, in this order:

  1. Read the raw request bytes. Do not parse, re-serialize or trim them first.
  2. Compute HMAC-SHA256 over those bytes with the shared secret as UTF-8.
  3. Hex-encode the 32-byte digest in lowercase and prefix sha256=.
  4. Compare with the header using a constant-time comparison.
  5. Only then parse the JSON.

Whitespace, key order and escaping change the digest. Sign the exact bytes sent. Lowercase hex is the contract; SKUU tolerates uppercase.

Test vector

secret:  skuu_test_secret
body:    {"variant_id":"V-123-38-BLK","location_id":"900","available_quantity":4}
header:  sha256=4d87a87bf1603abb826636239e62cedc6b15990fd609f3f5afb15dde81e5acc4

The body is exactly 72 bytes with no trailing newline, and if the signing code produces this header the store's signing is right.

import hashlib, hmac

def sign(secret: str, raw_body: bytes) -> str:
    return "sha256=" + hmac.new(secret.encode("utf-8"), raw_body, hashlib.sha256).hexdigest()

def verify(secret: str, raw_body: bytes, header: str) -> bool:
    return hmac.compare_digest(sign(secret, raw_body), (header or "").lower())

A bad signature

An unsigned request, a wrong signature and an unknown shop_slug all get the same 401 body, {"detail": "unauthorized"}. SKUU does not say which.

Rotating the secret

The request format has no key id, so a rotation is a small ceremony per environment: agree a moment, stage the new value on both sides, switch, verify, then revoke the old value. Never rotate one side alone.

The next page is Errors and retries.


Did this page help you?