OptStuff

Security Best Practices

Defense-in-depth security overview — encrypted storage, request signing, domain whitelisting, rate limiting, and actionable recommendations.

OptStuff is built with a defense-in-depth approach. Even if one layer is compromised, multiple additional barriers protect your assets.

Security Layers

LayerProtects AgainstHow
Encrypted StorageDatabase breachesAES-256-GCM encryption for secret keys at rest
Request SigningUnauthorized usageHMAC-SHA256 signature on every request
Signature ExpirationReplay attacksOptional exp timestamp limits URL validity
Domain WhitelistingHotlinking & abuseTwo-layer domain control
Rate LimitingResource exhaustionPer-key per-minute and per-day limits
Dual-Key SystemAccidental exposureSeparates public identifiers from secrets

Encrypted Storage

Secret keys are encrypted with AES-256-GCM before storage. The encryption key is derived via HKDF (RFC 5869) from a master secret stored in environment variables — separate from the database. Even if the database is compromised, attackers cannot obtain usable keys.

Request Signing

Every request must include an HMAC-SHA256 signature. The signature is a one-way function — intercepting it cannot reveal the secret key. Signatures are compared using constant-time comparison (timingSafeEqual) to prevent timing attacks.

See URL Signing for implementation details.

Signature Expiration

The optional exp parameter limits how long a signed URL is valid. Recommended expiration times depend on the use case — see URL Signing.

Domain Whitelisting

Two-layer domain control restricts both who can use the service (referer domains) and which images can be processed (source domains). Both settings are configured at the project level in Settings → Domain Security. Referer validation targets browser-based hotlinking specifically — requests without a Referer header are allowed since they indicate server-to-server calls or privacy-stripping policies, not hotlinking. See Domain Whitelisting for configuration and Referer Security Model for the trust model.

Rate Limiting

Per-key rate limits prevent abuse and contain the impact of compromised keys. In the current implementation, Redis outages cause rate limiting to fail open to preserve availability; monitor Redis health and alerting accordingly. See Rate Limiting for details.

Dual-Key System

Public keys (pk_...) are safe to expose in URLs. Secret keys (sk_...) never leave your server. Even if someone sees a signed URL, they cannot forge new requests.

Attack Protection Summary

AttackProtection
Brute ForceHMAC-SHA256 + 32-char signature makes collision infeasible
Replay AttacksSignature expiration (exp) limits URL validity
Timing AttackstimingSafeEqual constant-time comparison
Database BreachAES-256-GCM encryption; keys useless without master key
Man-in-the-MiddleHTTPS + signature validation
HotlinkingReferer domain whitelist
Unauthorized SourcesSource domain whitelist
Resource ExhaustionPer-key rate limiting
SSRFImage proxy validation/whitelisting and request sanitization (details)

Secure Defaults

SettingEmpty/Unset Behavior
allowedSourceDomainsProduction: reject all requests
allowedRefererDomainsAllow all (no restriction)
API key expirationNo expiration (we recommend setting one)

Technical Standards

StandardUsage
AES-256-GCMAuthenticated encryption for stored keys
HKDF (RFC 5869)Cryptographic key derivation
HMAC-SHA256URL signature generation
Constant-time comparisonTiming-safe signature verification

Production Checklist

Use this checklist before going live:

API Key Security

  • Secret keys (sk_...) stored in server-side environment variables only
  • No secret keys in frontend code, Git, or client-side bundles
  • .env / .env.local files added to .gitignore
  • API key expiration set for non-permanent integrations
  • Unused or test keys revoked

Domain Security

  • allowedSourceDomains explicitly configured (empty list rejects all in production)
  • allowedRefererDomains configured if browser hotlinking is a concern
  • Development, staging, and production use separate projects or domain configs

URL Signing

  • All signing happens server-side (Server Components, API Routes, or backend services)
  • Appropriate exp expiration set on signed URLs
  • No signing logic in client-side JavaScript

Infrastructure

  • Redis health monitoring configured
  • Rate limit alerts set (see Rate Limiting)
  • HTTPS enforced on all endpoints

Environment Isolation

Use separate projects and API keys for each environment to prevent cross-environment leakage:

EnvironmentProjectAPI KeySource Domains
Developmentmy-app-devDev key (short expiry)Empty (allows all)
Stagingmy-app-stagingStaging keySame as production
Productionmy-appProduction keyExplicitly listed

This ensures a compromised development key cannot access production resources, and development traffic does not consume production rate limits.

Incident Response: Key Compromise

If an API key may have been exposed:

  1. Rotate immediately — Use the Rotate action in Dashboard → API Keys. This atomically revokes the old key and creates a new one.
  2. Update environment variables — Deploy the new secret key to all services that use it.
  3. Review request logs — Check Dashboard → Usage for suspicious traffic patterns during the exposure window.
  4. Audit access — Verify no unauthorized domains were added to the project's domain security settings.
  5. Consider expiration — For the new key, set a shorter expiration until you've confirmed the incident is contained.

Rotation is atomic — the old key stops working the moment the new key is created. Plan for a brief window where in-flight requests with the old key may fail.

Last updated on

On this page