Persistent session / user management without auth-gating

Edit: Persistent session / user management without auth-gating - #8 by JD_2020

This is the most updated version of this function, as it had some imperfections. It also demonstrates more clearly the advantages to this method.

Hey all,

I’ve been trying to find the ideal user experience for Web Requests, and in the process have developed a fairly reliable method for tracking user state across ephemeral user ID resets, which while not 100%, can be pretty darn close.


    ephemeral_user_id = request.headers.get('Openai-Ephemeral-User-Id', 'unknown')
    conversation_id = request.headers.get('Openai-Conversation-Id', 'unknown')

    # Check if a unique user object exists for the given ephemeral_user_id or conversation_id
    async with unique_users_lock:
        user = None
        for unique_user in unique_users.values():
            if ephemeral_user_id in unique_user.ephemeral_user_ids or conversation_id in unique_user.conversation_ids:
                user = unique_user
                break

        # If no matching user is found, create a new one
        if user is None:
            user = UniqueUser(conversation_id, ephemeral_user_id)
            unique_users[ephemeral_user_id] = user
        else:
            # Update the user's ephemeral_user_ids and conversation_ids
            user.ephemeral_user_ids.add(ephemeral_user_id)
            user.conversation_ids.add(conversation_id)
            user.update_last_seen()

        # Check for any other unique users with the same conversation_id or ephemeral_user_id and merge them
        keys_to_remove = []
        for key, unique_user in unique_users.items():
            if user is not unique_user and (conversation_id in unique_user.conversation_ids or ephemeral_user_id in unique_user.ephemeral_user_ids):
                user.merge(unique_user)
                # Mark the merged user for removal from the unique_users dictionary
                keys_to_remove.append(key)

        # Remove the merged users from the unique_users dictionary
        for key in keys_to_remove:
            del unique_users[key]

It assumes a User object containing a list of ephemeral user ID’s and conversation ID’s that are associated with that unique user. And each time the ephemeral changes, assuming it changes and you’re still working with any o your conversations in your recent history, it will find the overlap and consolidate your various identifiers user an up-to-date Unique User object.

The edge case of all edge cases is your user comes back to ChatGPT, gets a new Ephemeral assigned, starts a new Conversation, and never returns. In this instance, you may technically have a duplicate user.

1 Like

Why not auth gate? It’s the way things are supposed to be done, and you don’t have to deal with hacky code.

Oh man, where to begin? :stuck_out_tongue:

For starters, from a user experience standpoint, auth gating the user before they even have a chance to try your thing out is a pretty poor experience. You especially need to consider, your Plugin users are already auth-gated once, are paying $20/mo already, and are already super aware of the whole “AI having my data is super scary…” – adding a random extra login page to some random site that has no reputation or easily established business entity behind it is a huge, huge attrition point for user attachment. More so than any other web-app scenario.

This is principally why Web Requests doesn’t OAuth at the start.

And believe me, if I could initiate an OAuth flow mid-chat, after installation, I’d totally be there. But we can’t. And even still, there are reasons for this passive tracking. You may want to rate-limit users based on usage over time. You may want to reward the most loyal users – even the ones that don’t Authenticate.

At the very least, you may want to use anonymized insights from that usage to inform strategic business decisions going forward, or even for valuable academic research purposes.

2 Likes

And the 2FA enabled…(For users who want to OAuth a plugin)

I believe OpenAI could supply an access_token to the plugin. This would allow the plugin to obtain some basic user information(Such as openid or something?) from this temporary access_token.

Here’s the updated outline for a python function that will manage sessions and unique user records with no auth gating. It involves mapping ephemeral user id’s to conversation id’s and merging persistent user objects that you maintain in your backend when you find overlaps.

This is how we offer the Web Requests plugin auth gate free while still maintaining records for debug, user experience purposes, and insights.

This also works with Custom GPT requests.

Not shown is the explicit user merging logic we use but you can figure that out based on your own needs I’m sure.

1 Like

This is really great! But what about this case?

  • User creates a chat on Day 1, gets Userid U1, and ChatId C1
  • User creates a chat on Day 2, gets Userid U2 and ChatId C2
  • User creates a chat on Day 3, gets Userid U3 and ChatId C3

Basically, a user always uses your service by making new chats and not revisiting old ones? This feels like quite a common use case too, since I find myself doing that often with GPTs.

This is the exact case where yes, there will not be an overlap, and will be a redundant in user objects.

That said, there are cleanup subroutines we’ve created and are tuning to help identify this stuff. Using first_seen, last_seen, request timing patterns, and request counts – trying to identify patterns that can reliably link customers up.

Lastly, there is also a “token” field that users who use advanced features are get generated a client token can put in their custom instructions and always authenticate in their request. This can also be done with a hashing salt method so that what is sent across the wire and in a prompt is a hash representation, and a “secret” is always in their custom instructions but never printed in plain text in the context window, so it stays private unless their actual account is compromised.

When users opt-in to this authentication method (by way of an upsell or feature opt-in) then it will forever guarantee we link up their ephemerals and conversations moving forward regardless.

So @thariq, what this system allows us to do is this :point_down:

Basically what you’re looking at is a user record with a subscription tier o 0 – meaning, they’re a totally 0-authenticated, anonymous user. And with just 16 Ephemeral ID’s and 10 Conversation ID’s, we were able to persist 54 days worth of user data (for our purposes, this is used for insights premium upsells, and usage limitation purposes as we think toward monetization).

We are able to create an absolute barrier-free onboarding experience with useful business intelligence for planning and prepping our future. The most elegant user experience, best-of-both-worlds scenario.