Appearance
plexctl key
Synopsis
plexctl key is the operator surface for the per-Node mesh-key rotation control plane. The family currently exposes a single rotate leaf that targets two operations on /v1/nodes/{id}/keys:
POST /v1/nodes/{id}/keys/rotate— record a rotation trigger (default).GET /v1/nodes/{id}/keys/rotate/preview— fetch the impact preview without recording a new rotation (via--dry-run).
text
plexctl key rotate --node <uuid> # record a rotation
plexctl key rotate --node <uuid> --dry-run # preview onlyA rotation re-issues the pairwise PSK on every live edge attached to the addressed Node. The signing-key rotation surface is a distinct aggregate — see Relationship to signing-key rotation below for the boundary.
Subcommands
plexctl key rotate
The leaf branches on --dry-run:
- Default path — POSTs
/v1/nodes/{id}/keys/rotateand renders the resulting rotation handle (rotation_id,node_id,state,requested_at). The server is idempotent on a pending row, so a second POST for a Node whose rotation is already pending returns409 already_pending—exitCodeFormaps that branch to exit0so CI scripts can retry without false alarms. - Preview path (
--dry-run) — GETs/v1/nodes/{id}/keys/rotate/previewand renders an impact summary: the addressed Node, the rotating Peer, the affected peer count, thealready_pendingflag and the estimated duration. The detailed per-edge listing is collapsed into the count for the text renderer; operators who need the full edge list select--output jsonor--output yaml.
The leaf does not wrap non-2xx responses with fmt.Errorf — the shared output.DecodeProblem helper returns a typed *output.APIError so the dispatcher's exitCodeFor can route the 409 already_pending branch to its dedicated exit code.
Flags
plexctl key rotate
| Flag | Type | Required | Description |
|---|---|---|---|
--node | string (UUID) | yes | Node UUID whose mesh keys to rotate. |
--dry-run | bool | no | Fetch the rotation impact preview without recording a new trigger. |
Persistent flags inherited from root
--server, --profile, --token-file, --output. See ../plexctl.md for the canonical list.
Exit codes
See ../plexctl.md#exit-code-taxonomy for the inherited base table. The Problem.code branches that apply to this family:
| HTTP status | Problem.code | Exit code |
|---|---|---|
409 | already_pending | 0 — the trigger is idempotent; a re-trigger is a no-op. |
404 | node_not_found | 4 |
403 | rebac_denied | 77 |
Relationship to signing-key rotation
The plexctl key rotate family addresses the per-Node mesh-key that anchors WireGuard edges in a Domain mesh; the rotation is local to one Node and affects only the peers connected to that Node.
The plexctl signing family — introduced in the sibling Signing-Key Rotation work — addresses the per-Domain signing key that signs the event bus. The two rotations target different aggregates, use independent gRPC vs HTTP surfaces, and can run independently: rotating a Node's mesh key does not affect the Domain signing key and vice versa. The two CLI families exist side by side so an operator picks the verb (key rotate vs signing rotate) matching the aggregate they intend to touch.
Examples
Trigger a rotation
shell
export PLEXSPHERE_URL="${PLEXSPHERE_URL:-https://localhost:8080}"
plexctl key rotate \
--server "${PLEXSPHERE_URL}" \
--node 0190a8b8-b1c1-7b1b-8b1b-b1b1b1b1b1b1Preview the impact without recording
shell
plexctl key rotate \
--server "${PLEXSPHERE_URL}" \
--node 0190a8b8-b1c1-7b1b-8b1b-b1b1b1b1b1b1 \
--dry-run \
--output jsonCross-references
../../../api/openapi/plexsphere-v1.yaml../../../cmd/plexctl/commands/key.go../../../contexts/signing-rotation.md— the sibling rotation surface that targets the per-Domain signing key (a different aggregate; see Relationship to signing-key rotation above).