API Key Best Practices
This page consolidates PayKore's key security guidance in one place — useful for your own security team's review, or for setting policy across an engineering organisation using PayKore across multiple services.
Key hierarchy
Maintain separate keys for each environment: local development, staging, and production. Never reuse the same key across more than one of these.
The reasoning is straightforward: if a key used in a lower-trust environment (a developer's laptop, a staging server with looser access controls) is compromised, the blast radius is contained to that environment. Reusing a production key in staging means a staging breach becomes a production incident.
Maintain a rotation policy independent of any suspected compromise — rotate every 90 days as a baseline, and immediately on any suspected exposure (see the compromise playbook below). Treat scheduled rotation as routine hygiene, not a sign that something went wrong.
Storing keys securely
Guidance varies slightly by stack, but the underlying principle is constant: keys live in environment variables or a secrets manager, never in source code.
Node.js:
- Local development: use
dotenvto load a.envfile. Add.envto.gitignoreimmediately — before you ever populate it with a real key. - Production: use your hosting platform's environment variable system (Heroku Config Vars, Railway Variables, Vercel Environment Variables, AWS Secrets Manager, etc.). Never bake keys into a Docker image at build time — inject them at runtime.
Python:
- Local development: use
python-dotenv, the same pattern as Node'sdotenv. - Production: same platform-level environment variable guidance applies.
Mobile (React Native):
- Use publishable keys only in mobile code — never secret keys. See the React Native SDK guide for the full warning on why secret keys cannot live in a mobile bundle.
- Store non-secret configuration values (like a publishable key) in
.envusing Expo'sEXPO_PUBLIC_prefix convention, which makes explicit that these values are bundled into the client and visible to anyone who inspects the app.
A secret key (sk_live_* or sk_test_*) committed to a Git repository — even a private one — should be treated as compromised. Revoke it immediately, even if you believe access to the repository was tightly controlled. Git history is forever; a key removed in a later commit is still recoverable from history unless the repository itself is purged or recreated.
Key rotation procedure
Rotating a key should never require downtime if done in this order:
- Create a new key in the dashboard (Settings → API Keys → Create Key), labelled clearly (e.g.,
api-server-production-v2). - Deploy your server with the new key set in your environment variables, while the old key is still active.
- Verify the new key is working — check the Last Used column for the new key in the dashboard to confirm live traffic is flowing through it.
- Revoke the old key only after step 3 is confirmed.
Reversing steps 2 and 4 — revoking before confirming the new key is live — risks an outage if the new key wasn't actually picked up by your deployment for any reason (a stale environment cache, a missed service restart, etc.).
What to do if a key is compromised
Treat this as an incident, not a maintenance task. Work through these steps in order:
- Revoke the compromised key immediately in the dashboard. This is the single most important action — every minute the key remains active is a minute of continued exposure.
- Check transaction history for the time window the key was exposed, looking for any transactions you don't recognise or didn't initiate.
- Contact PayKore support with the approximate date and time the key was exposed, even if you haven't yet found evidence of misuse. Early notice gives support the best chance of catching anything unusual before it compounds.
- Generate a new key and redeploy following the rotation procedure above (though in this case, you can revoke the old key immediately rather than waiting to confirm the new one — it's already compromised, so there's no "safe old key" to keep running in parallel).
Do not wait to "confirm" a suspected compromise before revoking. The cost of revoking a key that turns out to have been safe is a few minutes of rotation work. The cost of leaving a genuinely compromised key active is unbounded. When in doubt, revoke first.
Rate limits as a security layer
Rate limits exist primarily for system stability, but they also function as an unintentional security backstop. If a key is stolen and used to drive automated, high-volume requests — for example, an attacker scripting repeated balance checks or transfer attempts — the rate limit acts as a circuit breaker, capping the damage rate even before you notice and revoke the key.
Monitor for unexpected 429 RATE_LIMIT_EXCEEDED responses in your own logs or alerting. A sudden spike in rate-limit errors on a key that normally operates well under its limit can be an early signal of misuse, worth investigating even before any other evidence of compromise surfaces.
Next steps
- Authentication → — The technical mechanics of sending and rotating keys.
- PII and Compliance → — Broader data handling obligations beyond key security.