Appearance
plexctl domain-idp
plexctl domain-idp is the CLI surface over Domain IdP bindings. It groups seven operations against /v1/admin/idp and /v1/admin/idp/{id}/status:
plexctl domain-idp create— POST a newIdPBindingRequest.plexctl domain-idp list— GET the optionally domain-filtered list of bindings.plexctl domain-idp get— GET a single binding by id.plexctl domain-idp update— PATCH a partial update of a binding's non-status fields.plexctl domain-idp delete— DELETE a binding by id.plexctl domain-idp enable— PATCH binding status toactive.plexctl domain-idp disable— PATCH binding status todeactivated.
Two safety contracts surface here:
- Secret masking on output. Response fields whose JSON key matches
(?i)secret|key|tokenare rewritten to***increate,list,get,update,enable, anddisableoutput. Pass--reveal-secretsto opt out; in that case a one-line warning is written to stderr and the invocation is audit-logged. The masking rule is the same one applied toconfig-redacted.jsoninside the support bundle so the two surfaces stay consistent. - File-only client secret on create.
--client-secretMUST be passed as@<path>to a file holding the secret; an inline literal is rejected at parse time. The file content is read once and trimmed of trailing whitespace before being marshalled into theIdPBindingRequest.client_secret_reffield. This keeps the secret out of shell history, audit logs, and process listings.
update performs a partial PATCH: only the flags explicitly set on the command line are forwarded in the request body, and an invocation that sets none of the mutable flags is rejected client-side as exit 2 rather than issuing an empty round-trip. Status transitions are intentionally absent from update — they go through the dedicated enable and disable subcommands which hit /v1/admin/idp/{id}/status.
Synopsis
shell
plexctl domain-idp create --domain-id <UUID> --client-id <ID> --client-secret @<PATH> \
--discovery-url <URL> --issuer <URL> --jit-policy allow|deny \
[--required-acr <VALUE>]... [--required-amr <VALUE>]... \
[--claim-mapping plexsphere_claim=idp_claim]...
plexctl domain-idp list [--domain-id <UUID>] [--reveal-secrets]
plexctl domain-idp get --id <UUID> [--reveal-secrets]
plexctl domain-idp update --id <UUID> [--jit-policy allow|deny] [--discovery-url <URL>] \
[--required-acr <VALUE>]... [--required-amr <VALUE>]... \
[--claim-mapping plexsphere_claim=idp_claim]... [--reveal-secrets]
plexctl domain-idp delete --id <UUID>
plexctl domain-idp enable --id <UUID>
plexctl domain-idp disable --id <UUID>Invocation
plexctl domain-idp create
POSTs an IdPBindingRequest to /v1/admin/idp. The CLI validates --jit-policy, parses --claim-mapping plexsphere_claim=idp_claim pairs, and rejects an inline literal --client-secret.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--domain-id | UUID | yes | — | Owning Domain UUID. |
--client-id | string | yes | — | OIDC client identifier. |
--client-secret | string (@<path>) | yes | — | File spec; inline literals rejected. The file's trimmed contents become client_secret_ref. |
--discovery-url | URL | yes | — | OIDC discovery document URL. |
--issuer | URL | yes | — | OIDC issuer URL. |
--jit-policy | enum | yes | — | Just-in-time provisioning policy: allow or deny. |
--required-acr | string (repeatable) | no | — | Required OIDC ACR value. May be passed multiple times. |
--required-amr | string (repeatable) | no | — | Required OIDC AMR value. May be passed multiple times. |
--claim-mapping | key=value (repeatable) | no | — | Map a plexsphere claim to an IdP claim, e.g. email=preferred_email. |
Persistent flags inherited from root: see plexctl.md. The root-level --reveal-secrets is honoured by create for masking fields on the IdPBindingResponse echoed back to stdout.
plexctl domain-idp list
GETs /v1/admin/idp. An optional --domain-id filter narrows the result set to a single Domain. The response masks (?i)secret|key|token fields unless --reveal-secrets is passed.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--domain-id | UUID | no | — | Optional Domain filter. |
Persistent flags inherited from root: see plexctl.md. The root-level --reveal-secrets controls whether secret-shaped fields are unmasked.
plexctl domain-idp get
GETs a single binding from /v1/admin/idp/{id}. The --id flag is parsed as a UUID before the wire call. The response masks (?i)secret|key|token fields unless --reveal-secrets is passed — the same masking applied by list and create.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--id | UUID | yes | — | Binding UUID. |
Persistent flags inherited from root: see plexctl.md. The root-level --reveal-secrets controls whether secret-shaped fields are unmasked.
plexctl domain-idp update
PATCHes a partial mutation of a binding's non-status fields against /v1/admin/idp/{id}. Only the flags explicitly set on the command line are forwarded in the IdPBindingPatchRequest body; an invocation that sets none of --jit-policy, --discovery-url, --required-acr, --required-amr, or --claim-mapping is rejected client-side as exit 2 rather than issuing an empty PATCH. Status is not a settable field — use enable and disable for status transitions. The echoed IdPBindingResponse masks secret-shaped fields unless --reveal-secrets is passed.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--id | UUID | yes | — | Binding UUID. |
--jit-policy | enum | no | — | Just-in-time provisioning policy: allow or deny. |
--discovery-url | URL | no | — | OIDC discovery document URL (absolute http/https). |
--required-acr | string (repeatable) | no | — | Required OIDC ACR value. Pass with no value to clear the list. |
--required-amr | string (repeatable) | no | — | Required OIDC AMR value. Pass with no value to clear the list. |
--claim-mapping | key=value (repeatable) | no | — | Map a plexsphere claim to an IdP claim, e.g. email=preferred_email. |
At least one of the five mutable flags must be set; an empty patch surfaces locally as exit 2 rather than a 400 empty-patch round-trip.
Persistent flags inherited from root: see plexctl.md. The root-level --reveal-secrets controls whether secret-shaped fields are unmasked.
plexctl domain-idp delete
DELETE /v1/admin/idp/{id}. The server returns 204 No Content on success.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--id | UUID | yes | — | Binding UUID. |
Persistent flags inherited from root: see plexctl.md.
plexctl domain-idp enable
PATCH /v1/admin/idp/{id}/status with { "status": "active" }.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--id | UUID | yes | — | Binding UUID. |
Persistent flags inherited from root: see plexctl.md.
plexctl domain-idp disable
PATCH /v1/admin/idp/{id}/status with { "status": "deactivated" }.
Flags
| Flag | Type | Required | Default | Description |
|---|---|---|---|---|
--id | UUID | yes | — | Binding UUID. |
Persistent flags inherited from root: see plexctl.md.
Exit codes
| Code | Reachable from | Meaning |
|---|---|---|
0 | every subcommand | Success. |
1 | every subcommand | Runtime / API error (non-2xx response, body parse error). |
2 | every subcommand | Flag-parse / misconfiguration (missing required flag, malformed UUID, inline --client-secret without @ prefix, unknown --jit-policy, malformed --claim-mapping, empty update patch). |
3 | every subcommand | Missing or insecure credentials. |
4 | every subcommand | Permission denied (HTTP 403 from the server). |
No domain-idp subcommand produces exit 64; the whole family is wired against the typed OpenAPI client.
Examples
Create a Domain IdP binding (file-only client secret)
shell
echo -n 'super-secret-from-okta' > /run/secrets/okta-client.secret
chmod 0400 /run/secrets/okta-client.secret
plexctl domain-idp create \
--server "${PLEXSPHERE_URL}" \
--domain-id 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a1 \
--client-id plexsphere-staging \
--client-secret @/run/secrets/okta-client.secret \
--discovery-url https://idp.example.com/.well-known/openid-configuration \
--issuer https://idp.example.com/ \
--jit-policy allow \
--required-acr urn:mace:incommon:iap:silver \
--required-amr mfa \
--claim-mapping email=preferred_email \
--claim-mapping groups=memberOfThe CLI rewrites client_secret_ref (and any other secret-shaped field) to *** on output. Pass --reveal-secrets to opt out.
List bindings for a Domain (default masked output)
shell
plexctl domain-idp list \
--server "${PLEXSPHERE_URL}" \
--domain-id 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a1 \
--output jsonjson
[
{
"id": "0190a8c1-...-a0a4",
"domain_id": "0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a1",
"client_id": "plexsphere-staging",
"client_secret_ref": "***",
"discovery_url": "https://idp.example.com/.well-known/openid-configuration",
"issuer": "https://idp.example.com/",
"jit_policy": "allow",
"status": "active"
}
]List bindings with secrets revealed (audit-logged)
shell
plexctl domain-idp list --reveal-secrets --domain-id 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a1
# stderr: WARNING: --reveal-secrets is set; sensitive fields will be printed verbatim. This invocation is audit-logged.Refusal: inline --client-secret (exit 2)
shell
plexctl domain-idp create \
--domain-id 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a1 \
--client-id plexsphere-staging \
--client-secret hunter2 \
--discovery-url https://idp.example.com/.well-known/openid-configuration \
--issuer https://idp.example.com/ \
--jit-policy allow
# stderr: plexctl: --client-secret must be @<path>; reading secrets from argv is forbidden
echo "exit=$?" # exit=2Get a single binding (default masked output)
shell
plexctl domain-idp get \
--server "${PLEXSPHERE_URL}" \
--id 0190a8c1-1234-7a0a-8a0a-a0a0a0a0a0a4 \
--output jsonjson
{
"id": "0190a8c1-1234-7a0a-8a0a-a0a0a0a0a0a4",
"domain_id": "0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a1",
"client_id": "plexsphere-staging",
"client_secret_ref": "***",
"discovery_url": "https://idp.example.com/.well-known/openid-configuration",
"issuer": "https://idp.example.com/",
"jit_policy": "allow",
"status": "active"
}Update a binding's JIT policy (partial PATCH)
shell
plexctl domain-idp update \
--server "${PLEXSPHERE_URL}" \
--id 0190a8c1-1234-7a0a-8a0a-a0a0a0a0a0a4 \
--jit-policy denyOnly jit_policy is forwarded in the PATCH body; every other field is untouched. An invocation that sets none of the mutable flags exits 2:
shell
plexctl domain-idp update --id 0190a8c1-1234-7a0a-8a0a-a0a0a0a0a0a4
# stderr: plexctl: domain-idp update: at least one of --jit-policy, --discovery-url, --required-acr, --required-amr, --claim-mapping must be set
echo "exit=$?" # exit=2Cross-references
../../../api/openapi/plexsphere-v1.yaml— OpenAPI 3.1 source of truth for/v1/admin/idpand/v1/admin/idp/{id}/status, plus theIdPBindingRequest,IdPBindingResponse, andIdPBindingStatusRequestschemas.../../contexts/identity/idp.md— bounded-context reference: claim-mapping rules, ACR/AMR step-up examples, JIT policy semantics, IdPBinding lifecycle.../../../cmd/plexctl/commands/domain_idp.go— source of truth for the masking regex ((?i)secret|key|token), the file-only--client-secretreader, the--reveal-secretswarning banner, and the partial-PATCH empty-patch guard onupdate.plexctl.md— root command reference (persistent flags, profile resolution, shared exit-code taxonomy).