Skip to content

External OIDC sign-in

HTTP routes and behavior for external oidc sign-in.

Plex adds optional plex_available to GET /api/auth/status; clients treat an omitted field as false. The following routes return Cache-Control: no-store. Begin/exchange use the public sign-in rate limit; check/cancel have a separate 120/minute/IP budget and an attempt can poll Plex once every three seconds.

POST /api/auth/plex/begin # public: client (web/mobile), challenge, device_name, hardware_id -> flow, url, expires_at, interval
POST /api/auth/plex/check # public: flow + verifier -> pending, or complete + one-use code
POST /api/auth/plex/exchange # public: flow + code + verifier -> existing TokenResponse, linked, or MCP consent
POST /api/auth/plex/cancel # public: flow + verifier -> cancel pending attempt
POST /api/auth/plex/mcp/begin # public: client=mcp, challenge, validated oauth parameters
POST /api/auth/plex/link # authenticated: begin a link bound to this Cantinarr device/session
GET /api/auth/plex/identities # authenticated: numeric Plex identity and display information
DELETE /api/auth/plex/identities # authenticated: unlink; own account requires another permitted method
GET /api/admin/plex-auth # admin: enabled and auto_create, both default false
PUT /api/admin/plex-auth # admin: save enabled/auto_create; disable revokes Plex sessions/grants
GET /api/admin/plex-auth/candidates # admin: fresh review of existing Plex media-account links, including uncertainty
POST /api/admin/plex-auth/confirm # admin: explicit mappings [{user_id,plex_account_id}], freshly revalidated
GET /api/admin/users/{userID}/plex # admin: inspect identity
DELETE /api/admin/users/{userID}/plex # admin: unlink identity and revoke Plex sessions/grants

Plex attempts live in a capped in-memory store for at most ten minutes; completion and consent tickets last one minute. A private S256 verifier protects checks and exchange. Issuance rechecks configuration, identity, user and policy; account links additionally recheck the initiating session. Library-share removal is independent of an established login identity. Signup adopts only freshly proven accepted shares or ownership and never changes sharing. The media-access PIN result adds optional identity_state/identity_error; admin media-link and import results add plex_identity_error, separate from media-link errors. Plex imports refuse an existing username with username_conflict and direct the admin to explicit linking. Setup and policy.

GET /api/auth/status adds optional sso_available, sso_provider, sso_only, sso_origin and sso_error. Profile and user-list responses include sso_linked. In SSO-only mode /api/auth/connect returns { "sso_required": true, "continuation": "/api/auth/oidc/begin" } without consuming the invitation.

POST /api/auth/oidc/begin # public: client, S256 challenge, device name/id, optional invitation -> start_url + flow
GET /api/auth/oidc/start # public browser: one-use flow, sets browser-state cookie and redirects to provider
GET /api/auth/oidc/callback # public browser: verifies state/cookie, code, PKCE, ID token, nonce and required groups
POST /api/auth/oidc/exchange # public: handoff code + flow + client verifier -> TokenResponse or link/test/MCP result
POST /api/auth/oidc/mcp/begin # public: validated MCP authorize parameters plus client challenge
POST /api/auth/oidc/link # user: begin explicit account linking
GET /api/auth/oidc/identities # user: own linked identities (issuer, subject, created_at)
DELETE /api/auth/oidc/identities # user: unlink issuer; requires a permitted remaining local method
GET /api/admin/oidc # admin: configuration and exact callback; secret presence only
PUT /api/admin/oidc # admin: save configuration; optional write-only client_secret
POST /api/admin/oidc/validate # admin: discovery validation for saved configuration
POST /api/admin/oidc/test # admin: full provider sign-in test, without account writes
GET /api/admin/users/{userID}/oidc # admin: account's linked identities
DELETE /api/admin/users/{userID}/oidc # admin: unlink issuer and revoke associated SSO sessions/grants

Attempts last ten minutes and handoffs sixty seconds, are bounded in memory and single-use, and are invalidated by configuration saves. Provider traffic uses httpx.Internal() unless use_proxy explicitly selects httpx.External(). openid profile email are always requested. See OIDC setup for the configuration fields, invitation behavior, administrator recovery and limits of provider-side session revocation.

View the maintained source for this page.