gobridge

0002 — Credential rotation: build-first, commit-after-success

Status: accepted Date: 2026-07-03 Deciders: GoBridge core

Context

A running adapter holds a live connection built from credentials. When those credentials rotate — a refreshed SAS token, a new connection string — the adapter must move to the new material without dropping messages or leaving the connection in a half-updated state.

The naive path mutates the live config first, then rebuilds: set cfg.Connection = newCredentials, then tear down and rebuild the connection stack. If the rebuild fails (bad token, broker unreachable), the adapter is left holding config that names credentials it never managed to connect with. The old, working connection is gone and the recorded state lies about what is live.

Decision

Build-first applies to swap-capable transports — those that hold a client handle that can be rebuilt off to the side and swapped atomically (Azure Service Bus, SQS). For those, never mutate live connection config before the replacement stack has been built successfully: build first, commit the config only after the new stack stands up, and fence the session-mode commit against a concurrent rebuild with a generation counter.

Exclusive-connection transports that run a reconnect loop (paho MQTT, AMQP 1.0) cannot build-first without opening a second concurrent connection, which their single-session semantics forbid. They take the accepted alternative: commit the new material, then force a reconnect and let the retry loop reconverge.

Swap-capable client-handle transports

Reference implementation — Azure Service Bus rotation:

SQS follows the same build-first shape without sessions: ApplyCredentials rebuilds the SQS client with the new material and only then swaps it under the init lock (adapters/aws/transport/sqs/acl_credentials.go). A rebuild failure returns the error with the old client still live.

Exclusive-connection reconnect-loop transports

paho MQTT and AMQP 1.0 hold one session-scoped connection and reconnect through their own loop. They mutate live config under the session lock, then force a reconnect:

Known failure mode: a bad rotation strands the session reconnect-looping on the new (broken) material. There is no rollback — the previous credentials are already overwritten, so the session stays down until an operator pushes a corrected rotation.

Consequences

Rejected alternatives