"Generated token is too large" on some user profiles, but not others

I’ve been running into the “generated token is too large” error off and on for a while now - there’s a link in the documentation for id_token, but it was to the old community site and now just redirects to the homepage here.

I’m building a SPA that uses the Lock popup mode for authentication. I’m trying to link AWS keys to the id_token, and obviously more than one of them bumps up against the URL limit so instead of passing back the id_token I’ve been passing back an access_token that I can then use to access the id_token I enhanced in a rule. This works on some users, but not on others - for them I continue to get the error that the generated token is too large. I’ve lowered the scope on my Lock instance to just openid, as well as the audience to an API with minimal scope access. As the token being passed back is an API token that I’m using in lock.getUserInfo, I’m not sure why it’s failing on some users and not others. The only difference between the two is one has a username that’s 2 characters longer, and two small user_metadata claims that aren’t called at all.

Basically, here’s the authorization flow I’m using, I’m not certain if it’s correct:

  1. Open Lock with scope of ‘openid’ and audience of a minimal API
  2. Log in and run rule that attaches multiple AWS tokens to the id_token, as well as some app_metadata information (right now, all that information is the same for every user so that’s not the issue)
  3. Pass back access_token in the URL that allows the frontend to call getUserInfo, parse the hash manually in lock.resumeAuth and store the access_token
  4. Call getUserInfo using that access_token, to return the profile that we just attached the AWS tokens and app_metadata to
  5. Store tokens and data in application

Is this the correct way to go about this? Why is it failing on near identical profiles? Is there a way to pass back something smaller that will still work for my purposes?

It’s indeed intriguing this being caused on similar profiles, however, if both profiles are really near the limit of what is allowed to be included in the response then even the two character difference in the username can make a difference. You can update your question with the size of the ID token you received in the success case, but that would be mostly to satisfy curiosity because if you’re reaching the limit (even if only for some users) then you may need to tackle this differently.

In addition, you mention that you are including keys as custom claims so do take under consideration if the information you’re including in the tokens is okay to be disclosed to end-users because for a SPA the issued tokens will be available to end-users.

In conclusion, although you could technically find an alternative where you could add custom claims to ID tokens, adjust the authentication request (through response type and client application configuration) so that they would not be present in URL’s (avoiding the limitations) and then obtaining the actual custom claims through an additional request to the user information endpoint I’m hesitant to recommend that without first knowing more characteristics of the data being included in the tokens. In particular, confirming the data is not sensitive and can be disclosed and also the requirement for the data to be present on the tokens themselves and not just obtained on-demand in the API itself.

Thank you for your response! The access_token for the account that works is 799 characters, so I think you’re onto something with that.

I appreciate the security concerns about the tokens; we have considered that but the end-user requires AWS tokens to access the services and the only reason there are so many is specifically so we can restrict them very severely to only the resources that they should have access to out of the same concerns.

If we can store them somewhere else via our rule and then call them via the API, that would be fine as well.

Rereading this answer, I’m not sure if I was clear - we’re not receiving id_token at all in the URL. Only access_token, which we then use to pull the id_token later as we were aware that our excessive amount of AWS keys would be an issue with the hash parsing from the start.

Can you share the exact Lock config you use on your SPA to perform the authentication request so that I test under the same conditions? The reason I ask is that although the length of the access token you mention is somewhat significant it’s strange to hit the limit just because of that and I confess that I read it like both tokens were being issued and to be honest that would be the most simple explanation.

Sure, here are the options we use:

var options = {
    auth: {
        responseType: "token",
        autoParseHash: true,
        sso: true,
        params: {
            scope: 'openid',
            audience: 'API_URL_HERE'
        }
    },
    hashCleanup: true
  }

To try to minimize the scopes, the audience API URL has no scopes added to it at all. The url we receive back has an access_token value, an expiration time, a token type, and a state value.

Hi João,

I was wondering if you had time to look into this? Right now in our testing only one of the accounts work, and with MFA that makes it a little difficult to test anything else. Thanks!

@nbrooks sorry for not following with this before, it’s not forgotten but is indeed sitting in the backlog and this week I had not a big chance to go over the community part of my backlog. I anticipate some time to do this tomorrow.

I just reviewed that configuration and there’s a few things to point out. The use of audience in Lock implies the use of oidcConformant which implies cross-origin authentication and also means that popup mode is not supported. In addition, the audience parameter is set at the auth level so setting it at the params level is not supported. Finally, with that configuration Lock is using legacy flows which means that a responseType of token with an openid scope will still issue an ID token which I indeed obtained in my tests. I’ll add a few links to docs on a subsequent comment.

The audience option in Lock: Lock Configuration Options

The oidcConformant options in Lock (also check the linked cross-origin one in that section): Lock Configuration Options

Thank you for your response! I’m not sure how to structure it to return what I need in that case - we’ve tried appending it to the user’s metadata values, but to pass that through it needs to be appended to the id_token anyway as far as I can tell so it runs into the same issue. Is there an accepted way to return large values from Auth0 to a SPA using popup mode? Somewhere I could store it while inside a rule, that I can then access later?

Weirdly, having the audience value in the incorrect place results in returning an access_token instead of an id_token, but then runs into these errors.