Security and best practices

Reseller API

The API is designed assuming every call has direct financial impact and may access sensitive server credentials. Security requirements are therefore well above REST defaults.

Controls in place

  • HMAC-SHA256: Every request is signed with HMAC-SHA256 over method, path, timestamp, nonce and body hash. Constant-time verification (hash_equals).
  • AES-256-GCM: Secrets are persisted as AES-256-GCM ciphertexts only (libsodium). Master key lives outside the DB at /etc/kh-reseller-api/master.key.v{N}.
  • Replay protection: Timestamp window +-300s, nonce cache 600s. A successfully signed request cannot be replayed.
  • Scope-based authorization: Per-key explicit scope list. Writing and sensitive scopes must be explicitly enabled.
  • IP whitelist (optional): Optional IP whitelist per key (CIDR notation, IPv4 and IPv6).
  • Rate limit: Multi-layer: per key (minute + day) and per IP (minute). Token bucket with burst tolerance.
  • Idempotency: Orders and destructive service actions require an Idempotency-Key. 24h replay protection against network retries.
  • Tenant isolation: Every DB query hard-filters on your account id. Cross-tenant access is impossible by construction.
  • Tamper-evident audit log: Every request lands in the audit log with chain hash (chain_hash[n] = sha256(chain_hash[n-1] || row_n)). Retroactive tampering is detected by hash break.
  • Credentials.read alerting: Every credentials.read call produces a dedicated audit entry plus optional confirmation email to the account owner.
  • SSRF-guarded webhooks: Webhook URLs are vetted before storage: HTTPS only, DNS resolution must return public IPs only (no RFC1918, no link-local).

Best practices on your side

  • Store secret in a secret manager (HashiCorp Vault, AWS Secrets Manager, Doppler, 1Password), never in code, never in a git repo.
  • Rotate the secret regularly (at least yearly or after personnel changes). One-click rotation in the portal, the old secret is invalidated immediately.
  • One dedicated key per use case with the minimum scope (read-only if possible). No "god-mode" keys.
  • If your integration runs from fixed IPs (cloud, bastion): set an IP whitelist.
  • Generate the Idempotency-Key server-side and persist it; do not generate fresh on every retry. Recommendation: UUIDv4 per logical order.
  • Set a webhook to your own URL; watch at least order.created and credentials.read as an event stream.

Security disclosure

Please report security issues confidentially to security@kernelhost.com. PGP key on request. Response within 24h guaranteed. Bug-bounty program in preparation.