Skip to main content
Wildo.ai Coming soon

Service health

Replace credentials without an abrupt cutover

A timed overlap lets integrations adopt a new API key or OAuth client secret before the previous one stops working.

Old and new credentials overlap until the previous credential reaches its deadline.

Replace credentials without an abrupt cutover

Integrations need time to adopt a replacement secret. Wildo can keep the previous API key or OAuth client secret valid during a declared overlap window, then reject it after the deadline.

Rotation, regeneration and revocation have different purposes. A timed rotation supports a planned handover; revocation stops access. The authentication path checks the credential’s status and expiry as well as the previous secret’s window.

Example — Move an integration to its replacement key

An administrator rotates a credential with a handover deadline. The integration is updated while both secrets are accepted. After the deadline, requests using the previous secret fail while the new secret continues to work, provided the credential remains active and unexpired.

For engineers

Choose the right administration operation

OperationMeaning for the previous secret
RotateA declared invalidation date bounds its acceptance
RegenerateOpen-ended overlap until the next reissue
RevokeThe inactive status prevents authentication, including the previous secret
Extend expiryChanges the credential lifetime; it is distinct from the previous-secret deadline

Regeneration is not a response to a compromised secret. Choose revocation or a rotation deadline appropriate to the incident, and arrange how the legitimate consumer obtains its replacement through the authorized credential flow.

Perform a deliberate API-key handover

For an organization API key, use its declared ROTATE operation as an authorized organization administrator (or the administrator variant). This operation requires step-up authentication. The request and response fields below are selected from that operation’s schema:

requestDto: z.object({
  oldKeyInvalidationDate: z.date().min(new Date(), 'Invalidation date must be in the future or now').default(() => new Date()),
}),
customResponseDto: ApiKeyOrganizationSchema.extend({
  plainKey: z.string().min(1).isEphemeral(),
  oldKeyId: z.string(),
  oldKeyInvalidationDate: z.date(),
}),

Supply an explicit future oldKeyInvalidationDate when invoking the operation through the application’s administration interface or generated client. Omitting it means immediate cutover, not a default handover period. The schema fragment is a contract excerpt, not code to copy into an application or a guessed endpoint URL.

StepWhat to do and observe
PrepareSelect an active, unexpired key, choose a deadline and complete the required step-up
RotateSubmit the chosen deadline and capture the response’s one-time plainKey into the consumer’s secret store
SwitchUpdate the integration; verify the new secret works and the previous secret still works before the deadline
FinishVerify the previous secret is rejected after the deadline while the new one remains accepted

There is one previous-secret slot. Rotating again replaces that slot even if its earlier deadline has not passed. Finish one handover before beginning the next; never assume a chain of older secrets remains accepted. The returned plaintext is ephemeral and must not be logged or treated as a field that can be retrieved later.

This workflow concerns API-key records. Framework-managed platform secrets use coordinated provisioning and distribution, not this record’s overlap window.

Keep the two clocks distinct

These are the actual shared predicates used by machine authentication. The first checks the previous-secret slot; the second checks the lifetime of the credential itself.

export function isRotationGraceWindowOpen(invalidationDate?: Date | null): boolean {
  if (invalidationDate === null || invalidationDate === undefined) return true;
  return new Date(invalidationDate).getTime() > Date.now();
}

export function isCredentialExpired(expiresAt?: Date | null): boolean {
  if (expiresAt === null || expiresAt === undefined) return false;
  return new Date(expiresAt).getTime() <= Date.now();
}

The callers also require an active record. An open overlap cannot revive a revoked credential, and a delayed administrative status update cannot extend an expired credential’s actual access.

Follow persistence and authentication together

Reissue handlers write the previous-secret and grace fields through the repository’s server-managed field allow-list. The API-key request handlers, OAuth client handlers and OAuth token exchange use the shared date rules. The integration test for rotation persistence specifically checks that strict schema parsing preserves authorized injected fields.

A nightly expiry sweep now updates expired records through their expire operation. That bookkeeping can lag the clock, so authentication still checks expiresAt on every use. For a handover check, exercise both secrets before the deadline and the old secret after it; also check revocation independently. A single successful request with the new key does not establish the overlap behavior.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.