Back to Blog
Three silver keys side by side, representing overlapping credential versions during a rotation

Secrets Rotation for Long-Running AI Workflows

9 min read

Secrets rotation often fails after the secret manager reports success. An AI worker may keep an old database password in a connection pool, a queued job may resume with credentials captured hours earlier, or a tool retry may reuse an authorization header. Immediate revocation then breaks valid work. Indefinite overlap leaves both credentials usable and conceals workers that never reloaded.

A safe rotation treats credential replacement as a rollout with four observable phases: issue, adopt, verify, and revoke. This guide shows how to run that sequence across long-running AI workflows, including in-flight calls, retries, stale pools, and rollback. The result is a bounded change that operators can prove, rather than a secret-manager update followed by hope.

Why secret-manager rotation is only the first step

A credential has more than one lifecycle. The secret manager controls issuance and storage. Applications control retrieval, caching, connection establishment, and use. External services control acceptance and revocation. Those timelines rarely change at the same instant.

AWS Secrets Manager recommends automatic rotation, least-privilege access, controlled caching, and private network access. Those controls reduce exposure, but the application still has to decide when to refresh a cached value and what to do with work already running. A successful rotation function proves that a new version exists. It does not prove that every process uses it.

Long-running AI workflows add several places where stale credentials survive:

  • A worker loads a secret during startup and stays warm for days.
  • A database pool authenticates each connection once, then keeps old sessions alive.
  • A workflow checkpoint serializes configuration that should have remained runtime-only.
  • A delayed retry reproduces headers from the original attempt.
  • A human approval pauses a run beyond the credential lifetime.
  • A fan-out step sends work to workers deployed at different times.
  • A tool client refreshes on a timer but never refreshes after an authentication failure.

Kubernetes documents that Secrets need encryption, least-privilege access, and careful distribution, and it recommends short-lived service account tokens instead of long-lived token Secrets where possible. It also notes that a container consuming a Secret through environment variables will not see an update without a restart. See the Kubernetes Secrets security and consumption guidance. A mounted or injected value is therefore part of the rollout design, not a passive configuration detail.

Prefer identity exchange over stored keys

The easiest static secret to rotate is the one you remove. For cloud and cross-platform access, prefer a workload identity that exchanges a trusted runtime identity for a short-lived credential. Google Cloud workload identity federation is one example: an external workload presents an identity assertion and receives short-lived Google Cloud credentials without a service-account key file.

The same design principle applies to internal tool gateways. Authenticate the workload to a broker, authorize the requested destination and action, then mint or attach a credential with a narrow audience and lifetime. The model should never receive the credential. The workflow state should store a credential reference and policy decision, not secret bytes.

Short-lived credentials change the failure mode. Instead of coordinating a permanent key swap across every worker, the platform renews or reissues credentials before expiry. HashiCorp Vault tokens and leases support lifetimes, renewal, and revocation, as described in the Vault token concepts documentation. Renewal still needs limits. A workflow must not keep a compromised identity alive forever by renewing it automatically.

Use static credentials only where the destination cannot accept federation, delegated authorization, or dynamic credentials. Put each remaining static secret on a migration list with an owner, rotation interval, consumer inventory, and retirement plan.

Model rotation as a state machine

Give each credential version a non-secret identifier such as db-payments:v42. Emit that identifier in security telemetry, but never emit the value. Track the state of the rollout separately from the provider's version labels.

A useful state machine has these phases:

  1. issued: the new credential exists, has the intended scope, and passes an isolated authentication test.
  2. available: authorized workers can resolve the new version, while the old version remains accepted.
  3. adopting: new executions use the new version and existing workers refresh according to policy.
  4. verified: adoption and outcome checks meet the rollout threshold.
  5. revoked: the destination rejects the old credential and the secret manager marks it retired.
  6. closed: negative-use checks find no old-version attempts after the allowed drain period.

Store timestamps, actor identity, target system, expected consumers, and evidence for every transition. Keep payloads and credential values out of this record. The OWASP Secrets Management Cheat Sheet covers the broader secret lifecycle, including creation, rotation, revocation, expiration, auditing, and dynamic secrets.

A rotation controller can enforce the sequence:

def rotate(binding, now):
    new = issuer.create(binding.scope, binding.audience)
    assert isolated_probe(new)

    registry.publish(binding.name, version=new.version)
    deadline = now + binding.max_overlap

    while clock.now() < deadline:
        adoption = telemetry.consumer_versions(binding.name)
        outcomes = telemetry.auth_outcomes(binding.name)

        if adoption.covers(binding.expected_consumers) and outcomes.new_version_ok():
            issuer.revoke(binding.previous_version)
            assert negative_probe(binding.previous_version)
            return RotationResult(status="closed", evidence=adoption.summary())

        if outcomes.new_version_failures_exceed(binding.failure_budget):
            registry.publish(binding.name, version=binding.previous_version)
            issuer.revoke(new.version)
            return RotationResult(status="rolled_back")

        clock.wait(binding.check_interval)

    return RotationResult(status="blocked", reason="adoption deadline exceeded")

The controller does not revoke on a timer alone. It requires consumer coverage and successful use of the new version. It also refuses indefinite overlap. A blocked rollout pages the credential owner and names the missing consumers.

Fetch at the execution boundary

Resolve credentials as late as practical. A queued job should carry credential_binding=payments-reader, not a password or access token. When a worker starts the tool call, it resolves the current version, checks its remaining lifetime against the call deadline, and builds the client.

Do not serialize authorization headers into checkpoints or retry messages. Persist a sanitized request intent, an idempotency key, and the binding name. Rebuild authentication for each attempt. This lets a retry move to the current credential without changing the business operation's identity.

Connection pools need explicit handling. Mark each pool with the credential version used to create it. When the registry advances, stop assigning new work to old-version connections. Let safe reads drain for a short period, but close old sessions before revocation if the destination validates credentials only at connection establishment. For write operations, preserve the operation's idempotency key when reconnecting so an uncertain network result does not become a duplicate side effect.

A client should refresh once after a clear authentication failure, then retry only if the operation is safe under its retry policy. Repeated refresh attempts can hide a revoked identity, broken scope, or destination outage. They can also multiply a non-idempotent action.

Handle in-flight work by action type

Rotation decisions should follow the side effect, not the model step.

For read-only calls, drain short operations during the overlap window. Cancel and restart calls whose remaining deadline exceeds the old credential's revocation deadline.

For idempotent writes, keep one operation key across reconnection. Query the destination by that key after an uncertain response before sending the write again.

For non-idempotent writes, do not replay automatically after an authentication or connection boundary. Reconcile the destination state, then resume from a durable checkpoint or send the case to a human exception queue.

For approved actions, bind approval to the business action and current record version, not to credential bytes. A fresh credential may execute the same approved action if policy and target state are unchanged. Require new approval if rotation coincides with a scope, destination, payload, or target-state change.

For leases, renew only while the workflow remains authorized and within its maximum execution duration. A paused workflow should release or let the lease expire. On resume, it should obtain a new lease and rerun policy checks.

Verify adoption before revocation

Count consumers from a declared inventory, not only from recent traffic. Quiet workers and disaster-recovery replicas may not emit a new-version event during a short window. Each expected consumer should acknowledge the active version through deployment state, a safe probe, or a controlled restart.

Track these signals by binding and version:

  • expected consumers and consumers observed on the new version
  • successful and failed authentication attempts
  • old-version attempts after the adoption deadline
  • active old-version connections and leases
  • queued jobs carrying forbidden secret material
  • refresh latency from registry publication to worker adoption
  • rollback and manual-exception counts

Do not log credentials, authorization headers, signed URLs, or raw identity assertions. Restrict the telemetry because version identifiers and destination names still reveal security architecture.

Before revocation, run a positive probe with the new version. After revocation, run a negative probe that expects the old version to fail. Then watch for old-version attempts through at least the maximum queue delay, retry delay, connection lifetime, and checkpoint pause that the workflow permits. Closing the ticket immediately after revocation misses dormant consumers.

Plan rollback without restoring indefinite exposure

Rollback means routing new work back to the prior credential while it remains inside the approved overlap window. It does not mean reactivating an old credential days later. If the old credential has been revoked, issue a fresh replacement and start a new rotation record.

Trigger rollback when the new version cannot authenticate, lacks required scope, causes a material error increase, or is unreachable from an expected environment. Do not roll back merely because one stale worker appears. Quarantine or restart that worker while healthy consumers continue adopting.

If compromise caused the rotation, skip ordinary overlap where possible. Revoke the exposed credential, stop affected workflows, reconcile uncertain side effects, and resume with a new credential only after containment. Availability is secondary to preventing continued unauthorized use.

Run a rotation drill

Test one low-risk binding before applying the process to a payment system or production database. Use this checklist:

  • Inventory every worker, queue, pool, scheduled job, failover environment, and manual runbook that consumes the binding.
  • Confirm no checkpoint, retry payload, trace, or log contains secret bytes.
  • Issue a narrowly scoped new version and test it outside normal traffic.
  • Publish the version and confirm new executions fetch it at call time.
  • Drain or rebuild old-version connection pools.
  • Pause one worker intentionally and prove the controller blocks revocation or isolates that worker according to policy.
  • Simulate an uncertain write and prove reconciliation prevents a duplicate.
  • Revoke the old version and confirm the negative probe fails.
  • Search for old-version attempts through the maximum dormancy window.
  • Record evidence, exceptions, owner, and next rotation date.

Start by selecting one credential binding and writing down its expected consumers, maximum overlap, longest legitimate pause, retry semantics, and revocation test. If those five values are unknown, the workflow is not ready for unattended rotation.

References

  1. AWS Secrets Manager best practices supports automatic rotation, least privilege, caching, and network controls.
  2. Google Cloud workload identity federation supports replacing service-account keys with short-lived federated access.
  3. HashiCorp Vault token concepts supports token lifetime, renewal, lease, and revocation behavior.
  4. OWASP Secrets Management Cheat Sheet supports lifecycle, auditing, rotation, revocation, and dynamic-secret practices.
  5. Kubernetes Secrets supports the Secret distribution, environment update, least-privilege, encryption, and short-lived-token guidance.

About Fire In Belly: Independent senior engineering from Tallinn, Estonia. We design and build AI workflow automation, internal tools, and custom software with the rotation and revocation controls described above, at published fixed prices. Schedule a call to discuss your next project.