How do I get the existing token in the first place? Do I still need to use the Traditional Token Authentication (Legacy) method initially to get an account token before I can use JWT Authentication? In which case it’s not really the “legacy” method.
Side note: I believe there is a typo in the last step of the JWT Authentication. The URL should be pointing to a Plex Media Server instead of to clients.plex.tv.
I hope, but I don’t think this is a Typo. The first step mentions that you need to “register the device with plex.tv”. Wouldn’t that mean that you are registering something on your Plex account rather than that specific Plex server?
The last step is using the JWT. You use the JWT to query your Plex server (that’s what the entire documentation page is about). /library/sections is a Plex Media Server endpoint to retrieve a list of the server’s libraries. It is an invalid clients.plex.tv endpoint.
The authentication token is/was the normal way to access your Plex server. However, in the API documentation, it is stated as “legacy”. So, using that “legacy” token as a way to issue a JWT token doesn’t really make much sense.
For now, this would work until that “legacy” token wouldn’t exist anymore and probably everything has been moved to JWT/JWK. But then the question still remains: how do you issue a new JWT from scratch?
Could be they are keeping that old token from the legacy only while deprecating legacy authentication itself as an option in favor of JWT. But would need someone from Plex to actually confirm that.
This is one of the questions I asked in the Fireside questions thread.
It is one thing to have the API documentation. What is most needed are code examples and step-by-step walk-throughs of John Doe getting and using JWT on his own PMS…
What are the most common pitfalls and how to get around these (catching errors)? Will this also work for managed users or only for server owners?
I found a place to generate ED25519 keys here: Private/Public Key Pair Generator. I then used the public key (and, getting an old “legacy” token mentioned here:
I did try to put something random in there and still got the same response. Am I missing something? Also, totally agree - it seems strange to have to still obtain a ”legacy” Plex token to start this process.
(edited to better show I’m in agreement with SwiftPanda’s original point, and leaving the rest to help others understand the flow not really explained in the docs)
I was just coming in to see if anyone had figured out the whole “you can’t get a token unless you already have a token” problem. Nice sample, @SwiftPanda16 , thanks for posting it. I’ll have to take a bit to digest that; doesn’t look like I can quite throw a few shell scripts and curl commands together to do things yet. Looks like I may also have to register a “device” that is “all the random utility scripts and things I’ll write” so that’s… interesting. Hmmm.
I’m really surprised that none of the current employees have answered in this thread so I guess I will. I don’t remember if last July’s layoffs affected all of those who worked on this as it did me. Here are my answers to the questions as best I remember them from when I worked on designing this system. Do note that I don’t have current knowledge so some of my answers may be out of date.
The token before the key problem:
Clients are added to an account in the same way as before and through that they are given a token (the legacy method)
When a client registers a JWK with plex.tv, the aforementioned token is removed from that device and all future auth is performed via the JWTs obtained by using the JWK
I presume there will eventually be a mechanism for a client to register with a JWK directly but it was not yet part of this system last I saw it.
This documentation is about auth with plex.tv and not PMS. It was likely added to the PMS documentation because it was the most ready to go to the public (after I had been writing nearly all of it over the past year). Ideally there would’ve been separate documentation for how clients talk to plex.tv and this section would go in there.
There was intent for this same auth to be used in talking to PMS with plex.tv communicating the JWK for a client to PMS and then the client uses the same JWK to obtain JWTs for each PMS going through the same flow to update them.
The big push for this was to reduce secrets that plex.tv needs to keep. It is computationally infeasible to obtain the private key from the JWK that plex.tv would store. So in the case of a suspected data breach (like recently), there would be no tokens associated with these clients stored and thus none to be exfiltrated. If a server-side JWK was suspected as exfiltrated, it could be simply invalidated and a new one generated. As a result all past JWTs are also invalidated but a client is expected to handle this situation by obtaining a new one and continuing on.
PMS was intended to be the first consumer of this API owing to the fact that removing its token from the plex.tv side leads to the greatest headache since signing in a PMS is still onerous in several setups. Though this may be slowed as the last 2 rounds of layoffs have reduced PMS from 5 developers to 2.
Limiting scopes of a token on plex.tv is a long-standing issue I have no idea if any progress has been made on it.
/library/sections is a Plex Media Server endpoint to retrieve a list of the server’s libraries. It is an invalid clients.plex.tv endpoint.
Yeah, this is new to me and was not in the documentation as last I saw it. I’m guessing a mistake from a rush job adding all of this to the PMS docs.
Where can get get Plex’s public key to verify the signature on the exchanged Plex JWT?
I took a guess from what I remember and it appears that https://clients.plex.tv/api/v2/auth/keys is what you need. I haven’t verified that any of the keys returned are the actual keys used to sign JWTs given to the client.
Note, this can return multiple keys with the keys going through a rotation with one key is the one that is currently signing and the others are keys that were rotated out of signing but their signed JWTs are still valid.
Thank you for your insights, @gbooker02 and I am sorry to hear that you’re no longer part of the dev team.
I would love to see more examples like the one from @SwiftPanda16 coming.
For example, I don’t have the slightest idea of how to register external code with PMS do add metadata to objects. Are web hooks the way to do it?
With @McWanke s comment in the Fireside threads, it seems that we’ll be left alone when it comes to basic examples of basic best-practices.
For me personally, it is hard to wrap my head around the JWT thing. If I want to use my PMS (without any virtualization things) to run a few web apps that communcate with the local PMS (see below if you want to know more)… The PMS itself can hardly register as a new device with plex.tv… therefore, I don’t know how to even start
Note: Besides adding metadata agents to new Plex libraries and common maintainance tasks for myself and others, I think of having a complete backup mechanism that does not work on the Plex DB level, but gets metadata and graphics from a PMS and stores it locally using Plex ID system as well as movie database IDs in order to have a way to get all your data restored on a new hardware PMS that’s using a different file and folder structure/locations.
You need to do for now at least, both the legacy way and JWT way. JWT needs an auth token from the legacy method and JWT should be more secure than legacy.
Hey @gbooker02! Thanks for these details. This is all correct!
I’ll add the details of how to get a JWT without ever having to get a legacy token. This is new and will be included in the PMS docs in the next update, along with the feedback from here.
You can use the strong Pin authentication flow and include the JWK of your device. For this flow, a nonce is not required in the signed JWT you will share in the end:
Now, exchange the Pin by the auth token, providing a valid signed JWT of your device:
GET https://clients.plex.tv/api/v2/pins/<pinID>?deviceJWT=<signedJWT>
Remember to include the "aud": "plex.tv" and "iss": "<clientIdentifier>" in the payload, and kid and alg in the headers of your JWT.
This new JWT will be used to authenticate with PMS and clients.plex.tv. It will be valid for 7 days and can be refreshed at any moment, including after it expires. Use POST https://clients.plex.tv/api/v2/auth/token to refresh it.