Plugin authentication

Plugins offer numerous authentication schemas to accommodate various use cases. To specify the authentication schema for your plugin, use the manifest file. Our plugin domain policy outlines our strategy for addressing domain security issues. For examples of available authentication options, refer to the examples section, which showcases all the different choices.

No authentication

We support no-auth flow for applications that do not require authentication, where a user is able to send requests directly to your API without any restrictions. This is particularly useful if you have an open API that you want to make available to everyone, as it allows traffic from sources other than just OpenAI plugin requests.

"auth": {
  "type": "none"
},

Service level

If you want to specifically enable OpenAI plugins to work with your API, you can provide a client secret during the plugin installation flow. This means that all traffic from OpenAI plugins will be authenticated but not on a user level. This flow benefits from a simple end user experience but less control from an API perspective.

  • To start, a developer pastes in their access token (global key)
  • Then, they have to add the verification token to their manifest file
  • We store an encrypted version of the token
  • Users don’t need to do anything when they install the plugin
  • Last, we pass it in the Authorization header when making requests to the plugin (“Authorization”: “[Bearer/Basic][user’s token]”)
"auth": {
  "type": "service_http",
  "authorization_type": "bearer",
  "verification_tokens": {
    "openai": "cb7cdfb8a57e45bc8ad7dea5bc2f8324"
  }
},

User level

Just like how a user might already be using your API, we allow user level authentication through enabling end users to copy and paste their secret API key into the ChatGPT UI during plugin install. While we encrypt the secret key when we store it in our database, we do not recommend this approach given the poor user experience.

  • To start, a user pastes in their access token when installing the plugin
  • We store an encrypted version of the token
  • We then pass it in the Authorization header when making requests to the plugin (“Authorization”: “[Bearer/Basic][user’s token]”)
"auth": {
  "type": "user_http",
  "authorization_type": "bearer",
},

OAuth

The plugin protocol is compatible with OAuth. A simple example of the OAuth flow we are expecting in the manifest looks like the following:

  • To start, a developer pastes in their OAuth client id and client secret
    • Then they have to add the verification token to their manifest file
  • We store an encrypted version of the client secret
  • Users log in through the plugin’s website when they install the plugin
    • That gives us an OAuth access token (and optionally a refresh token) for the user, which we store encrypted
  • Last, we pass that user’s token in the Authorization header when making requests to the plugin (“Authorization”: “[Bearer/Basic][user’s token]”)
"auth": {
  "type": "oauth",
  "client_url": "https://my_server.com/authorize",
  "scope": "",
  "authorization_url": "https://my_server.com/token",
  "authorization_content_type": "application/json",
  "verification_tokens": {
    "openai": "abc123456"
  }
},

To better understand the URL structure for OAuth, here is a short description of the fields:

  • When you set up your plugin with ChatGPT, you will be asked to provide your OAuth client_id and client_secret
  • When a user logs into the plugin, ChatGPT will direct the user’s browser to "[client_url]?response_type=code&client_id=[client_id]&scope=[scope]&redirect_uri=https%3A%2F%2Fchat.openai.com%2Faip%2F[plugin_id]%2Foauth%2Fcallback"
  • After your plugin redirects back to the given redirect_uri, ChatGPT will complete the OAuth flow by making a POST request to authorization_url with content type authorization_content_type and parameters { “grant_type”: “authorization_code”, “client_id”: [client_id], “client_secret”: [client_secret], “code”: [the code that was returned with the redirect], “redirect_uri”: [the same redirect uri as before] }