DEV Community

unifyport for UnifyPort

Posted on • Originally published at unifyport.ai

Zero-Downtime API Key Rotation: Why You Shouldn’t Call Rotate First

API key rotation sounds like a single operation:

Old key → Rotate → New key
Enter fullscreen mode Exit fullscreen mode

In a production system, that sequence can cause an authentication outage.

The problem is not generating the new credential. The problem is that your web servers, background workers, scheduled jobs, and operational scripts do not all start using it at the same moment.

With the UnifyPort API, calling:

POST /v1/api-keys/{key_id}/rotate
Enter fullscreen mode Exit fullscreen mode

invalidates the old key immediately.

That behavior is useful during a credential leak, but it is usually the wrong starting point for an ordinary rolling deployment.

For zero-downtime rotation, use a controlled overlap:

Create → Store → Test → Deploy → Verify → Deactivate
Enter fullscreen mode Exit fullscreen mode

The two rotation strategies

Strategy Old key Best use case
Call the rotate endpoint Invalidated immediately Suspected credential exposure or coordinated maintenance
Create a second key, then deactivate the old one Remains active during deployment Normal rolling deployments

The distinction matters because a production deployment rarely changes every process atomically.

During a rolling release, some instances may already use the new configuration while others are still completing requests with the previous configuration. If the old key is revoked too early, otherwise healthy requests begin failing with:

401 invalid_api_key
Enter fullscreen mode Exit fullscreen mode

A safer mental model

Treat credential rotation as a migration, not a single API call.

The application moves through four states:

State 1: Old key active
State 2: Old and new keys active
State 3: All callers use the new key
State 4: Old key inactive
Enter fullscreen mode Exit fullscreen mode

State 2 is the overlap window that protects availability.

Keep that window short, but do not eliminate it until you have evidence that every caller has migrated.

Step 1: Inventory every API caller

Before creating or revoking anything, identify every component that sends X-Api-Key to the API.

Typical callers include:

  • public web and API services;
  • queue consumers;
  • background workers;
  • scheduled jobs;
  • webhook handlers that send replies;
  • health checks;
  • production support scripts;
  • regional deployments.

Do not confuse an API key with a webhook signing_secret.

They protect different directions of communication:

Credential Purpose
X-Api-Key Authenticates requests your application sends to the REST API
signing_secret Verifies webhook requests delivered to your endpoint

Rotating one does not rotate the other.

You can inspect existing API key records with:

curl https://api.unifyport.ai/v1/api-keys \
  -H "X-Api-Key: $CURRENT_UNIFYPORT_API_KEY"
Enter fullscreen mode Exit fullscreen mode

The response includes metadata such as:

  • id
  • name
  • key_prefix
  • status

It does not return the complete secret.

Step 2: Create a second active key

For a normal deployment, create another key instead of rotating the existing one:

curl -X POST https://api.unifyport.ai/v1/api-keys \
  -H "X-Api-Key: $CURRENT_UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production 2026-08 cutover",
    "prefix": "dk_live"
  }'
Enter fullscreen mode Exit fullscreen mode

A successful 201 response returns:

  • key metadata under data.key;
  • the complete new secret under data.api_key.

The full value is returned only once.

Capture it directly into your approved secret-management system. Do not:

  • print it in deployment logs;
  • paste it into a ticket;
  • send it through chat;
  • commit it to the repository;
  • assume it can be retrieved from the list endpoint later.

If the value is lost before deployment, create another key and deactivate the unused record.

A key prefix is metadata, not enough information to recover the secret.

Step 3: Test the new key before deployment

Before changing application configuration, prove that the new credential can authenticate successfully.

Use a read-only endpoint:

curl https://api.unifyport.ai/v1/workspace \
  -H "X-Api-Key: $NEW_UNIFYPORT_API_KEY"
Enter fullscreen mode Exit fullscreen mode

A successful response confirms that the key resolves to the expected workspace.

This is only the first verification gate. It proves that the credential works, but it does not prove that every application instance has loaded it.

Keep the old key active and deploy the new secret through your normal configuration system.

Step 4: Roll out and verify every caller

Update each caller in controlled batches.

For example:

1. Web/API instances
2. Queue consumers
3. Background workers
4. Scheduled jobs
5. Operational scripts
Enter fullscreen mode Exit fullscreen mode

For each group, verify:

  • the deployment completed;
  • processes restarted or reloaded their configuration;
  • authenticated requests succeed;
  • no instance still references the old secret;
  • scheduled jobs will load the new value on their next run;
  • emergency scripts have also been updated.

Do not assume the migration is complete just because one HTTP request succeeded.

Also avoid relying on metadata that the API does not provide. If the key-list response does not expose per-key last-used analytics, it cannot prove that the old key is unused.

Use deployment state and application-side request results as your evidence.

A simple internal checklist might look like this:

const rollout = {
  web: "verified",
  workers: "verified",
  scheduledJobs: "verified",
  supportTools: "verified",
};

const safeToDeactivate = Object.values(rollout).every(
  (status) => status === "verified",
);
Enter fullscreen mode Exit fullscreen mode

The exact implementation is less important than making the verification state explicit.

Step 5: Deactivate the old key

After every caller is confirmed on the new credential, deactivate the old record using the new key:

curl -X PATCH \
  "https://api.unifyport.ai/v1/api-keys/$OLD_KEY_ID" \
  -H "X-Api-Key: $NEW_UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"inactive"}'
Enter fullscreen mode Exit fullscreen mode

The documented API key states are:

active
inactive
Enter fullscreen mode Exit fullscreen mode

After deactivation, make one controlled read-only request with the old credential and confirm that it returns:

401 invalid_api_key
Enter fullscreen mode Exit fullscreen mode

Do not use a real customer request or production job as the test.

Finally, remove the retired secret from:

  • deployment configuration;
  • CI/CD variables;
  • local environment files;
  • temporary migration files;
  • operational scripts.

The change record should contain non-secret metadata only, such as the key ID, key name, owner, status, deployment version, and cutover time.

When immediate rotation is the right choice

The dedicated rotate endpoint is appropriate when immediate invalidation is the requirement.

Examples include:

  • the old credential may have leaked;
  • it appeared in a log or repository;
  • an unauthorized person may have accessed it;
  • all callers can switch together during a maintenance window.

The incident-response sequence is different:

1. Stop or isolate callers using the old key
2. Call the rotate endpoint
3. Capture the new secret once
4. Update every credential consumer
5. Restore traffic
6. Verify authentication
Enter fullscreen mode Exit fullscreen mode

In this situation, revocation speed is more important than continuous availability.

Do not keep a potentially compromised credential active merely to preserve an overlap window.

The trade-off of overlapping keys

A zero-downtime migration briefly leaves two valid credentials active.

That creates a larger credential surface for a limited period, so the overlap should be:

  • planned;
  • monitored;
  • access-controlled;
  • as short as operationally practical.

This is a deliberate availability-versus-exposure trade-off.

For a normal rolling deployment, the short overlap prevents avoidable outages. For a security incident, immediate revocation usually takes priority.

Rotation checklist

Before deactivating the old key, confirm all of the following:

  • [ ] Every API caller has been identified.
  • [ ] A second active key has been created.
  • [ ] The one-time secret is stored securely.
  • [ ] GET /v1/workspace succeeds with the new key.
  • [ ] Web and API instances use the new key.
  • [ ] Workers and queue consumers use the new key.
  • [ ] Scheduled jobs will load the new key.
  • [ ] Operational scripts have been updated.
  • [ ] Authenticated production paths have been verified.
  • [ ] The old key has been changed to inactive.
  • [ ] A controlled request confirms the old key is rejected.
  • [ ] The retired value has been removed from configuration.

Takeaway

An API named rotate does not necessarily provide a zero-downtime migration.

Always check the endpoint’s actual contract.

If rotation invalidates the old credential immediately, use it for urgent revocation or a coordinated cutover.

For an ordinary rolling deployment, the safer sequence is:

Create a second key
        ↓
Store it securely
        ↓
Test it
        ↓
Deploy it everywhere
        ↓
Verify every caller
        ↓
Deactivate the old key
Enter fullscreen mode Exit fullscreen mode

The key idea is simple: prove that the new credential is in use before removing the old one.

References


This article was adapted from an original UnifyPort technical guide with AI-assisted editing.

Top comments (0)