Rotate a secret everywhere without downtime

Short answer: the hard part of rotation is not generating a new value. It is finding every copy, changing them in one pass, restarting only what must restart, and knowing which consumers still hold the old value. Do it as a previewed plan: list every place, show who restarts, apply, then confirm each deployment picked it up. Below is a tested run with Dynv, and the cases where "no downtime" needs more than a tool.

Most rotations are put off because they hurt: the same AUTH_SECRET is in four services under two names, someone restarts one and forgets another, and half your sessions break. This page shows what a safe procedure looks like and what has to be true for it to be truly zero-downtime. The Dynv commands were run on 2026-11-01 against a local server with two services running under dynv run.

Step 1: preview the plan

Two services, api and worker, each with its own AUTH_SECRET, and (as in real life) different values. AUTH_SECRET is one of the names with a built-in generator preset, so no extra flag is needed:

$ dynv rotate AUTH_SECRET --dry-run
Rotate AUTH_SECRET (one new value everywhere), generated base64:32
  places (2):
    api
    worker
  note: AUTH_SECRET has 2 different values today; after this, every place shares one
  2 services change; 2 restart: api, worker
  2 writes, plan 2b19cad53f33

--dry-run writes nothing. It shows every place the secret lives, flags a value that differs between services, names which services restart, and fixes a plan id. Dynv also lists same-value copies under other names as suggested aliases, and templates that use the secret follow automatically; see the rotation guide.

Step 2: apply, and watch it land

$ dynv rotate AUTH_SECRET --yes
...
job yJE2eDH3jhWBz0J9: 2 writes done; AUTH_SECRET rotated
propagated to 2/2 live deployments

The last line is the point: finishing the writes and applying them in running deployments are separate steps, and the CLI waits (30 seconds by default, --wait to change it) for deployments to report. Each is one of applied, pending, refused or offline. The two services, which print a fingerprint (a short hash, never the value) of their secret:

api    pid 1599864  AUTH_SECRET fingerprint 586ca20d     <- before
dynv: v4 applied; changed: [AUTH_SECRET] -> restarting
api    pid 1601030  AUTH_SECRET fingerprint 4d811649     <- after
worker pid 1599892  AUTH_SECRET fingerprint b599f676
dynv: v4 applied; changed: [AUTH_SECRET] -> restarting
worker pid 1601038  AUTH_SECRET fingerprint 4d811649

Both now hold the same value (4d811649) and the generated value was never printed. To avoid a restart for a variable that can change live, mark it hot and read it with the SDK (how); a variable that applies by restart restarts exactly the services that use it, as above.

Same everywhere, or different per service

Mode Command Use when
Same value everywhere (default) dynv rotate AUTH_SECRET The services must agree: one service signs, another verifies; shared session keys
Unique per service dynv rotate AUTH_SECRET --unique Each service uses it privately; a leak of one should not expose the others

Run with --unique, each service got its own value under the same name (fingerprints 8f609c50 and 48ff1281). If a shared group provides the key, Dynv first gives each consumer its own copy, then removes the group’s, so no service is ever left without it.

For a value that comes from outside (a provider-issued API key), pipe it in so it never appears in argv: pbpaste | dynv rotate STRIPE_KEY --stdin (see the leaked-key playbook). Dynv rotates the copies; you still have to create the new key at the provider and revoke the old one.

“Zero downtime” depends on what the secret is

Restarting services is the easy half. The real question is what happens to things signed or encrypted with the old value.

  • A password or API key a client presents (database password, third-party API key): the consumer simply starts using the new one. Zero downtime needs both old and new to be valid at the provider during the switch: create the new credential first, deploy it, then revoke the old.
  • A secret that signs or encrypts things you keep (session cookies, JWTs, encrypted columns): changing it invalidates everything made with the old one. Users are logged out, tokens fail verification. The fix is overlap, so the app accepts the old value for verification while signing with the new one. Some frameworks support this natively: Django, for example, lets you “set a new SECRET_KEY and move the previous value to the beginning of SECRET_KEY_FALLBACKS,” then remove old values when you’re ready to expire sessions and similar tokens (Django settings). For JWTs, publish both keys in your key set.
  • A key several services verify: use three steps. First deploy the new value as an accepted verifier everywhere, then switch the signer, then retire the old.

Dynv’s planned rollover feature, a signed fallback value with an expiry that dynv run exposes to the app and retires itself, is coming soon. It would turn those three steps into one operation. Until it ships, do the overlap in your app or by staging two rotations as above.

A checklist you can reuse

  1. List every place the secret lives (services, shared groups, aliases, CI, laptops, other vaults).
  2. Decide: same value everywhere, or unique per service?
  3. Does anything verify or decrypt with the old value? If yes, set up overlap first.
  4. Create the new credential at the provider (if external); keep the old valid.
  5. Preview the plan; check the restart list against traffic and deploy windows.
  6. Apply; wait for “propagated to N/N”; investigate any refused or offline.
  7. Revoke the old credential at the provider; check usage of the old one drops to zero.
  8. Write down the date. Put a reminder on the calendar.

What this doesn’t do

  • It does not discover copies outside Dynv: a repository, a teammate’s .env, a CI provider’s secret store. Search those yourself.
  • It does not rotate at the provider or run provider-specific rotation hooks. You supply the new value or generate one for secrets you control.
  • Rotation is an admin write, done with a writer master token on your one writer machine. Scheduled, unattended rotation and rotation policies are not available yet.
  • offline deployments get the new state when they next connect; make sure the old credential stays valid until they do.

Facts last verified . Spotted an error? Tell us.

New here? Start here for the guides in a sensible order.