Rotating Paystack Secret Keys Without Downtime
Deploy your new key to all services first, then rotate on the Paystack dashboard. If you have multiple services, use a dual-key verification approach where your code tries the new key and falls back to the old one during the transition window. Always rotate during low-traffic hours and verify with a test transaction immediately after.
When to Rotate Your Keys
Key rotation is not something you do casually. It involves coordination, potential downtime risk, and verification. Rotate when you have a genuine reason:
- A team member with key access leaves. Anyone who had access to the Paystack dashboard or your environment variables could have copied the key.
- A suspected or confirmed leak. The key appeared in a git commit, a log file, a Slack message, or any other place it should not be. See what to do if your Paystack secret key leaked.
- Periodic rotation policy. Fintech companies and regulated businesses often require key rotation every 90 days regardless of incidents.
- Infrastructure migration. Moving to a new hosting provider or restructuring your services is a good time to rotate.
Do not rotate just because you can. Each rotation carries risk. But when any of the above conditions apply, rotate promptly.
The Timing Problem
Paystack key rotation works like this: you click "Generate New Keys" on the dashboard, and the old keys stop working immediately. The new keys are active from that moment.
This creates a timing problem. Between the moment you generate new keys and the moment your server starts using them, your server is sending requests with an invalid key. Every API call during that window fails with a 401 Unauthorized error. That means failed payment verifications, failed transaction initializations, and failed webhook signature checks.
The window can be as short as a few seconds (if you update an environment variable and your platform auto-restarts) or as long as several minutes (if you need to update multiple services, run a deployment pipeline, and wait for containers to restart).
The strategies below minimize or eliminate this window.
Strategy 1: Single-Service Rotation
If your Paystack integration runs as a single service (one server, one deployment), the simplest approach is to pre-stage the new key and swap it at the same time you rotate on the dashboard.
Step-by-Step
- Generate the new keys on the Paystack dashboard. Copy them immediately.
- Update the environment variable on your hosting platform with the new key value.
- Trigger a deployment or restart the service.
- Once the new deployment is live, verify with a test transaction.
The window of downtime is the time between step 1 (when the old key is invalidated) and step 3 (when the new deployment is live). On platforms like Railway that auto-restart on variable changes, this can be under 30 seconds. On Vercel, a redeployment takes 30 to 90 seconds.
Minimizing the Window
Some developers prefer to reverse the order: update the environment variable with the new key value first, deploy, and then rotate on Paystack. But this does not work because you do not have the new key until you generate it on the dashboard, which simultaneously invalidates the old one.
The practical approach: schedule the rotation during your lowest traffic hour. For most African businesses, this is between 2 AM and 5 AM local time. The probability of a payment attempt during a 30-second window at 3 AM is very low.
Strategy 2: Multi-Service Dual-Key Pattern
If your architecture has multiple services that use the Paystack key (a web server, a webhook handler, a background worker), you cannot update them all simultaneously. The dual-key pattern handles this.
Add support for a secondary key in your configuration:
// config.js
var primaryKey = process.env.PAYSTACK_SECRET_KEY;
var fallbackKey = process.env.PAYSTACK_SECRET_KEY_OLD;
function getPaystackHeaders() {
return {
Authorization: 'Bearer ' + primaryKey,
'Content-Type': 'application/json',
};
}
function getFallbackHeaders() {
if (!fallbackKey) return null;
return {
Authorization: 'Bearer ' + fallbackKey,
'Content-Type': 'application/json',
};
}
module.exports = { getPaystackHeaders, getFallbackHeaders };
In your API calls, try the primary key first and fall back:
var https = require('https');
var config = require('./config');
function verifyTransaction(reference, callback) {
var headers = config.getPaystackHeaders();
makeRequest(headers, reference, function(err, result) {
if (err && err.statusCode === 401) {
var fallback = config.getFallbackHeaders();
if (fallback) {
console.log('Primary key failed, trying fallback key');
makeRequest(fallback, reference, callback);
return;
}
}
callback(err, result);
});
}
function makeRequest(headers, reference, callback) {
var options = {
hostname: 'api.paystack.co',
path: '/transaction/verify/' + reference,
method: 'GET',
headers: headers,
};
var req = https.request(options, function(res) {
var data = '';
res.on('data', function(chunk) { data += chunk; });
res.on('end', function() {
if (res.statusCode === 401) {
callback({ statusCode: 401 }, null);
} else {
callback(null, JSON.parse(data));
}
});
});
req.end();
}
Rotation Sequence with Dual Keys
- Deploy the dual-key code to all services (with only the primary key set)
- Generate new keys on Paystack dashboard
- Set PAYSTACK_SECRET_KEY to the new key and PAYSTACK_SECRET_KEY_OLD to the old key on all services
- Deploy all services (they now try new key first, fall back to old)
- Once all services are running with the new key, remove PAYSTACK_SECRET_KEY_OLD
- Deploy again to clean up
This approach eliminates downtime because every service can use either key during the transition.
Rotating the Webhook Verification Secret
Your webhook handler uses the Paystack secret key to verify webhook signatures. When you rotate the secret key, the HMAC computation changes. Webhooks signed with the old key will fail verification if your handler only knows the new key.
This matters because Paystack may retry failed webhooks. A webhook that was sent and signed before rotation but retried after rotation will have a signature computed with the old key.
var crypto = require('crypto');
function verifyWebhookSignature(payload, signature) {
var keys = [process.env.PAYSTACK_SECRET_KEY];
// During rotation, also check the old key
if (process.env.PAYSTACK_SECRET_KEY_OLD) {
keys.push(process.env.PAYSTACK_SECRET_KEY_OLD);
}
for (var i = 0; i < keys.length; i++) {
var hash = crypto
.createHmac('sha512', keys[i])
.update(JSON.stringify(payload))
.digest('hex');
if (hash === signature) {
return true;
}
}
return false;
}
Accept signatures from either key during the rotation window. After 48 hours (enough time for all webhook retries to complete), remove the old key and revert to single-key verification.
Post-Rotation Verification
After rotating keys and deploying, verify everything works before going back to bed:
- Transaction initialization. Start a test payment through your frontend. Confirm the checkout popup appears.
- Transaction verification. Complete the test payment. Confirm your server successfully verifies it with the new key.
- Webhook delivery. Check your webhook logs. Confirm the charge.success webhook arrived and passed signature verification.
- API calls. If your application makes other API calls (list transactions, create transfers, manage subscriptions), test those too.
- Error logs. Check your application logs for any 401 errors in the minutes following rotation.
If any step fails, the most likely cause is a service that still has the old key. Check all services and redeploy the ones that were missed.
Documenting Rotations
Maintain a rotation log for compliance and incident response. Each entry should include:
- Date and time of rotation
- Reason for rotation (team change, suspected leak, periodic policy)
- Who performed the rotation
- Which environments were updated
- Verification results
- Duration of any downtime
Keep this log in a secure location (not in the git repository). A shared document in your team's password manager or a dedicated security log works well.
If your organization is subject to regulatory requirements (PCI DSS, NDPA, Kenya DPA), key rotation documentation may be required during audits. Having a clean log saves hours of investigation later.
Key Takeaways
- ✓Paystack invalidates old keys immediately when you generate new ones. The gap between rotation and deployment is a window of payment downtime.
- ✓Deploy the new key to your environment variables before rotating on the Paystack dashboard to minimize or eliminate downtime.
- ✓For multi-service architectures, use a dual-key pattern that tries the new key first and falls back to the old key during the transition.
- ✓Webhook signature verification uses the secret key. When you rotate keys, update the webhook verification logic to accept signatures from both old and new keys temporarily.
- ✓Always rotate during low-traffic hours and verify with a test transaction immediately after.
- ✓Document every rotation with the date, reason, and who performed it for your security audit trail.
Frequently Asked Questions
- Does Paystack support having two active keys at the same time?
- No. When you generate new keys, the old keys are invalidated immediately. The dual-key pattern described in this guide is a code-level approach that handles the transition, not a Paystack feature.
- How long does a rotation take from start to finish?
- For a single-service deployment on a fast platform like Railway or Vercel, the entire process takes 2 to 5 minutes. For a multi-service architecture with the dual-key pattern, plan for 15 to 30 minutes including verification.
- Do I need to rotate both test and live keys?
- Rotate based on the reason. If a team member who had access to live keys leaves, rotate the live keys. If the leak was test keys, rotate test keys. If your security policy requires periodic rotation, rotate both.
- What happens to in-flight transactions during rotation?
- Transactions that were already initialized before rotation will still complete on the Paystack side. However, your verification call will fail if it uses the old key. The transaction is not lost. You can verify it with the new key using the same reference.
- Should I rotate the public key too?
- Public keys (pk_*) are rotated together with secret keys when you generate new keys on the Paystack dashboard. Update the public key in your frontend environment variables as part of the same rotation process.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon