Skip to content

plexctl ssh ​

Synopsis ​

plexctl ssh issues a one-time mediated SSH access session against a Resource, waits for the target Node to report the session's on-Node listener endpoint, then connects to that listener with its own SSH client. It POSTs an IssueSession request with kind=ssh, reads the session projection until the endpoint is reported, and dials the endpoint directly over the mesh; it does not open the browser attach WebSocket, and it needs no local ssh client.

text
plexctl ssh --project-id <uuid> --resource-id <uuid> --login-user <user> [flags] [-- command...]

Subcommands ​

plexctl ssh is a single-leaf command — there are no subcommands. It performs one operation: issue the session, then connect to its listener.

plexctl ssh ​

POSTs /v1/projects/{project_id}/sessions with a kind=ssh body and the requested login user, expecting 201 Created with an IssuedSession. The listener endpoint settles asynchronously (the target Node reports it after issuance), so plexctl reads GET /v1/projects/{project_id}/sessions/{session_id} and repeats that read every two seconds until the session carries a listener_endpoint or --listener-timeout elapses. A transport failure or a 5xx on one of those reads is retried on the next tick rather than ending the wait, and surfaces only if it is still failing when the timeout elapses; a 4xx ends the wait at once.

plexctl then dials the listener_endpoint (a bracketed IPv6 host such as [fd00::5]:2222 is accepted) and speaks SSH-2 to it. It logs in as --login-user with SSH password authentication, presenting the one-time session token as the password, so the token never appears on a command line, in an environment variable, or in a child process. The dial and the handshake are each bounded at ten seconds. The listener's host key is not pinned: the listener is authenticated by the mesh address it was reached on, which the control plane bound to the reporting Node. See the SSH session listener contract.

What runs on the connection depends on the arguments and on stdin:

  • With arguments after --, plexctl sends them as one exec request, joined with single spaces, and requests no terminal. No shell quoting is applied: a session with an allowed-command list accepts the command only when the joined string equals a list entry byte for byte.
  • Without a command, and with stdin a terminal, plexctl requests a terminal sized like the local one ($TERM, or xterm-256color), switches the local terminal to raw mode, forwards window resizes, and opens an interactive shell. A session with an allowed-command list refuses the shell.
  • Without a command, and with stdin piped, plexctl opens a shell with no terminal and feeds it stdin.

The token is not printed unless --reveal-secrets is set, in which case a one-line warning is written to stderr, followed by the token, before the connection is made, and the invocation is audit-logged.

--project-id and --resource-id are parsed as UUIDs locally; --login-user is required and an empty value exits 2.

Flags ​

plexctl ssh ​

FlagTypeRequiredDescription
--project-idstring (UUID)yesOwning Project UUID.
--resource-idstring (UUID)yesTarget Resource UUID.
--login-userstringyesSSH login user the mediated session connects as.
--ttl-secondsintnoRequested session TTL in seconds (server default when zero).
--listener-timeoutdurationnoHow long to wait for the target Node to report the session's listener endpoint (default 1m0s). 0 reads the session exactly once and fails if the endpoint is absent.
--reveal-secretsboolnoPrint the one-time session token to stderr (audit-logged). Inherits the root persistent flag when unset.

Persistent flags inherited from root ​

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

Exit codes ​

See ../plexctl.md#exit-code-taxonomy for the inherited base table. The cases that apply to this family:

CodeTrigger
0The mediated session was issued and the remote command or shell exited with status 0.
1Transport or API failure, a 5xx, a target Node that reported no listener endpoint before --listener-timeout elapsed, a listener that cannot be dialled (ssh: dial session listener: …), a refused login (ssh: handshake with the session listener: …), a listener that refuses the command or the shell, as one with an allowed-command list does (ssh: session: …), a remote command that exited non-zero (ssh: remote command exited with status <n>), or a session that closed without an exit status.
2Malformed --project-id / --resource-id UUID or a missing required flag.
3Missing or insecure credentials, a 401 Unauthorized, or a 401 step_up_required (re-authenticate before retrying).
4403 Forbidden.
77ReBAC denial (403 Forbidden with code == "rebac_denied").

Examples ​

Open a mediated SSH session as a login user ​

shell
export PLEXSPHERE_URL="${PLEXSPHERE_URL:-https://localhost:8080}"

plexctl ssh \
  --server      "${PLEXSPHERE_URL}" \
  --project-id  0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0c0 \
  --resource-id 0190a8b8-d3e3-7d3d-8d3d-d3d3d3d3d3d3 \
  --login-user  ops

Run one command on the Resource ​

The arguments after -- run as one remote command. The session's allowed-command list, when it has one, must contain the exact string systemctl status plexd.

shell
plexctl ssh \
  --server      "${PLEXSPHERE_URL}" \
  --project-id  0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0c0 \
  --resource-id 0190a8b8-d3e3-7d3d-8d3d-d3d3d3d3d3d3 \
  --login-user  ops \
  -- systemctl status plexd

Open a session with a bounded TTL and reveal the token ​

shell
plexctl ssh \
  --server         "${PLEXSPHERE_URL}" \
  --project-id     0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0c0 \
  --resource-id    0190a8b8-d3e3-7d3d-8d3d-d3d3d3d3d3d3 \
  --login-user     ops \
  --ttl-seconds    900 \
  --reveal-secrets

Cross-references ​