Skip to content

plexctl signing

Synopsis

plexctl signing is the operator surface for the per-scope signing-key rotation lifecycle. The family wraps two RPCs on the signer's gRPC SignerService:

  • OpenRotation — start a new rotation for a scope and return the transition window (opened_at, closes_at).
  • CloseRotation — finalise the rotation by retiring the old key and promoting the new key to active.
text
plexctl signing rotate --scope <scope> --new-key-id <id>
plexctl signing close  --scope <scope> --old <id> --new <id>

The signer speaks its own gRPC surface on a separate host:port from the plexsphere HTTP API, so the signing family does NOT consult the persistent --server flag. Use --signer-endpoint or the PLEXSPHERE_SIGNER_ENDPOINT environment variable instead.

This family addresses the per-Domain signing key that signs the mesh event bus. It is distinct from plexctl key rotate, which rotates the per-Node mesh key anchoring WireGuard edges; the two rotations target different aggregates and run independently.

Subcommands

plexctl signing rotate

Calls SignerService.OpenRotation to open a new rotation for a signing scope. The renderer prints the transition window (opened_at, closes_at) alongside the (scope, old_key_id, new_key_id) triple so an operator transcript names the keys involved without a follow-up query.

The leaf does not wrap the gRPC status error with fmt.Errorf — the dispatcher's exitCodeFor consumes the raw *status.Status and maps gRPC codes to exit codes per the family's contract.

plexctl signing close

Calls SignerService.CloseRotation to finalise a rotation. The server's CloseRotationResponse is empty by design, so the renderer echoes the (scope, old_key_id, new_key_id) triple back so the operator's local transcript still records which keys were involved.

Flags

plexctl signing rotate

FlagTypeRequiredDescription
--scopestringyesSigning scope — either platform or domain:<uuid>.
--new-key-idstringyesURL-safe identifier for the new key being introduced.
--signer-endpointstring (host:port)noSigner gRPC endpoint; overrides PLEXSPHERE_SIGNER_ENDPOINT.

plexctl signing close

FlagTypeRequiredDescription
--scopestringyesSigning scope — either platform or domain:<uuid>.
--oldstringyesKey id being retired.
--newstringyesKey id being promoted to active.
--signer-endpointstring (host:port)noSigner gRPC endpoint; overrides PLEXSPHERE_SIGNER_ENDPOINT.

Persistent flags inherited from root

--profile, --token-file, --output. See ../plexctl.md for the canonical list.

The persistent --server flag is not consumed by this family — it points at the plexsphere HTTP API, while signing-key rotation talks to the signer's gRPC surface. Set --signer-endpoint or PLEXSPHERE_SIGNER_ENDPOINT instead.

Exit codes

See ../plexctl.md#exit-code-taxonomy for the inherited base table. The gRPC status branches that apply to this family map as follows:

gRPC statusExit codeMeaning
InvalidArgument2A flag value was rejected by the signer's input validation.
FailedPrecondition1The signer refused the call (e.g. close against a non-open rotation, rotate against an already-open transition).
Unauthenticated / PermissionDenied77Signer denied the caller; check the deployment's auth posture.
Unavailable / dial failure1The signer endpoint did not accept the gRPC dial — host, port, or service-mesh sidecar misconfigured.

--scope, --new-key-id, --old, and --new are validated client-side before the dial step, so a missing required flag surfaces as exit 2 without a network round-trip.

Output

Both subcommands honour the inherited --output selector (text / json / yaml). The text renderer emits a single-row table; JSON and YAML emit a struct verbatim:

SubcommandText columns
rotateSCOPE, OLD_KEY_ID, NEW_KEY_ID, OPENED_AT, CLOSES_AT
closeSCOPE, OLD_KEY_ID, NEW_KEY_ID

Timestamps are emitted as RFC 3339-UTC so a forensic transcript reads identically regardless of the operator's local timezone.

Examples

Open a rotation for the platform scope

shell
export PLEXSPHERE_SIGNER_ENDPOINT="${PLEXSPHERE_SIGNER_ENDPOINT:-localhost:9443}"

plexctl signing rotate \
  --scope        platform \
  --new-key-id   platform-2026-05

Close a rotation for a Domain scope

shell
plexctl signing close \
  --scope  domain:0190a8b8-b1c1-7b1b-8b1b-b1b1b1b1b1b1 \
  --old    domain-2026-04 \
  --new    domain-2026-05

Pin a one-off endpoint

shell
plexctl signing rotate \
  --signer-endpoint signer.internal:9443 \
  --scope           platform \
  --new-key-id      platform-2026-06

Cross-references

  • ../../../api/openapi/plexsphere-v1.yaml — the plexsphere HTTP API spec; signing-key rotation lives on the gRPC surface and is not represented here.
  • ./key.md — sibling rotation family that targets the per-Node mesh key; pick plexctl signing for the per-Domain signing key, plexctl key for the per-Node mesh key.
  • ../../../contexts/signing-rotation.md — bounded-context reference for the signing-key rotation state machine and the two-phase fan-out posture the signer uses.