Secret rotation as a mesh verb and a tool: secret rotate <node> <module> <name>, offered by the mesh itself or mesh-vault #231

Closed
opened 2026-09-30 19:07:10 +00:00 by mesh-admin · 1 comment
Contributor

Asked by the operator on 2026-09-30 ("we should have a secret rotation mcp tool as well … provided by the mesh itself or the keyvault module ideally").

Today there is no rotation. When a value has to change, the only path is secret accept <node> <module> <name> with a value the operator (or an agent) generated by hand — done today for nodered's api-token after its value was printed by accident — or an unassign/assign, which drops the module. Provisioned pair credentials (postgres-database, mqtt-topic, influxdb-api, oidc-client, …) cannot be rotated at all short of deleting the grant.

Ask

  1. A controller verb secret rotate <node> <module> <name> for own-secrets: mint a fresh value the way the first mint did, seal it, and let the next push deliver it (files under restart-on restart their containers as usual). --all for a module; a rotated line in the module's log with the time and by whom, never the value.
  2. The same for a provision's pair credential: secret rotate <node> <module> <provision> asks the provider's provisioner to re-issue (the provisioner interface gains rotate, next to ensure/delete), then re-renders the consumer's bind file and secret. Provider first, consumer after, so the old credential works until the consumer has the new one.
  3. Exposed as a tool so an agent can do it through the mesh — on the mesh-controller seat's own tools (#166 made the mesh's verbs its seat's tools) or on mesh-vault, which holds the sealed values. Scoped like the rest: only for the node/module the caller may act on.
  4. Accepted values (an adopted instance's real password, ADR 0092/0113) are rotated only when the module can apply the new value itself (a provisioner or a rotate step in the manifest); otherwise the verb says the value is accepted and names what would have to change by hand.

Related: #228 (an accepted value that never applied), the nodered api-token incident in ace's MIGRATION-LOG (2026-09-30).

Asked by the operator on 2026-09-30 ("we should have a secret rotation mcp tool as well … provided by the mesh itself or the keyvault module ideally"). **Today** there is no rotation. When a value has to change, the only path is `secret accept <node> <module> <name>` with a value the operator (or an agent) generated by hand — done today for nodered's `api-token` after its value was printed by accident — or an unassign/assign, which drops the module. Provisioned pair credentials (postgres-database, mqtt-topic, influxdb-api, oidc-client, …) cannot be rotated at all short of deleting the grant. **Ask** 1. A controller verb `secret rotate <node> <module> <name>` for own-secrets: mint a fresh value the way the first mint did, seal it, and let the next push deliver it (files under `restart-on` restart their containers as usual). `--all` for a module; a `rotated` line in the module's log with the time and by whom, never the value. 2. The same for a provision's pair credential: `secret rotate <node> <module> <provision>` asks the provider's provisioner to re-issue (the provisioner interface gains `rotate`, next to `ensure`/`delete`), then re-renders the consumer's bind file and secret. Provider first, consumer after, so the old credential works until the consumer has the new one. 3. Exposed as a tool so an agent can do it through the mesh — on the mesh-controller seat's own tools (#166 made the mesh's verbs its seat's tools) or on mesh-vault, which holds the sealed values. Scoped like the rest: only for the node/module the caller may act on. 4. Accepted values (an adopted instance's real password, ADR 0092/0113) are rotated only when the module can apply the new value itself (a provisioner or a `rotate` step in the manifest); otherwise the verb says the value is accepted and names what would have to change by hand. Related: #228 (an accepted value that never applied), the nodered api-token incident in ace's MIGRATION-LOG (2026-09-30).
Author
Contributor

Recorded as hq issue 180 (04-ISSUES/180-a-modules-own-secret-cannot-be-rotated/00-report.md); the built half merged as mesh-controller #183, rolling out now.

  • secret rotate <node> <module> <name> for a module's own secret: made anew, sealed to the machine and the operator, the machine sent so the module restarts on it; logged with who and when, never the value.
  • An own secret declares how it is taken: {"path": …, "taken": "at-start"} or "taken": "applied". Undeclared → not rotated, refused with the word to write (issue 179 is what a rotation under software that never reads the value looks like). applied → refused until the staged form of ADR 0114 is built. Accepted values → refused as ADR 0113 says, with the way out.
  • rotate is a verb on the controller's seat with both shapes (pair credential by provision; own secret by node/module/name), so the console can ask. rotate <provision> for pair credentials already existed (design 13).
  • First catalogue adopter: nodered's api-token and admin (mesh-catalog, pending the roll-out). Then the token from the 2026-09-30 incident can be rotated through the console.

Open, in the record: the staged form for an applied credential (keycloak admin, database superusers) and re-issue through the provider's own code for pair credentials. Please close this tracker issue; hq's issues live in 04-ISSUES/.

Recorded as hq issue 180 (`04-ISSUES/180-a-modules-own-secret-cannot-be-rotated/00-report.md`); the built half merged as mesh-controller #183, rolling out now. - `secret rotate <node> <module> <name>` for a module's own secret: made anew, sealed to the machine and the operator, the machine sent so the module restarts on it; logged with who and when, never the value. - An own secret declares how it is taken: `{"path": …, "taken": "at-start"}` or `"taken": "applied"`. Undeclared → not rotated, refused with the word to write (issue 179 is what a rotation under software that never reads the value looks like). `applied` → refused until the staged form of ADR 0114 is built. Accepted values → refused as ADR 0113 says, with the way out. - `rotate` is a verb on the controller's seat with both shapes (pair credential by provision; own secret by node/module/name), so the console can ask. `rotate <provision>` for pair credentials already existed (design 13). - First catalogue adopter: nodered's `api-token` and `admin` (mesh-catalog, pending the roll-out). Then the token from the 2026-09-30 incident can be rotated through the console. Open, in the record: the staged form for an applied credential (keycloak admin, database superusers) and re-issue through the provider's own code for pair credentials. Please close this tracker issue; hq's issues live in `04-ISSUES/`.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/hq#231