Appearance
Log in with plexctl
plexctl login authenticates an operator with the RFC 8628 device grant and persists the bearer token (mode 0600) so later commands need no flags. plexctl whoami confirms the session.
Prerequisites
plexctlon$PATH— see Install plexctl.- A reachable control plane. For local work bring up the kind dev stack:
../../tutorials/set-up-local-plexsphere.md. - The
domain_idandidp_binding_id(both UUIDv7) you authenticate into — discover them as below.
Steps
Discover the IDs (local kind stack)
make dev seeds demo Domains and one active IdP binding each. Read the UUIDs straight from the dev Postgres StatefulSet:
shell
kubectl exec statefulset/postgres -- \
env PGPASSWORD=plexsphere psql -U plexsphere -d plexsphere -tAc \
"SELECT d.slug, d.id, b.id
FROM plexsphere.domains d
JOIN plexsphere.idp_bindings b
ON b.domain_id = d.id AND b.status = 'active'
ORDER BY d.slug"The three columns are the Domain slug, the domain_id, and the active idp_binding_id. Against a remote deployment, read them from plexctl domain list once any operator session exists.
Point plexctl at the server
shell
export PLEXSPHERE_URL="${PLEXSPHERE_URL:-https://localhost:8080}"Every command also accepts --server "${PLEXSPHERE_URL}" instead.
Run the device-code login
shell
plexctl login \
--domain-id <domain-uuid> \
--idp-binding-id <idp-binding-uuid>plexctl prints a verification URL and a user code, then polls until the device code is approved and writes the returned token to the default profile (override with --profile-name <name>). Missing either flag exits 2.
Approve the device code in a browser
Open the printed verification URL (the /v1/device?user_code=… link) in a browser. The control plane serves the approval page itself, so a bare stack needs no external dashboard:
- Signed out, the page starts the sign-in round-trip against the binding the device request resolved to and returns you to the same page once your identity provider authenticates you.
- Signed in, the page shows an Approve button. Approving flips the device request and the waiting
plexctlpoll receives its token.
If you reopen the link after approval (or after it expires), the page explains the request is no longer pending and points you back to plexctl login.
Verification
shell
plexctl whoami
# PRINCIPAL SUBJECT DOMAIN ACR AMR
# user … … - -A populated row proves the token reaches the API and resolves to a principal. 401/missing credentials exits 3.
Browser sign-in resolution
The browser flow posts to POST /v1/auth/sign-in. plexctl does not wrap this endpoint (it uses the device grant), so it is exercised with curl when reproducing resolution behaviour:
shell
curl -sS -X POST "${PLEXSPHERE_URL}/v1/auth/sign-in" \
-H 'content-type: application/json' \
-d '{"domain_id":"0192f2f6-b840-7000-a123-000000000001"}'Resolution branches
| Body | Outcome |
|---|---|
domain_id with exactly one active binding | redirect to that binding's IdP (e.g. a GitHub OIDC app) |
domain_id with multiple active bindings | 409 multiple-bindings |
domain_id with no active binding | 404 binding-not-found |
no domain_id and no resolvable host | 400 bad-request |
See also
../../reference/cli/plexctl/login.md— all flags and exit codes.../../contexts/identity/idp.md— the device-code surface andIdPBindingaggregate.