Skip to content
Last updated

Tutorial: Secure API keys

Why API key security matters

Your API key authenticates every request to Paradise Gateway. A leaked key lets anyone process transactions, access customer data, and create accounts under your client. Treat API keys with the same care as database passwords.

Threat model

image

Rule 1: Never hard-code keys

Common mistake

Never embed API keys in source code, configuration files committed to version control, or client-side JavaScript.

Bad — hard-coded in source

# DO NOT DO THIS
API_KEY = "APIKEY-01KEW32V6YNV11T33XGDR7TGWC"

Good — loaded from environment

import os
API_KEY = os.environ["PARADISE_API_KEY"]

Rule 2: Use environment variables

Store API keys in environment variables. This keeps them out of your codebase and lets you use different keys per environment.

export PARADISE_API_KEY="your-api-key-here"
export PARADISE_BASE_URL="https://api.dev.paradisegateway.net"
.env files

If using .env files, add .env to your .gitignore immediately. Never commit .env files to version control.

.gitignore entry

# API keys and secrets
.env
.env.*
*.pem

Rule 3: Use a secrets manager in production

Environment variables are fine for development. In production, use a dedicated secrets manager.

ProviderServiceBenefit
AWSSecrets ManagerAutomatic rotation, IAM-based access, audit logging
AzureKey VaultRBAC, HSM-backed, versioned secrets
GCPSecret ManagerIAM policies, audit logging, automatic replication
HashiCorpVaultPlatform-agnostic, dynamic secrets, lease management

Example: AWS Secrets Manager

import boto3, json

def get_api_key() -> str:
    client = boto3.client("secretsmanager", region_name="us-east-1")
    secret = client.get_secret_value(SecretId="paradise-gateway/api-key")
    return json.loads(secret["SecretString"])["api_key"]

Rule 4: Rotate keys regularly

Generate new API keys periodically and when you suspect exposure.

Rotation steps

image

  1. Generate a new key using POST /v1/auth/keys with Basic Authentication.
  2. Update your secrets store with the new key.
  3. Deploy so your application picks up the new key.
  4. Verify by making a test API call.
  5. Monitor for any failures from the old key (indicates something still using it).
curl -s -X POST \
  https://api.dev.paradisegateway.net/v1/auth/keys \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic $(echo -n 'user@example.com:password' | base64)" \
  | jq -r '.key'

Rule 5: Limit key exposure

PracticeDetails
Server-side onlyNever send your API key to a browser or mobile app
Least privilegeUse separate keys for sandbox and production
One key per serviceIf multiple services call the API, each should have its own key
Network restrictionsIf possible, allow API calls only from known IP ranges
Audit accessMonitor who has access to your secrets manager

Rule 6: Detect and respond to leaks

Prevention

  • Add .env and secrets files to .gitignore
  • Use git hooks (e.g., pre-commit) to scan for secrets before committing
  • Use tools like gitleaks, trufflehog, or GitHub's secret scanning

If a key is compromised

  1. Rotate immediately — generate a new key via POST /v1/auth/keys.
  2. Deploy the new key to all services.
  3. Audit recent activity — check transaction logs for unauthorized transactions.
  4. Review access — determine how the key was exposed and close the gap.
  5. Report — if unauthorized transactions occurred, contact Paradise Gateway support with the correlation_id values.
Immediate action required

If you believe your production API key has been compromised, rotate it immediately and audit all transactions from the suspected exposure window.

Quick reference

DoDon't
Store keys in environment variables or secrets managerHard-code keys in source files
Add .env to .gitignoreCommit secrets to version control
Use different keys for sandbox and productionShare a single key across environments
Rotate keys on a scheduleUse the same key indefinitely
Keep keys server-side onlyExpose keys in client-side code
Log API calls (redact the key)Log full API key values

Further reading