Skip to main content
Back to engineering notes

Engineering note

Coordinating credential renewal under concurrency

Cache validity, per-upstream coordination and renewal failure handling.

APIs / Concurrency

Shared authentication state

The API separates vendor-specific authentication strategies from a shared token service. Strategies implement token acquisition and header attachment; the service provides caching and per-upstream renewal coordination.

Concurrent requests can observe the same cache miss. Without coordination, each request may acquire a new token, increasing upstream load and potentially invalidating credentials obtained by another request.

Coordinated cache misses

The documented service uses a per-API semaphore. Cache validity must be checked again after acquiring the semaphore because another request may have completed renewal while the caller waited. Coordination should cover credential acquisition rather than the entire vendor operation.

Renewal sequence

  1. Check cacheUse a valid, readable credential when available.
  2. Acquire API coordinationWait for the renewal lock associated with this upstream.
  3. Recheck cacheUse the value installed by an earlier caller if it is now valid.
  4. Acquire and publishObtain a replacement, protect the cached value and release coordination.
Reference sequence for coordinated renewal. Every acquired lock requires release on success, error and cancellation. Separate upstreams should not share a global renewal bottleneck.

Concurrent request example

Two callers, one upstream

  1. Requests A and B observe an empty cache.
  2. A acquires the upstream semaphore and starts token acquisition; B waits.
  3. A stores a usable token and releases the semaphore.
  4. B acquires the semaphore, rechecks the cache and uses the stored token without another acquisition.
Expected behaviour for a synthetic concurrency test. This sequence explains the coordination requirement; it is not a captured production trace.

A useful test holds the fake token endpoint behind a synchronisation signal, starts both callers and then releases the response. The assertion checks acquisition count and caller results. Timing delays alone do not reliably establish that requests overlapped.

Validity and protected cache values

Cache presence does not establish validity. Expiry, unreadable protected content and invalidation require defined outcomes. The authentication ADR documents protected cached values and eviction after decryption failure so renewal can recover.

Expiry policy should account for the credential's lifetime and the time needed to dispatch a request. Protection of cached content reduces plaintext retention; the application still needs access to the credential during use.

Cancellation and acquisition failure

A waiting request needs a cancellation path. The service must define whether acquisition belongs to the initiating caller or to a shared operation, and how one caller's cancellation affects others. This is a design requirement rather than a claim about an undocumented cancellation implementation.

Failed acquisition must release coordination and must not publish an unusable cache entry. A later request must be able to attempt recovery. The API can report a local credential-acquisition failure through its Problem Details contract before the vendor operation is dispatched.

An upstream rejection after dispatch is a separate case. Automatic token renewal and replay require operation-specific policy, particularly for requests whose side effects may already have occurred.

Recommended regression cases

  • Concurrent misses for one upstream cause one successful acquisition followed by cache reuse.
  • Renewal for one upstream does not block another upstream's independent acquisition.
  • Expired or unreadable entries trigger controlled renewal.
  • Failed acquisition releases the semaphore and permits a subsequent attempt.
  • Cancellation follows the documented ownership policy without leaking coordination state.

These cases are proposed verification requirements. The article is based on service and architecture documentation; it does not report a fresh execution of the project's authentication tests.

Related reading: proxy boundaries and the API case study.

Examples are generalised or synthetic and omit operational details and identifying information.

← All engineering notes