Files
hq/01-RESEARCH/016-how-a-credential-can-be-rotated/03-the-options.md
T
jochen 942ebe350f Research 016: survey how each provider can rotate a credential
Overlap as drafted in 0113 would have deleted consumer data: seven of
eight providers name the resource after the login and five drop it on
remove. Rotation is now undecided in 0113 and to-be 27, pending the
survey. Also: a requirement naming a seat resolves to its holder, a
person chooses among remaining candidates at assignment, the controller's
secrets are requirements of its definition, genesis seals to the
control-node key, and moving the vault or broker is break-glass.
2026-09-26 00:14:23 +02:00

76 lines
4.4 KiB
Markdown

# 03 — The options
Three mechanisms, weighed against [01](01-the-providers.md) and [02](02-the-readers.md).
## A. In place, as today
The vault makes a new value. Every applier re-applies it on the same login, which all eight
providers already do. Every reader is recreated by the host.
- **Works with:** every provider, unchanged. It is what `rotate` does now.
- **Costs:** a window per consumer, from the provider applying to the consumer being recreated. They
are on different machines, and nothing orders them. A reader whose machine is unreachable from the
mesh but still reaches its provider stays locked out until the mesh reaches it again.
- **Admin credentials:** the natural form. The provider module is the only party, and it has to
apply the new value with the old one anyway (finding 6).
## B. Two secrets on one login
The applier adds the new password beside the old one, readers move, and the old one is removed.
- **Works with:** redis natively, and gitea through tokens. **Not** with the other six, whose backends
hold one password per login (finding 4).
- **Verdict:** not a mechanism, a special case. Using it where it exists and something else
elsewhere is the "this way or that way" the design is trying to remove.
## C. Two logins per consumer, over one resource
The consumer has two logins derived by the mesh, and uses one at a time. The applier creates the other
with the new value and grants it the same rights over the consumer's resource. Readers move to it,
and then the old login is retired, which removes the login only, never the resource.
- **Works with:** every backend (finding 5), **after** each adapter changes:
- the resource is named after the consumer, not the login. Today the two are the same string (finding
7), so existing resources keep their names, the current login stays one of the two, and only the
second is new;
- both logins get the same rights, through a group role or its equivalent;
- *retire a login* and *remove the consumer* become two operations. Today they are one call, and
in five providers that call destroys data (finding 3). This is the whole of the danger, and it has
to be split, whatever else is chosen.
- **Costs:**
- seven adapters change;
- the harness learns the alternation and a confirmation per step;
- the second login's name must fit the tightest backend. That is 20 characters for a minio access
key ([ADR 0049](../../02-DECISIONS/0049-a-consumers-identity-fits-the-tightest-backend.md)), and
a suffix spends part of it;
- an MQTT client identifier stays unique per connection, so mosquitto needs the client id kept apart
from the login.
- **Gains:** no window. A reader that cannot be reached keeps a working login until it can.
- **Does not apply to** single-party secrets: admin credentials and a module's own secrets. There is
no second party to overlap with.
## Independent of the choice
- **Split remove.** Retiring a credential must never be able to destroy a consumer's data. That holds
under A too, because A's remove is the same call. A remove that drops a database should be a
separate, explicit operation, which [ADR 0030](../../02-DECISIONS/0030-data-outlives-the-mesh-that-declared-it.md)
already implies: data outlives the declaration.
- **Admin credentials are applied by their own provider**, using the old value. That happens in place
whichever mechanism consumers get. Where a backend takes the value only at first initialisation, the
file alone changes nothing, and rotation needs the provider's provisioner to run the change.
- **Classify the 22 readers** ([02](02-the-readers.md)) before relying on derived restarts.
## Recommendation
- **Consumer credentials: C**, because it is the only mechanism every backend supports, and it closes
the window instead of shortening it. Its prerequisite, separating the resource from the login and
retiring a login from removing a consumer, is worth doing on its own, because it removes a
data-loss path that exists today.
- **Single-party secrets (admin credentials, a module's own): A.** In place, applied by the provider
that holds them.
- **Until the adapters are changed, A stays** as `rotate` implements it, with its window stated. It is
not replaced by a mechanism the providers cannot yet carry.
This is two mechanisms, split by a property of the secret rather than by provider: whether it has one
party or two. Every provider is treated the same way for the same kind of secret.