ADR 0094: a module may hold several secrets from one provider; issue 069 resolved; design 24 amended
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
---
|
||||
topic: the tiers
|
||||
status: accepted
|
||||
date: 2026-09-21
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
extends: 02-DECISIONS/0085-a-secret-is-a-provision.md
|
||||
---
|
||||
|
||||
# 94. A module may hold several secrets from one provider, each a pair of its own
|
||||
|
||||
## Context
|
||||
|
||||
[ADR 0085](0085-a-secret-is-a-provision.md) makes a module's own secret a provision: the module
|
||||
requires `secret` from the vault and reads the pair credential minted for that consumer↔vault
|
||||
pair. A pair has one credential, a module requires a provision once, and so a module received
|
||||
one value. Read against the catalogue, nine modules hold two or more secrets besides their
|
||||
broker account; seven of them hold genuinely independent values with independent lifetimes — a
|
||||
root certificate, its key and that key's password; an admin password beside an API token. None
|
||||
derives from another, so "one value, derivation the module's business" answers nothing
|
||||
([issue 069](../04-ISSUES/069-one-secret-provision-yields-one-value/00-report.md)).
|
||||
|
||||
## Considered Options
|
||||
|
||||
1. **One value per module; the module derives the rest.** Rejected: the values are independent.
|
||||
2. **Require the provision several times.** Rejected: `requires` is a list of names, and a
|
||||
requirement is matched by name everywhere.
|
||||
3. **The `secrets` map names several files under local names, and each local name is a pair
|
||||
credential of its own.** Adopted.
|
||||
|
||||
## Decision
|
||||
|
||||
A module's `secrets` entry for a requirement may be a path, as before, or an object of local
|
||||
names to paths. Each local name is its own pair credential, keyed on it beside the provision,
|
||||
the consumer node, the consumer module and the provider; its own file on the consumer, referred
|
||||
to as `${secret:<local name>}`; its own holder at the provider, named the consumer's identity
|
||||
with the local name after it; and rotated apart from the others. A local name may not be one of
|
||||
the module's own secrets or something it requires, so what a placeholder means is never
|
||||
ambiguous. The plain shape is unchanged, and every credential that exists is the one it was.
|
||||
|
||||
The holder's suffix is not a login any backend checks — a secret is not a login — so the
|
||||
identity limit that binds a database role or an access key does not apply to it.
|
||||
|
||||
## Consequences
|
||||
|
||||
The ten modules that could not move onto the vault can. What got harder: `rotate secret` for a
|
||||
consumer rotates every local name it holds from that provider; rotating one of several is a
|
||||
finer command than the mesh has, and waits for a case that needs it.
|
||||
|
||||
## How it is checked
|
||||
|
||||
Manifest tests read both shapes, write them back, and refuse a colliding or unusable local
|
||||
name. A resolver test asserts two local names are two needs, two files with two credentials,
|
||||
and two holders at the provider. An inventory test asserts two local names are two rows, that
|
||||
rotating one leaves the other, and that the provider is told both. The vault bed installs a
|
||||
consumer that keeps two secrets and asserts two values delivered, two holders in the vault's
|
||||
ledger, and both rotated by one command.
|
||||
|
||||
## References
|
||||
|
||||
- [issue 069](../04-ISSUES/069-one-secret-provision-yields-one-value/00-report.md)
|
||||
- [ADR 0085](0085-a-secret-is-a-provision.md), [ADR 0049](0049-a-consumers-identity-fits-the-tightest-backend.md)
|
||||
- [`03-DESIGN/01-to-be/24-the-secrets-vault.md`](../03-DESIGN/01-to-be/24-the-secrets-vault.md)
|
||||
@@ -113,6 +113,7 @@ python3 00-META/checks/index.py fail if stale
|
||||
- **0078** — [The store and the broker are ordinary modules](0078-the-store-and-broker-are-modules.md)
|
||||
- **0079** — [The foundation seats are named after their servers](0079-the-foundation-seats-are-named-after-their-servers.md)
|
||||
- **0092** — [An operator delivers a pair credential, and the mesh never replaces it](0092-an-operator-delivers-a-pair-credential.md)
|
||||
- **0094** — [A module may hold several secrets from one provider, each a pair of its own](0094-a-module-may-hold-several-secrets-from-one-provider.md)
|
||||
|
||||
### What runs on them, and how it gets there
|
||||
|
||||
|
||||
Reference in New Issue
Block a user