Credentials and integrations

Prevent replay and duplicate work

Use expirations, nonces, idempotency keys, and stored operation results where repeated requests could charge, send, or mutate twice.

Networks retry. Attackers replay. A sensitive operation needs a clear answer to “what if this exact request arrives again?” — because it will, whether from a flaky mobile connection or a captured request resent on purpose.

Idempotency keys for client retries

Use idempotency keys tied to the caller and operation, store the result for a bounded period, and reject conflicting reuse:

curl -X POST https://api.example.com/payments \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: pay-order-8912" \
  -d '{"invoiceId":"inv_9f3c2a","amount":4900}'

A client times out after payment succeeds and retries the same request. Returning the stored result prevents a second charge, while reusing the key with a different amount must fail:

# same key, different body
curl -i -X POST https://api.example.com/payments \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: pay-order-8912" \
  -d '{"invoiceId":"inv_9f3c2a","amount":9900}'
# HTTP/1.1 422 Unprocessable Entity
# {"error":"idempotency key reused with a different request body"}

Make the store atomic

Store the key and result atomically with the operation. Otherwise two workers can both see an unused key and perform the same side effect before either stores evidence:

-- the unique constraint is the actual lock
INSERT INTO idempotency_keys (key, account_id, request_hash)
VALUES ('pay-order-8912', 'acc_42', 'sha256:9d1e44…')
ON CONFLICT (key, account_id) DO NOTHING;
-- zero rows inserted -> another worker owns this key,
-- return its stored result instead of charging again

Checking with a SELECT first and inserting afterwards is the race condition, not the fix. Design database changes atomically so a rejected duplicate leaves nothing half-done.

Give stored keys a bounded lifetime, say 24 hours. That covers realistic client retries, keeps the table small, and prevents an old key from resurrecting a stale result months later.

Replay windows for signed requests

For signed requests, include a timestamp or nonce and enforce a replay window. A captured request older than a few minutes gets rejected even with a valid signature, and a stored nonce blocks the same request inside the window.

Send two concurrent payment requests with the same idempotency key and body. Prove one charge exists, both callers receive the same result, and conflicting key reuse is rejected.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →