ChatGPT plugins drastically expand the capabilities of OpenAI’s most advanced model - GPT-4. Plugins give GPT-4 access to tools, which can be used to inject context into conversations, plan travel, go shopping, and more. Plugins have the potential to be another app store---giving developers a new platform for users to consume their products. As a developer, you might want to protect access to your plugin to only registered users. ChatGPT offers a few authentication strategies for vetting users and protecting access to your plugin. In this post, we’ll cover all of the available plugin authentication strategies, and discuss the tradeoffs between them.
If you’re not familiar with ChatGPT plugins, I recommend reading our post: What is a ChatGPT plugin?. Then, check out one of our tutorials on making your own ChatGPT plugin:
Now, let’s dive in!
Auth0 describes authentication as:
the process of proving that some fact or some document is genuine. In computer science, this term is typically associated with proving a user’s identity.
Most applications will require a user to authenticate with a username/e-mail and password before accessing certain parts of the application. By authenticating with a username and password, the user proves their identity e.g. that they are in fact the user with the given credentials.
Authentication is typically a precondition for authorization. Authorization is the process of verifying what specific resources a user has access to. In order to perform authorization, we typically need to authenticate a user, and then verify the user has access to a given resource.
There are many reasons you’d want to implement authentication and authorization for your ChatGPT plugin including:
Authentication and authorization in ChatGPT plugins differ from traditional platforms because the experience is driven via an external platform that you as the developer do not control. OpenAI dictates what authentication methods are valid, and thus you must stay within the confines of their restrictions. Fortunately, the provided authentication options are sensible, and cover the range of what you might want to do with your plugin.
In order to configure authentication for your plugin, you must use the auth
field in your plugin’s manifest. The structure of the auth
field is largely driven by the type of authentication you choose to implement.
The simplest type of authentication isn’t authentication at all. By specifying auth
with type
set to none
, users can use your plugin without any authentication restrictions:
"auth": {
"type": "none"
},
If you don’t have a reason for implementing authentication, then there’s no need to overcomplicate things. Keep in mind that without authentication, auditing is a challenge. Additionally, your API might not be restricted to just ChatGPT users. If you don’t protect your ChatGPT API, you may run into issues with load, malicious users, and more.
The recommended best practice for plugins that will be made available in the plugin store is service level authentication. Service level authentication allows you to specifically enable access to your plugin API only to ChatGPT. Essentially, you are providing blanket authentication to any ChatGPT user.
If you’ve implemented API-based authentication before, you should have a good understanding of how service level authentication works. First, you specify service level authentication in your plugin manifest:
"auth": {
"type": "service_http",
"authorization_type": "bearer",
},
Next, you add your plugin to ChatGPT by clicking “Develop your own” in the plugin store and providing the plugin domain. ChatGPT will detect that you’re using service level authentication and ask for a client secret. This client secret is private and should be a securely generated string. For example, you might use the following Python code to generate a random client secret:
import secrets
import string
def generate_client_secret(length):
# Define the character set for the random string
characters = string.ascii_letters + string.digits
# Generate the random string
client_secret = ''.join(secrets.choice(characters) for _ in range(length))
return client_secret
# Generate a client secret with a length of 64 characters
client_secret = generate_client_secret(64)
print(client_secret)
After providing your client secret to ChatGPT, it will provide you with a verficiation token. You then need to add this verification token to your plugin manifest:
"auth": {
"type": "service_http",
"authorization_type": "bearer",
"verification_tokens": {
"openai": "Replace_this_string_with_the_verification_token_generated_in_the_ChatGPT_UI"
}
},
Whenever ChatGPT sends requests to your plugin API, it will pass the client secret you provided during the installation process in the Authorization
header. It’s your responsibility to verify the passed secret is the same as the client secret your application expects.
Service level authentication is recommended as a baseline for most plugins because it provides some level of protection for your API. It also is the least intrusive experience for your users. The downside is that you don’t necessarily have fine-grained control over which users have acccess to which resources. Because ChatGPT users are authenticated via the ChatGPT service, you cannot differentiate between different users of your plugin.
User Level Authentication is another type of API-based authentication which allows you to authenticate users of your plugin on a per-user basis. Rather than verifying a request came from the ChatGPT service, you can associate a request with a specific user. User Level Authentication is easy if you already have a REST API with authentication configured. First, you specify that you want to use user level authentication in your plugin manifest:
"auth": {
"type": "user_http",
"authorization_type": "bearer",
},
Then, when installing your plugin, a user just needs to provide their API key. ChatGPT will then send this user’s API key in the Authorization
header with every request.
One significant drawback of user level authentication is that (at the moment), it’s not supported for plugins that will go into the plugin store. It also provides a less intuitive and more intrusive user experience for consumers of your plugin. Some users will have little experience with API-based authentication, and thus forcing them to generate API keys and provide them to your application will be foreign.
If you really need to authenticate at the user-level, I strongly recommend using OAuth.
The final and most complex authentication strategy that OpenAI supports is authentication via an OAuth flow. The OAuth flow will redirect users to your website to authenticate, before redirecting them back to the ChatGPT UI upon successful authentication. The OAuth strategy allows you to authenticate consumers at the user-level with your own authentication flow (e.g. with username and password). The drawback is that it is easily the most complex strategy to implement. Fortunately, many third-party identity providers will provide integrations and tooling for building your own OAuth server implementation.
The basic OAuth flow looks like this:
First, you specify OAuth as a strategy in your plugin manifest:
"auth": {
"type": "oauth",
"client_url": "https://example.com/authorize",
"scope": "read:resource",
"authorization_url": "https://example.com/auth/",
"authorization_content_type": "application/json",
},
You must specify a client_url
and authorization_url
. After initially installing your plugin, ChatGPT will prompt you for an OAuth client secret and client ID. Once provided, you will be given a verification token to add to your plugin manifest:
"auth": {
"type": "oauth",
"client_url": "https://example.com/authorize",
"scope": "",
"authorization_url": "https://example.com/auth/",
"authorization_content_type": "application/json",
"verification_tokens": {
"openai": "Replace_this_string_with_the_verification_token_generated_in_the_ChatGPT_UI"
}
},
Now, when a user installs your plugin, they will be redirected to your application’s Client URL. This is where your application needs to authenticate the user, verify they have access to the requested scopes, and also verify that the client ID provided by OpenAI is correct. After authenticating, you should redirect the user back to a provided redirectURI
with a securely generated and quickly expiring code. At that time, OpenAI will make an additional POST
request to the given authorization URL. The POST
request will contain information such as your provided client ID and client secret and the generated code from the previous step. You should verify all of this information matches what you expect and respond to the request with an access token and a refresh token.
Subsequent requests to your API will be made with the access token you returned to OpenAI in the Authorization
header. You can see an example of a complete OAuth enabled plugin in this post.
OAuth is by far the most complex authentication strategy; however, it’s recommended if you need to authenticate users at a finer-level than provided by service level authentication. One drawback of OAuth authentication is that you cannot test them with a local server. This means you need to user services such as ngrok for testing.
ChatGPT plugins provide 4 distinct authentication strategies for plugin developers to control access to their plugin APIs. These strategies allow you to implement authentication at the user-level, service-level, or not at all. Choosing the right authentication strategy is important for developing a quality plugin. If you need help choosing or implementing an authentication strategy, feel free to reach out!
Get updates on new content, exclusive offers, and exclusive materials by subscribing to our newsletter.