Appearance
plexctl identity-tokens
plexctl identity-tokens is the CLI surface for psk-shaped API tokens bound to a User or ServiceIdentity, plus the OAuth2 service-token mint endpoint. It groups five operations against /v1/auth/tokens and /v1/auth/service/token:
plexctl identity-tokens issue— mint a new psk-shaped API token (POST /v1/auth/tokens).plexctl identity-tokens list— return the plaintext-free summary view (GET /v1/auth/tokens).plexctl identity-tokens delete— revoke a token in place (DELETE /v1/auth/tokens/{id}).plexctl identity-tokens rotate— rotate a token, returning the new plaintext exactly once (POST /v1/auth/tokens/{id}/rotate).plexctl identity-tokens issue-service— perform the OAuth2client_credentialsorurn:ietf:params:oauth:grant-type:jwt-bearergrant againstPOST /v1/auth/service/token.
The one-time-plaintext contract is pinned by the CLI's secret- rendering rules: issue and rotate print the plaintext exactly once on stdout, prefixed by the marker line:
text
# WARNING: this is the only time this plaintext will be displayedThere is no API surface on the server that returns the plaintext a second time. Capture it from the response and hand it to the consuming workload before the response leaves your terminal.
Synopsis
shell
plexctl identity-tokens issue --identity-ref user:<UUID>|service:<UUID> --env-prefix dev|prod|stage [--ttl <DURATION>]
plexctl identity-tokens list
plexctl identity-tokens delete --id <UUID>
plexctl identity-tokens rotate --id <UUID>
plexctl identity-tokens issue-service --client-id <ID> --grant-type client_credentials [--client-secret <SECRET>] [--scope <SCOPE>]
plexctl identity-tokens issue-service --client-id <ID> --grant-type urn:ietf:params:oauth:grant-type:jwt-bearer --client-assertion <JWT> [--scope <SCOPE>]Invocation
plexctl identity-tokens issue
Mints a psk-shaped API token for a User or ServiceIdentity. The --identity-ref value MUST be of the form user:<uuid> or service:<uuid>; the prefix and UUID are validated at flag-parse time so a malformed value never reaches the wire. --env-prefix is encoded literally into the plaintext.
One-time-plaintext banner. In
--output textmode the marker line above is printed before the plaintext on stdout. In--output json/--output yamlmode the typedAPITokenIssueResponseshape is rendered with theplaintextfield still populated — the structured form is for scripting consumers and is also emitted exactly once.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--identity-ref | string | yes | — | Identity binding: user:<uuid> or service:<uuid>. |
--env-prefix | string | yes | — | Environment segment encoded into the plaintext: dev, prod, or stage. |
--ttl | duration | no | server default | Token lifetime (e.g. 1h, 30m). |
Persistent flags inherited from root: see plexctl.md.
plexctl identity-tokens list
Returns the plaintext-free summary view for the authenticated principal. The plaintext field is intentionally absent from the server's APITokenSummary response shape: there is no API surface that returns plaintext after issue/rotate.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
| (none) | The list is scoped to the authenticated principal. |
Persistent flags inherited from root: see plexctl.md.
plexctl identity-tokens delete
Revokes a token in place. The server returns 204 No Content on success; the dispatcher maps that to exit 0.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--id | UUID | yes | — | API token UUID. |
Persistent flags inherited from root: see plexctl.md.
plexctl identity-tokens rotate
Rotates an API token and returns the new plaintext exactly once. Until rotation_deadline the rotated-from plaintext is still honoured; after the deadline only the rotated-to plaintext works. The same one-time-plaintext banner is printed in text mode.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--id | UUID | yes | — | API token UUID. |
Persistent flags inherited from root: see plexctl.md.
plexctl identity-tokens issue-service
Mints an OAuth2 service access token via either the client_credentials grant (presenting a client secret) or the urn:ietf:params:oauth:grant-type:jwt-bearer grant (presenting a signed JWT assertion). The CLI rejects mismatched flag combinations before issuing the request:
--client-secretis required forclient_credentialsand forbidden forurn:ietf:params:oauth:grant-type:jwt-bearer.--client-assertionis required for the JWT-bearer grant and forbidden forclient_credentials.
A mismatched combination is a plain runtime refusal and exits 1 (see the Exit codes table); only a genuinely malformed flag exits 2.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--client-id | string | yes | — | ServiceIdentity client identifier. |
--grant-type | string | yes | — | client_credentials or urn:ietf:params:oauth:grant-type:jwt-bearer. |
--client-secret | string | conditional | — | Required for client_credentials; forbidden for the JWT-bearer grant. |
--client-assertion | string | conditional | — | Required for the JWT-bearer grant; forbidden for client_credentials. |
--scope | string | no | — | Space-delimited OAuth2 scope list. |
Persistent flags inherited from root: see plexctl.md.
Exit codes
| Code | Reachable from | Meaning |
|---|---|---|
0 | every subcommand | Success. |
1 | every subcommand | Runtime / API error (server returned non-2xx, body parse error, network failure), and a grant-flag mismatch on issue-service — --client-secret/--client-assertion set against the wrong grant, or both set together. Those refusals are plain errors and fall through the dispatcher's default branch. |
2 | every subcommand | Flag-parse / misconfiguration: missing required flag (--identity-ref, --env-prefix, --id, --client-id, --grant-type), malformed UUID, an unknown --env-prefix or --grant-type enum value, or a malformed --identity-ref. |
3 | every subcommand | Missing or insecure credentials (no token resolved, InsecureModeError). |
4 | every subcommand | Permission denied (HTTP 403 — caller lacks the relation needed to mint or rotate the requested token). |
64 | none | Family is fully wired; not a deferred command. |
Examples
Issue a User-bound API token for the prod environment
shell
plexctl identity-tokens issue \
--server "${PLEXSPHERE_URL}" \
--identity-ref user:0190a8b9-1234-7a0a-8a0a-a0a0a0a0a0a2 \
--env-prefix prod \
--ttl 24hOutput (text mode):
text
# WARNING: this is the only time this plaintext will be displayed
psk_prod_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
id: 0190a8c0-1234-7a0a-8a0a-a0a0a0a0a0a3
env_prefix: prod
expires_at: 2026-05-02T10:00:00ZCapture the plaintext from the line below the banner; nothing on the server (or in any other CLI subcommand) ever returns it again.
Rotate a token, observing the rotation deadline
shell
plexctl identity-tokens rotate \
--server "${PLEXSPHERE_URL}" \
--id 0190a8c0-1234-7a0a-8a0a-a0a0a0a0a0a3Output (text mode):
text
# WARNING: this is the only time this plaintext will be displayed
psk_prod_yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
id: 0190a8c0-1234-7a0a-8a0a-a0a0a0a0a0a3
env_prefix: prod
expires_at: 2026-05-09T10:00:00Z
rotation_deadline: 2026-05-03T10:00:00ZMint a service access token (client_credentials grant)
shell
plexctl identity-tokens issue-service \
--server "${PLEXSPHERE_URL}" \
--client-id svc-deployer \
--grant-type client_credentials \
--client-secret "$(cat /run/secrets/svc-deployer.secret)" \
--scope "domain:read project:deploy"Refusal: mismatched grant flags (exit 1)
shell
plexctl identity-tokens issue-service \
--client-id svc-deployer \
--grant-type urn:ietf:params:oauth:grant-type:jwt-bearer \
--client-secret hunter2
# stderr: plexctl: --client-secret must not be set for grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
echo "exit=$?" # exit=1The grant-flag mismatch refusal is a plain errors.New — not a typed input-validation error — so the dispatcher routes it through its default branch to exit 1 rather than the exit 2 reserved for flag-parse failures. A genuinely malformed flag (an unknown --grant-type enum value, a missing required flag) still exits 2.
Cross-references
../../../api/openapi/plexsphere-v1.yaml— OpenAPI 3.1 source of truth for/v1/auth/tokens,/v1/auth/tokens/{id},/v1/auth/tokens/{id}/rotate, and/v1/auth/service/token, plus theAPITokenIssueRequest,APITokenIssueResponse,APITokenSummary,APITokenRotateResponse,ServiceTokenRequest, andServiceTokenResponseschemas.../../contexts/identity/idp.md— bounded-context reference: psk-shaped plaintext format, Argon2id hash storage, rotation policy, revocation contract.../../../cmd/plexctl/commands/identity_tokens.go— source of truth for the CLI dispatch, the one-time-plaintext banner constant, and the grant-type flag-validation rules.plexctl.md— root command reference (persistent flags, profile resolution, shared exit-code taxonomy).