OIDC Access Token (mine is opaque, but docs say it should be JWT)

The docs say (https://auth0.com/docs/api-auth/tutorials/verify-access-token):

If the Access Token you got from Auth0 is not a JWT but an opaque string (like kPoPMRYrCEoYO6s5 ), this means that your implementation follows our legacy pipeline. For info on how to use the latest and more secure pipeline, see our OIDC Conformant Authentication Adoption Guide.”

However, I have enabled “OIDC Conformant” in the advanced settings of my app and still I seem to get an opaque string as access token (the id token comes as JWT).

What do I have to do to get a the access token as JWT? I like to be fully OIDC conformant.

PS: This is part of the code I use to do the authentication:
auth0 = new auth0.WebAuth({
clientID: ‘redacted xxxxxxxx’,
domain: ‘redacted.auth0.com’,
responseType: ‘token id_token’,
redirectUri: this.prod?‘https://predacted.de/home’:'https://localhost:xxxxx/home’,
scope: ‘openid email profile’,
prompt: “login” // enforces window

Hi Heike. I’m afraid there’s an incorrect statement from the documentation, and I’ll make sure it gets corrected.
If you enabled the “OIDC Conformant” toggle in the application you are using the OIDC conformant pipeline, and yo have nothing to worry about. As for the access token formats:

When you do an authorize request with scope=openid, the resulting access token implicit audience will be the OIDC “userinfo” endpoint (i.e. https://{your_auth0_domain}/userinfo, which lets you get the OIDC user profile. In these cases, the access token format will (for now) be opaque. Note that this could change at any moment, and applications should not be concerned about this. This is a “contract” between the authorization server and the target API, client applications don’t need to understand the access token.
If you specify an audience, and the audience is a custom API you built, then you’ll get a JWT token, so that your custom API can read it and verify it.
Hope that clarifies the issue, I’ll send a PR to correct the documentation.

that was very clarifying. I am using the “userinfo” endpoint now to validate the (opaque) access token. Thanks!

that was very clarifying. I am using the “userinfo” endpoint now to validate the (opaque) access token.

At the risk of sounding overly academic or even pedantic, just want to point out that the /userinfo endpoint is to get information about the user. What kind of validation are you trying to achieve?
On the original token response you get an expires_in value (translated to expiresIn by Auth0.js I believe) that tells you for how long the access token is good for. But it’s the target API (the /userinfo endpoint in this case) who needs to validate the token really.

Thanks for pointing that out. My motivation was the following: The SPA sends the access token to the backend together with some information on changes to be made in the database. The backend then uses the access token to query user information. If this is successful, the access token was valid and the database change can be done. I am not defining scopes at this point. The approach protects me from having my backend accessed from someone without a valid access key. If this is all nonsense or if there is a better way, please let me know!

That’s definitely not a good way to protect the backend, as if you were to have other applications defined in your Auth0 tenant, any of those applications could obtain an OIDC access token that would prove valid in your backend.
You should define a backend API in Auth0 (in the API sections of the dashboard) representing your backend, and the SPA will need to ask for a token for that backend API by using the audience parameter indicating your API identifier.
When you indicate an audience, the issued access token is a JWT token. Your backend API will need to validate the token by validating the signature, audience, issuer and expiration time (all of our backend API quickstarts work like this if you want to take a look).

Good point. I only have one application currently but I will definitely an audience as proposed. I already have the php quickstart running so I should be able to copy some boilerplate code from there. I also started to use lock now which is very comfortable. Thanks for your effort, much appreciated

Hey there!

Sorry for such huge delay in response! We’re doing our best in providing you with best developer support experience out there, but sometimes our bandwidth is not enough comparing to the number of incoming questions.

Wanted to reach out to know if you still require further assistance?