Skip to content

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 OAuth2 client_credentials or urn:ietf:params:oauth:grant-type:jwt-bearer grant against POST /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 displayed

There 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 text mode the marker line above is printed before the plaintext on stdout. In --output json / --output yaml mode the typed APITokenIssueResponse shape is rendered with the plaintext field still populated — the structured form is for scripting consumers and is also emitted exactly once.

Flags

FlagTypeRequiredDefaultDescription
--identity-refstringyesIdentity binding: user:<uuid> or service:<uuid>.
--env-prefixstringyesEnvironment segment encoded into the plaintext: dev, prod, or stage.
--ttldurationnoserver defaultToken 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

FlagTypeRequiredDefaultDescription
(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

FlagTypeRequiredDefaultDescription
--idUUIDyesAPI 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

FlagTypeRequiredDefaultDescription
--idUUIDyesAPI 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-secret is required for client_credentials and forbidden for urn:ietf:params:oauth:grant-type:jwt-bearer.
  • --client-assertion is required for the JWT-bearer grant and forbidden for client_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

FlagTypeRequiredDefaultDescription
--client-idstringyesServiceIdentity client identifier.
--grant-typestringyesclient_credentials or urn:ietf:params:oauth:grant-type:jwt-bearer.
--client-secretstringconditionalRequired for client_credentials; forbidden for the JWT-bearer grant.
--client-assertionstringconditionalRequired for the JWT-bearer grant; forbidden for client_credentials.
--scopestringnoSpace-delimited OAuth2 scope list.

Persistent flags inherited from root: see plexctl.md.

Exit codes

CodeReachable fromMeaning
0every subcommandSuccess.
1every subcommandRuntime / 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.
2every subcommandFlag-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.
3every subcommandMissing or insecure credentials (no token resolved, InsecureModeError).
4every subcommandPermission denied (HTTP 403 — caller lacks the relation needed to mint or rotate the requested token).
64noneFamily 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 24h

Output (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:00Z

Capture 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-a0a0a0a0a0a3

Output (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:00Z

Mint 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=1

The 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 the APITokenIssueRequest, APITokenIssueResponse, APITokenSummary, APITokenRotateResponse, ServiceTokenRequest, and ServiceTokenResponse schemas.
  • ../../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).