Threat model

An API key embedded in browser JavaScript, HTML source or a public repository can be copied. Browser clients should call your own authenticated endpoint; the server then calls the provider.

Configuration

Keep secrets in server environment variables or protected configuration. Apply least-privilege scopes when the API supports them. Use separate keys for development and production.

Example: outbound HTTPS request

$apiKey = getenv('SERVICE_API_KEY');
if (!$apiKey) { throw new RuntimeException('Missing API key'); }
$ch = curl_init('https://api.example.com/v1/resource');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
    CURLOPT_TIMEOUT => 15,
    CURLOPT_CONNECTTIMEOUT => 5,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException('Provider unavailable'); }
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code < 200 || $code >= 300) { throw new RuntimeException('Provider error'); }

Replace the example URL with the official provider endpoint. Never pass visitor-controlled URLs into this fetch path.

Production safeguards

  • Authenticate and rate-limit your own API endpoint.
  • Validate outbound payload size and output type.
  • Log only non-sensitive metadata and status codes.
  • Monitor usage and set billing limits where supported.
  • Rotate credentials on suspicion of exposure.
  • Treat provider responses as untrusted input and escape them in HTML.
Editorial note

Examples are starting points, not production security audits. Confirm dependencies, versions and pricing using linked vendor documentation.