From 73a1517dbad0138d6b37e9ba401210159225e29e Mon Sep 17 00:00:00 2001 From: Matt Kafonek Date: Wed, 2 Aug 2023 12:14:39 -0700 Subject: [PATCH 01/21] Start the OAuth Blog Post --- blog/2023-08-04-oauth-plugin/index.mdx | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 blog/2023-08-04-oauth-plugin/index.mdx diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx new file mode 100644 index 0000000..b6286a7 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -0,0 +1,43 @@ +--- +slug: notebook-tools-for-llms +title: "OAuth for ChatGPT Plugins" +authors: [kafonek] +description: "How Noteable added OAuth to its ChatGPT Plugin" +# image: "./TODO.png" +tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] +--- + +Hello plugin community. I work on the backend engineering team at Noteable, which includes development of the Noteable ChatGPT plugin. Today I wanted to share a bit of a guide to OAuth for plugin developers based on documentation and retrospectives I’ve written for our internal consumption. Feel free to re-use and re-purpose the images and text below for your own projects if it helps. I’m happy to answer questions in the comments or direct messages. + +I’m going to start out at a very high level and then work down into some more complicated use cases using our own system as an example. There are many different OAuth providers out there, and you can always roll your own. We happen to use Auth0, so that’s what my diagrams are geared towards. My words here should complement official OpenAI tutorials and Auth0 docs:: + +- https://platform.openai.com/docs/plugins/authentication/oauth +- https://auth0.com/docs/authenticate/protocols/oauth#authorization-endpoint + +Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip Oauth because you don’t need to have a logged in user to read Wiki. If the LLM is creating Notebooks and running code via Noteable plugin, which is chock full of RBAC and user-context-aware features, we need to know what user account the request is for. + +As a plugin developer, getting started with OAuth can be a bit tricky. You can’t test with localhost plugin development workflow. If you try to “develop your own plugin” and point to localhost, and your manifest file has anything other than “none” in the auth section, you’ll get a message saying “Only auth type `none` is supported for localhost plugins”. + +One option is to use a tool like ngrok to proxy requests to your localhost, just make sure you adjust the allowed redirect domains in your OAuth provider every time you spin up a new proxy. Luckily for me, Noteable has several integration and staging domains I can test with. + +Next, what does it look like to users of your plugin? When they install your plugin, they’ll be redirected to your OAuth provider to login. When that’s complete, the user can activate your plugin for new chats and the LLM will include a JWT in an Authorization: bearer header for all HTTP requests to your plugin. If you look at your browser network tab, you can see part of the flow but not all of it. + +Your plugin can then do two things with the JWT: validate that it’s signed by the OAuth provider and decode it to get a payload of information about the user. https://jwt.io is a great resource for seeing what a generic JWT looks like and decoding (but not validating) JWTs in testing and debugging. OAuth providers will typically publish their public signing keys at a /.well-known/jwks.json endpoint. + +I’ll pause for a moment to talk about the values you configure in ChatGPT when clicking “develop your own plugin” and what goes in the manifest file. If you’re using auth0, the client_url in the manifest file should be the /authorize endpoint and the authorization_url is the /oauth/token endpoint for your tenant. The redirect_uri is controlled by ChatGPT and will be built using your plugin id, make sure to configure your OAuth provider to allow that redirect path. + +If you’ve worked with OAuth in typical frontend/backend applications before, then it can help to think about ChatGPT and the plugin as effectively just another frontend to your API. The Noteable plugin as an example is mostly a passthrough to a subset of the overall Noteable API, with some shortened endpoints and an OpenAPI schema tailored for the LLM. + +One nice perk of auth0 is that you can configure different “Applications” (the auth0 term, not the generic sense of the word) in the same tenant. Those can display different landing pages for users that are coming into your login/signup flow from a normal frontend vs ChatGPT. As well, you may want to customize which logins are allowed. As a practical example, we had to disable username/password signup from ChatGPT since we enforce email verification for that flow in Auth0, but the “you must verify your email” detail that Auth0 sent back to ChatGPT isn’t displayed to the user. + +If you store User information in your own database, then the backend auth validation process is probably a two-step thing. First, validate the JWT and decode the claims, then look-up User row from information in the claims (sub/iss for auth0). One tip I’d offer to developers is think about whether you want one User account per email or one User account per auth mechanism, and separate out your Users and Principals tables appropriately. + +We definitely experienced some pain when users ended up logged into the Noteable UI app as one account (user/pass auth mechanism) and the ChatGPT plugin as a different account (say, google oauth social login) and then ran into weird permission errors trying to work with Projects or Notebooks owned by different accounts. We tried to lean on auth0’s built-in account linking but we’re working instead right now restructuring our database and sign-up flow so it is one account per email instead of auth mechanism. + +The final big unaddressed topic in that last diagram is account creation on the backend. It’s fine that ChatGPT or your frontend UI can redirect a new user to auth0 so they create an account in auth0, but how do you make sure there’s a matching account in your database? + +There’s two parts to that answer. First, you want to use the right OpenID connect scopes (https://auth0.com/docs/get-started/apis/scopes/openid-connect-scopes) so that Auth0 returns an id_token in addition to an access_token from the POST to the token_url. You may as well ask for a refresh_token while you’re at it. The scopes we put in our manifest file are “offline_access openid email profile”. + +Second, you need to receive the id_token somehow. The way we implemented that is to have ChatGPT POST to our plugin instead of directly to auth0 /oauth/token endpoint. Here’s the last diagram of this post. + +Thanks, I hope this helps. From 445e49a28c7ea4dbd597bd51e8f7a8c509385fef Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Wed, 2 Aug 2023 12:14:52 -0700 Subject: [PATCH 02/21] add Kafonek --- blog/authors.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/blog/authors.yml b/blog/authors.yml index b1d0f90..227e4d0 100644 --- a/blog/authors.yml +++ b/blog/authors.yml @@ -3,3 +3,9 @@ kyle: title: Mad Scientist @ Noteable url: https://github.com/rgbkrk image_url: https://github.com/rgbkrk.png + +kafonek: + name: Matt Kafonek + title: Senior Software Engineer @ Noteable + url: https://github.com/kafonek + image_url: https://github.com/kafonek.png From 069f4adae819a962afb8e555c2abc0883f158e5e Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Wed, 2 Aug 2023 12:15:41 -0700 Subject: [PATCH 03/21] set post to draft --- blog/2023-08-04-oauth-plugin/index.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index b6286a7..4e26db0 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -3,6 +3,7 @@ slug: notebook-tools-for-llms title: "OAuth for ChatGPT Plugins" authors: [kafonek] description: "How Noteable added OAuth to its ChatGPT Plugin" +draft: true # image: "./TODO.png" tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] --- From 16224e720af5b2d1ec940dd7452eb2acb3c7668a Mon Sep 17 00:00:00 2001 From: Kafonek Date: Thu, 3 Aug 2023 12:35:32 -0400 Subject: [PATCH 04/21] Kafonek content for blog --- .../account_creation.svg | 1 + blog/2023-08-04-oauth-plugin/bad_times.svg | 1 + blog/2023-08-04-oauth-plugin/good_times.svg | 1 + blog/2023-08-04-oauth-plugin/index.mdx | 72 ++++++++++++++----- .../2023-08-04-oauth-plugin/localhost_dev.svg | 1 + blog/2023-08-04-oauth-plugin/oauth_101.svg | 1 + blog/2023-08-04-oauth-plugin/oauth_app.svg | 1 + .../oauth_combined_app.svg | 1 + blog/2023-08-04-oauth-plugin/oauth_config.svg | 1 + .../2023-08-04-oauth-plugin/user_accounts.svg | 1 + 10 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 blog/2023-08-04-oauth-plugin/account_creation.svg create mode 100644 blog/2023-08-04-oauth-plugin/bad_times.svg create mode 100644 blog/2023-08-04-oauth-plugin/good_times.svg create mode 100644 blog/2023-08-04-oauth-plugin/localhost_dev.svg create mode 100644 blog/2023-08-04-oauth-plugin/oauth_101.svg create mode 100644 blog/2023-08-04-oauth-plugin/oauth_app.svg create mode 100644 blog/2023-08-04-oauth-plugin/oauth_combined_app.svg create mode 100644 blog/2023-08-04-oauth-plugin/oauth_config.svg create mode 100644 blog/2023-08-04-oauth-plugin/user_accounts.svg diff --git a/blog/2023-08-04-oauth-plugin/account_creation.svg b/blog/2023-08-04-oauth-plugin/account_creation.svg new file mode 100644 index 0000000..0e890c2 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/account_creation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blog/2023-08-04-oauth-plugin/bad_times.svg b/blog/2023-08-04-oauth-plugin/bad_times.svg new file mode 100644 index 0000000..0efac40 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/bad_times.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blog/2023-08-04-oauth-plugin/good_times.svg b/blog/2023-08-04-oauth-plugin/good_times.svg new file mode 100644 index 0000000..57e74c5 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/good_times.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 4e26db0..b33d025 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -8,37 +8,77 @@ draft: true tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] --- -Hello plugin community. I work on the backend engineering team at Noteable, which includes development of the Noteable ChatGPT plugin. Today I wanted to share a bit of a guide to OAuth for plugin developers based on documentation and retrospectives I’ve written for our internal consumption. Feel free to re-use and re-purpose the images and text below for your own projects if it helps. I’m happy to answer questions in the comments or direct messages. +## Introduction +OAuth is mechanism used enable single sign on across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google or Github account among others. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. -I’m going to start out at a very high level and then work down into some more complicated use cases using our own system as an example. There are many different OAuth providers out there, and you can always roll your own. We happen to use Auth0, so that’s what my diagrams are geared towards. My words here should complement official OpenAI tutorials and Auth0 docs:: +Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. + +There are many OAuth providers out there, and there's nothing stopping you from writing your own. We happen to use [Auth0](https://auth0.com/), so our examples will include their implementation details (such as `authorize` and `/oauth/token` endpoints). OpenAI and Auth0 both have good documentation about OAuth flows, I recommend reading these sections in addition to this blog post if you're working on an OAuth plugin yourself. - https://platform.openai.com/docs/plugins/authentication/oauth - https://auth0.com/docs/authenticate/protocols/oauth#authorization-endpoint -Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip Oauth because you don’t need to have a logged in user to read Wiki. If the LLM is creating Notebooks and running code via Noteable plugin, which is chock full of RBAC and user-context-aware features, we need to know what user account the request is for. +## OAuth 101 + +When you click `Install` on an OAuth-enabled ChatGPT plugin, your browser will be redirected to the OAuth provider page. Once you've completed logging in there, which may entail even more OAuth redirect jumps, the provider will redirect you back to ChatGPT. If everything goes well, ChatGPT will acquire a JSON web token (JWT) that it will include in an Authorization header on every HTTP request to your plugin. + +A JWT contains limited identity information about the authenticated user, and has an expiration. You can learn more about JWT's and decode the payloads in a JWT at [jwt.io](https://jwt.io/). + +![OAuth 101](./oauth_101.svg) + +:::note +When you are developing a plugin in localhost mode, the only authorization type allowed is "none". You cannot test OAuth flows in localhost development mode. You will need to host your plugin somewhere or use a tool like [ngrok](https://ngrok.com/) to create a proxy to your machine. + +::: + +## OAuth apps + +OAuth and JWT's are not unique to ChatGPT plugins. A typical front-end / back-end web application would use an OAuth flow very similar to the ChatGPT plugin experience. On the backend, you can validate that the JWT's you're receiving were issued by the OAuth provider you trust by using JSON Web Keys (JWK). At Noteable we use the [jwcrypto](https://jwcrypto.readthedocs.io/en/latest/) Python library. + +![OAuth app](./oauth_app.svg) + +The Noteable ChatGPT plugin is more or less a proxy to our main API. There's a little more going on in our application, but a plugin that is effectively a pass-through to another API can pass the JWT it got from ChatGPT right along as an Authorization header to the real API. + +![Plugin and Frontend](./oauth_combined_app.svg) + +## OAuth configuration + +Once you're ready to test out OAuth with your plugin, the first step is to have your plugin hosted somewhere besides `localhost` and for your manifest file (`ai-plugin.json`) to have its auth section set to type oauth. You'll also need to have the client_url and authorization_url point to the endpoints of your OAuth provider for the initial redirect and POST to grab the jwt respectively. + +When you click "develop your own plugin" in ChatGPT and give it the domain your plugin is hosted at, it will try to download the manifest file and OpenAPI spec file. If it sees your manifest file has type oauth, it will prompt you to enter the client_id and client_secret from your OAuth provider. After you've put those in, ChatGPT will give you a token that you need to add to your manifest file and then redeploy / restart. If ChatGPT can pull the manifest file and see the new token, then the "develop your own plugin" flow is complete and ChatGPT will give you a plugin application id that you can use to update the redirect_uri in your OAuth provider. + +![OAuth config](./oauth_config.svg) + +:::note +Scope is optional, and is an empty string in the OpenAI example. Noteable uses scopes `openid profile email offline_access` in order get back three tokens during the OAuth process: `access_token`, `id_token`, and `refresh_token` (all are JWTs). + - ChatGPT uses the `access_token` in Authorization headers to our plugin + - ChatGPT will automatically refresh `access_token` using the `refresh_token` + - Noteable uses the name and email from the `id_token` payload to create a User account in Noteable if one does not already exist + +You can read more about scopes [here](https://auth0.com/docs/get-started/apis/scopes/openid-connect-scopes) + +::: -As a plugin developer, getting started with OAuth can be a bit tricky. You can’t test with localhost plugin development workflow. If you try to “develop your own plugin” and point to localhost, and your manifest file has anything other than “none” in the auth section, you’ll get a message saying “Only auth type `none` is supported for localhost plugins”. +## Painful Lessons -One option is to use a tool like ngrok to proxy requests to your localhost, just make sure you adjust the allowed redirect domains in your OAuth provider every time you spin up a new proxy. Luckily for me, Noteable has several integration and staging domains I can test with. +One decision we made early on at Noteable that turned out to be a mistake was creating User accounts using the `sub` payload from the Auth0 identity tokens, and looking up a User row in our database from the `sub` in the Auth0 access token. Each login mechanism ended up being its own separate User in our system. If you logged in to [app.noteable.io](https://app.noteable.io) using your Github social login, then installed the ChatGPT plugin and authenticated with your Google login, you would end up with all sorts of permission denied errors trying to work on Notebooks between them. It was a major pain point. -Next, what does it look like to users of your plugin? When they install your plugin, they’ll be redirected to your OAuth provider to login. When that’s complete, the user can activate your plugin for new chats and the LLM will include a JWT in an Authorization: bearer header for all HTTP requests to your plugin. If you look at your browser network tab, you can see part of the flow but not all of it. +A compounding problem was that we were enforcing email verification for username / password accounts using a rule in Auth0 that would not return a JWT until the user clicked a link in their email. In our Noteable app frontend, when you signed up that way we could direct the user what to do. However we had no control over the ChatGPT UI, and from the user perspective they would install the Noteable plugin and it would fail with no error message. Technically there was an error code in url arguments of the redirect from Auth0 back to ChatGPT, but it would take an eagle-eyed user to notice that. Our temporary solution was to disable username / password login from the Auth0 application we used for ChatGPT, funneling even more users into the multiple-account problem space. -Your plugin can then do two things with the JWT: validate that it’s signed by the OAuth provider and decode it to get a payload of information about the user. https://jwt.io is a great resource for seeing what a generic JWT looks like and decoding (but not validating) JWTs in testing and debugging. OAuth providers will typically publish their public signing keys at a /.well-known/jwks.json endpoint. +![Bad Times](./bad_times.svg) -I’ll pause for a moment to talk about the values you configure in ChatGPT when clicking “develop your own plugin” and what goes in the manifest file. If you’re using auth0, the client_url in the manifest file should be the /authorize endpoint and the authorization_url is the /oauth/token endpoint for your tenant. The redirect_uri is controlled by ChatGPT and will be built using your plugin id, make sure to configure your OAuth provider to allow that redirect path. +Our solution was to create a second database table we called Principals to represent the login mechanism, and link to the Users table. We reconfigured our ChatGPT manifest file to proxy the authorize and token endpoints through our plugin so that we could automatically create or link Noteable accounts during the OAuth flow. And we moved the email verification onto our own system instead of within an Auth0 rule, with error handling in the plugin to tell the user that while they did successfully install the Noteable ChatGPT plugin, they still need to click the email verification link before it will successfully create Notebooks or run code for them. -If you’ve worked with OAuth in typical frontend/backend applications before, then it can help to think about ChatGPT and the plugin as effectively just another frontend to your API. The Noteable plugin as an example is mostly a passthrough to a subset of the overall Noteable API, with some shortened endpoints and an OpenAPI schema tailored for the LLM. +![Good Times](./good_times.svg) -One nice perk of auth0 is that you can configure different “Applications” (the auth0 term, not the generic sense of the word) in the same tenant. Those can display different landing pages for users that are coming into your login/signup flow from a normal frontend vs ChatGPT. As well, you may want to customize which logins are allowed. As a practical example, we had to disable username/password signup from ChatGPT since we enforce email verification for that flow in Auth0, but the “you must verify your email” detail that Auth0 sent back to ChatGPT isn’t displayed to the user. +![Account Creation](./account_creation.svg) -If you store User information in your own database, then the backend auth validation process is probably a two-step thing. First, validate the JWT and decode the claims, then look-up User row from information in the claims (sub/iss for auth0). One tip I’d offer to developers is think about whether you want one User account per email or one User account per auth mechanism, and separate out your Users and Principals tables appropriately. +## Localhost development -We definitely experienced some pain when users ended up logged into the Noteable UI app as one account (user/pass auth mechanism) and the ChatGPT plugin as a different account (say, google oauth social login) and then ran into weird permission errors trying to work with Projects or Notebooks owned by different accounts. We tried to lean on auth0’s built-in account linking but we’re working instead right now restructuring our database and sign-up flow so it is one account per email instead of auth mechanism. +We mentioned at the top of the post that you cannot do OAuth testing in localhost development. If your backend API requires a JWT for authentication though, what do you do? Luckily at Noteable we issue our own tokens for programmatic access to our API, which we'll talk more about in other blog posts and show off in Origami documentation. -The final big unaddressed topic in that last diagram is account creation on the backend. It’s fine that ChatGPT or your frontend UI can redirect a new user to auth0 so they create an account in auth0, but how do you make sure there’s a matching account in your database? +![Localhost Development](./localhost_dev.svg) -There’s two parts to that answer. First, you want to use the right OpenID connect scopes (https://auth0.com/docs/get-started/apis/scopes/openid-connect-scopes) so that Auth0 returns an id_token in addition to an access_token from the POST to the token_url. You may as well ask for a refresh_token while you’re at it. The scopes we put in our manifest file are “offline_access openid email profile”. +## Final Thoughts -Second, you need to receive the id_token somehow. The way we implemented that is to have ChatGPT POST to our plugin instead of directly to auth0 /oauth/token endpoint. Here’s the last diagram of this post. -Thanks, I hope this helps. diff --git a/blog/2023-08-04-oauth-plugin/localhost_dev.svg b/blog/2023-08-04-oauth-plugin/localhost_dev.svg new file mode 100644 index 0000000..d35a529 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/localhost_dev.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blog/2023-08-04-oauth-plugin/oauth_101.svg b/blog/2023-08-04-oauth-plugin/oauth_101.svg new file mode 100644 index 0000000..8c687f9 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/oauth_101.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blog/2023-08-04-oauth-plugin/oauth_app.svg b/blog/2023-08-04-oauth-plugin/oauth_app.svg new file mode 100644 index 0000000..496cd81 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/oauth_app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blog/2023-08-04-oauth-plugin/oauth_combined_app.svg b/blog/2023-08-04-oauth-plugin/oauth_combined_app.svg new file mode 100644 index 0000000..5d3fa36 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/oauth_combined_app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blog/2023-08-04-oauth-plugin/oauth_config.svg b/blog/2023-08-04-oauth-plugin/oauth_config.svg new file mode 100644 index 0000000..51b3911 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/oauth_config.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blog/2023-08-04-oauth-plugin/user_accounts.svg b/blog/2023-08-04-oauth-plugin/user_accounts.svg new file mode 100644 index 0000000..eb37511 --- /dev/null +++ b/blog/2023-08-04-oauth-plugin/user_accounts.svg @@ -0,0 +1 @@ + \ No newline at end of file From 5e650e7453711400dcf9bc185a74f6bf71a5b24a Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Thu, 3 Aug 2023 09:57:09 -0700 Subject: [PATCH 05/21] include slug, turn off draft --- blog/2023-08-04-oauth-plugin/index.mdx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index b33d025..f13dd98 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -1,14 +1,14 @@ --- -slug: notebook-tools-for-llms +slug: oauth-for-chatgpt-plugins title: "OAuth for ChatGPT Plugins" authors: [kafonek] description: "How Noteable added OAuth to its ChatGPT Plugin" -draft: true # image: "./TODO.png" tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] --- ## Introduction + OAuth is mechanism used enable single sign on across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google or Github account among others. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. @@ -50,10 +50,11 @@ When you click "develop your own plugin" in ChatGPT and give it the domain your ![OAuth config](./oauth_config.svg) :::note -Scope is optional, and is an empty string in the OpenAI example. Noteable uses scopes `openid profile email offline_access` in order get back three tokens during the OAuth process: `access_token`, `id_token`, and `refresh_token` (all are JWTs). - - ChatGPT uses the `access_token` in Authorization headers to our plugin - - ChatGPT will automatically refresh `access_token` using the `refresh_token` - - Noteable uses the name and email from the `id_token` payload to create a User account in Noteable if one does not already exist +Scope is optional, and is an empty string in the OpenAI example. Noteable uses scopes `openid profile email offline_access` in order get back three tokens during the OAuth process: `access_token`, `id_token`, and `refresh_token` (all are JWTs). + +- ChatGPT uses the `access_token` in Authorization headers to our plugin +- ChatGPT will automatically refresh `access_token` using the `refresh_token` +- Noteable uses the name and email from the `id_token` payload to create a User account in Noteable if one does not already exist You can read more about scopes [here](https://auth0.com/docs/get-started/apis/scopes/openid-connect-scopes) @@ -80,5 +81,3 @@ We mentioned at the top of the post that you cannot do OAuth testing in localhos ![Localhost Development](./localhost_dev.svg) ## Final Thoughts - - From 00695441ab47aea108ded6a7bd9cfa47c11a0b41 Mon Sep 17 00:00:00 2001 From: Matt Kafonek Date: Thu, 3 Aug 2023 13:16:38 -0400 Subject: [PATCH 06/21] Update blog/2023-08-04-oauth-plugin/index.mdx Co-authored-by: Rohit Sanjay --- blog/2023-08-04-oauth-plugin/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index f13dd98..795b890 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -9,7 +9,7 @@ tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] ## Introduction -OAuth is mechanism used enable single sign on across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google or Github account among others. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. +OAuth is a mechanism used to enable Single Sign-On (SSO) across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google or Github account among others. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. From 6a39dca98b3df3f961bb996a44f08176749f0532 Mon Sep 17 00:00:00 2001 From: Kafonek Date: Thu, 3 Aug 2023 13:18:37 -0400 Subject: [PATCH 07/21] account linking wording --- blog/2023-08-04-oauth-plugin/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 795b890..7a2be74 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -68,7 +68,7 @@ A compounding problem was that we were enforcing email verification for username ![Bad Times](./bad_times.svg) -Our solution was to create a second database table we called Principals to represent the login mechanism, and link to the Users table. We reconfigured our ChatGPT manifest file to proxy the authorize and token endpoints through our plugin so that we could automatically create or link Noteable accounts during the OAuth flow. And we moved the email verification onto our own system instead of within an Auth0 rule, with error handling in the plugin to tell the user that while they did successfully install the Noteable ChatGPT plugin, they still need to click the email verification link before it will successfully create Notebooks or run code for them. +Our solution was to create a second database table we called Principals to represent the login mechanism. A Google, Github, or Auth0 username/password login with the same email all link to the same User account now. We reconfigured our ChatGPT manifest file to proxy the authorize and token endpoints through our plugin so that we could automatically create or link Noteable accounts during the OAuth flow. And we moved the email verification onto our own system instead of within an Auth0 rule, with error handling in the plugin to tell the user that while they did successfully install the Noteable ChatGPT plugin, they still need to click the email verification link before it will successfully create Notebooks or run code for them. ![Good Times](./good_times.svg) From 4173c75e81b4b6c1d8e494dbb10af93f1229ed45 Mon Sep 17 00:00:00 2001 From: Kafonek Date: Thu, 3 Aug 2023 13:19:52 -0400 Subject: [PATCH 08/21] list linkedin --- blog/2023-08-04-oauth-plugin/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 7a2be74..b9664b2 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -9,7 +9,7 @@ tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] ## Introduction -OAuth is a mechanism used to enable Single Sign-On (SSO) across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google or Github account among others. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. +OAuth is a mechanism used to enable Single Sign-On (SSO) across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google, Github, or LinkedIn account. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. From 2006f2519966df27b9ad31ad3c2d0c9d03d6a862 Mon Sep 17 00:00:00 2001 From: Matt Kafonek Date: Thu, 3 Aug 2023 13:20:13 -0400 Subject: [PATCH 09/21] Update blog/2023-08-04-oauth-plugin/index.mdx Co-authored-by: Kyle Kelley --- blog/2023-08-04-oauth-plugin/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index b9664b2..140159b 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -11,7 +11,7 @@ tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] OAuth is a mechanism used to enable Single Sign-On (SSO) across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google, Github, or LinkedIn account. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. -Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. +Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via the Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. There are many OAuth providers out there, and there's nothing stopping you from writing your own. We happen to use [Auth0](https://auth0.com/), so our examples will include their implementation details (such as `authorize` and `/oauth/token` endpoints). OpenAI and Auth0 both have good documentation about OAuth flows, I recommend reading these sections in addition to this blog post if you're working on an OAuth plugin yourself. From a3456732ae16a414c8de8bbc2026e8974d62b41a Mon Sep 17 00:00:00 2001 From: Matt Kafonek Date: Thu, 3 Aug 2023 13:20:26 -0400 Subject: [PATCH 10/21] Update blog/2023-08-04-oauth-plugin/index.mdx Co-authored-by: Kyle Kelley --- blog/2023-08-04-oauth-plugin/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 140159b..558db84 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -33,7 +33,7 @@ When you are developing a plugin in localhost mode, the only authorization type ## OAuth apps -OAuth and JWT's are not unique to ChatGPT plugins. A typical front-end / back-end web application would use an OAuth flow very similar to the ChatGPT plugin experience. On the backend, you can validate that the JWT's you're receiving were issued by the OAuth provider you trust by using JSON Web Keys (JWK). At Noteable we use the [jwcrypto](https://jwcrypto.readthedocs.io/en/latest/) Python library. +OAuth and JWT's are not unique to ChatGPT plugins. A typical front-end / back-end web application would use an OAuth flow very similar to the ChatGPT plugin experience. On the backend, you can validate that the JWT's you're receiving were issued by the OAuth provider you trust by using JSON Web Keys (JWK). At Noteable we use the [`jwcrypto`](https://jwcrypto.readthedocs.io/en/latest/) Python library. ![OAuth app](./oauth_app.svg) From 18e8aca2aba0128ae079f9171b943b916794d698 Mon Sep 17 00:00:00 2001 From: Matt Kafonek Date: Thu, 3 Aug 2023 13:20:33 -0400 Subject: [PATCH 11/21] Update blog/2023-08-04-oauth-plugin/index.mdx Co-authored-by: Kyle Kelley --- blog/2023-08-04-oauth-plugin/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 558db84..99b2511 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -43,7 +43,7 @@ The Noteable ChatGPT plugin is more or less a proxy to our main API. There's a l ## OAuth configuration -Once you're ready to test out OAuth with your plugin, the first step is to have your plugin hosted somewhere besides `localhost` and for your manifest file (`ai-plugin.json`) to have its auth section set to type oauth. You'll also need to have the client_url and authorization_url point to the endpoints of your OAuth provider for the initial redirect and POST to grab the jwt respectively. +Once you're ready to test out OAuth with your plugin, the first step is to have your plugin hosted somewhere besides `localhost` and for your manifest file (`ai-plugin.json`) to have its auth section set to type oauth. You'll also need to have the `client_url` and `authorization_url` point to the endpoints of your OAuth provider for the initial redirect and POST to grab the jwt respectively. When you click "develop your own plugin" in ChatGPT and give it the domain your plugin is hosted at, it will try to download the manifest file and OpenAPI spec file. If it sees your manifest file has type oauth, it will prompt you to enter the client_id and client_secret from your OAuth provider. After you've put those in, ChatGPT will give you a token that you need to add to your manifest file and then redeploy / restart. If ChatGPT can pull the manifest file and see the new token, then the "develop your own plugin" flow is complete and ChatGPT will give you a plugin application id that you can use to update the redirect_uri in your OAuth provider. From 372af7e302942621eeb049d51210966c7dfce697 Mon Sep 17 00:00:00 2001 From: Matt Kafonek Date: Thu, 3 Aug 2023 13:21:49 -0400 Subject: [PATCH 12/21] Update blog/2023-08-04-oauth-plugin/index.mdx Co-authored-by: Kyle Kelley --- blog/2023-08-04-oauth-plugin/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 99b2511..1f6e5fd 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -68,7 +68,7 @@ A compounding problem was that we were enforcing email verification for username ![Bad Times](./bad_times.svg) -Our solution was to create a second database table we called Principals to represent the login mechanism. A Google, Github, or Auth0 username/password login with the same email all link to the same User account now. We reconfigured our ChatGPT manifest file to proxy the authorize and token endpoints through our plugin so that we could automatically create or link Noteable accounts during the OAuth flow. And we moved the email verification onto our own system instead of within an Auth0 rule, with error handling in the plugin to tell the user that while they did successfully install the Noteable ChatGPT plugin, they still need to click the email verification link before it will successfully create Notebooks or run code for them. +Our solution was to create a second database table we called Principals to represent the login mechanism. A Google, Github, or Auth0 username/password login with the same email all link to the same User account now. We reconfigured our ChatGPT manifest file to proxy the authorize and token endpoints through our plugin so that we could automatically create or link Noteable accounts during the OAuth flow. We moved the email verification onto our own system instead of within an Auth0 rule, with error handling in the plugin to tell the user that while they did successfully install the Noteable ChatGPT plugin, they still need to click the email verification link before it will successfully create Notebooks or run code for them. ![Good Times](./good_times.svg) From 50495f48ea26d820fa714b6847abc7803474505c Mon Sep 17 00:00:00 2001 From: Kafonek Date: Thu, 3 Aug 2023 13:39:41 -0400 Subject: [PATCH 13/21] images for develop your own plugin --- .../2023-08-04-oauth-plugin/develop_plugin1.png | Bin 0 -> 20785 bytes .../2023-08-04-oauth-plugin/develop_plugin2.png | Bin 0 -> 19865 bytes .../2023-08-04-oauth-plugin/develop_plugin3.png | Bin 0 -> 20299 bytes blog/2023-08-04-oauth-plugin/index.mdx | 12 +++++++++++- 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 blog/2023-08-04-oauth-plugin/develop_plugin1.png create mode 100644 blog/2023-08-04-oauth-plugin/develop_plugin2.png create mode 100644 blog/2023-08-04-oauth-plugin/develop_plugin3.png diff --git a/blog/2023-08-04-oauth-plugin/develop_plugin1.png b/blog/2023-08-04-oauth-plugin/develop_plugin1.png new file mode 100644 index 0000000000000000000000000000000000000000..fe3f02c0b1e62b92efedfc39d943c136ac9d4ac7 GIT binary patch literal 20785 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 ZRabgWrsFr-=#sp1#s>H9;`BTc{{bxh>Ei$Z literal 0 HcmV?d00001 diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 1f6e5fd..d818c93 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -45,7 +45,17 @@ The Noteable ChatGPT plugin is more or less a proxy to our main API. There's a l Once you're ready to test out OAuth with your plugin, the first step is to have your plugin hosted somewhere besides `localhost` and for your manifest file (`ai-plugin.json`) to have its auth section set to type oauth. You'll also need to have the `client_url` and `authorization_url` point to the endpoints of your OAuth provider for the initial redirect and POST to grab the jwt respectively. -When you click "develop your own plugin" in ChatGPT and give it the domain your plugin is hosted at, it will try to download the manifest file and OpenAPI spec file. If it sees your manifest file has type oauth, it will prompt you to enter the client_id and client_secret from your OAuth provider. After you've put those in, ChatGPT will give you a token that you need to add to your manifest file and then redeploy / restart. If ChatGPT can pull the manifest file and see the new token, then the "develop your own plugin" flow is complete and ChatGPT will give you a plugin application id that you can use to update the redirect_uri in your OAuth provider. +When you click "develop your own plugin" in ChatGPT and give it the domain your plugin is hosted at, it will try to download the manifest file and OpenAPI spec file. If it sees your manifest file has type oauth, it will prompt you to enter the client_id and client_secret from your OAuth provider. + +![Develop your own Plugin step 1](./develop_plugin1.png) + +![Develop your own Plugin step 2](./develop_plugin2.png) + +After you've put those in, ChatGPT will give you a token that you need to add to your manifest file and then redeploy / restart. + +![Develop your own Plugin step 3](./develop_plugin3.png) + +If ChatGPT can pull the manifest file and see the new token, then the "develop your own plugin" flow is complete and ChatGPT will give you a plugin application id that you can use to update the redirect_uri in your OAuth provider. ![OAuth config](./oauth_config.svg) From d09daf1ea4d51705882fe3fb6f00f127e38ef0aa Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Thu, 3 Aug 2023 11:17:26 -0700 Subject: [PATCH 14/21] include social card --- blog/2023-08-04-oauth-plugin/index.mdx | 2 +- .../oauth-plugin-social-card.png | Bin 0 -> 81465 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 blog/2023-08-04-oauth-plugin/oauth-plugin-social-card.png diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index d818c93..6614e07 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -3,7 +3,7 @@ slug: oauth-for-chatgpt-plugins title: "OAuth for ChatGPT Plugins" authors: [kafonek] description: "How Noteable added OAuth to its ChatGPT Plugin" -# image: "./TODO.png" +image: "./oauth-plugin-social-card.png" tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] --- diff --git a/blog/2023-08-04-oauth-plugin/oauth-plugin-social-card.png b/blog/2023-08-04-oauth-plugin/oauth-plugin-social-card.png new file mode 100644 index 0000000000000000000000000000000000000000..e88e578f59393b2c333c4c17e223324944b279e7 GIT binary patch literal 81465 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 Date: Thu, 3 Aug 2023 11:51:24 -0700 Subject: [PATCH 15/21] deploy social media card when on vercel --- docusaurus.config.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index ee056e2..e36e4d6 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -4,6 +4,14 @@ const lightCodeTheme = require("prism-react-renderer/themes/github"); const darkCodeTheme = require("prism-react-renderer/themes/dracula"); +// process.env.VERCEL_URL + +let siteURL = "https://platform.noteable.io"; + +if (process.env.VERCEL_URL) { + siteURL = `https://${process.env.VERCEL_URL}`; +} + /** @type {import('@docusaurus/types').Config} */ const config = { title: "Noteable Platform", @@ -11,7 +19,7 @@ const config = { favicon: "img/favicon.ico", // Set the production url of your site here - url: "https://platform.noteable.io", + url: siteURL, // Set the // pathname under which your site is served // For GitHub pages deployment, it is often '//' baseUrl: "/", From 4366a861203eed0587c72a738eddb6d86ae43185 Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Tue, 8 Aug 2023 17:55:01 -0700 Subject: [PATCH 16/21] include new intro --- blog/2023-08-04-oauth-plugin/index.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 6614e07..83f3d18 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -9,6 +9,8 @@ tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] ## Introduction +By now, everyone has played with a large language model like ChatGPT, at least a user. You've probably gone through those cycles of copying and pasting your email drafts, code snippets, or posts. There's a lot of power in giving large language models more context. The biggest way to do this is to provide access to documents directly. As a developer, you can enable this experience by writing a ChatGPT Plugin that uses OAuth. + OAuth is a mechanism used to enable Single Sign-On (SSO) across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google, Github, or LinkedIn account. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via the Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. From c823418453d1ceff07fbd94874182fce5dfb95bf Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Tue, 8 Aug 2023 18:55:45 -0700 Subject: [PATCH 17/21] include new intro, outro, and descr --- blog/2023-08-04-oauth-plugin/index.mdx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-04-oauth-plugin/index.mdx index 83f3d18..525a6a2 100644 --- a/blog/2023-08-04-oauth-plugin/index.mdx +++ b/blog/2023-08-04-oauth-plugin/index.mdx @@ -2,7 +2,7 @@ slug: oauth-for-chatgpt-plugins title: "OAuth for ChatGPT Plugins" authors: [kafonek] -description: "How Noteable added OAuth to its ChatGPT Plugin" +description: "How Noteable added OAuth to its ChatGPT Plugin. By now, everyone has played with a large language model like ChatGPT, at least a user. You've probably gone through those cycles of copying and pasting your email drafts, code snippets, or posts. There's a lot of power in giving large language models more context. The biggest way to do this is to provide access to documents directly. As a developer, you can enable this experience by writing a ChatGPT Plugin that uses OAuth." image: "./oauth-plugin-social-card.png" tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] --- @@ -11,6 +11,16 @@ tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] By now, everyone has played with a large language model like ChatGPT, at least a user. You've probably gone through those cycles of copying and pasting your email drafts, code snippets, or posts. There's a lot of power in giving large language models more context. The biggest way to do this is to provide access to documents directly. As a developer, you can enable this experience by writing a ChatGPT Plugin that uses OAuth. +:::tip + +[OpenAI's own plugin docs](https://platform.openai.com/docs/plugins/review) include two use cases that either require OAuth or are greatly augmented by it. + +1. Retrieval over **user-specific** or otherwise hard-to-search knowledge sources + +2. Plugins that give the model **computational** abilities + +::: + OAuth is a mechanism used to enable Single Sign-On (SSO) across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google, Github, or LinkedIn account. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via the Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. @@ -53,7 +63,7 @@ When you click "develop your own plugin" in ChatGPT and give it the domain your ![Develop your own Plugin step 2](./develop_plugin2.png) -After you've put those in, ChatGPT will give you a token that you need to add to your manifest file and then redeploy / restart. +After you've put those in, ChatGPT will give you a token that you need to add to your manifest file and then redeploy / restart. ![Develop your own Plugin step 3](./develop_plugin3.png) @@ -93,3 +103,7 @@ We mentioned at the top of the post that you cannot do OAuth testing in localhos ![Localhost Development](./localhost_dev.svg) ## Final Thoughts + +Integrating OAuth with ChatGPT plugins opens up a world of personalized possibilities, linking the reasoning capabilities of Large Language Models with personalized content. If you're a developer inspired by the idea of creating powerful, user-centric plugins, now's the time to get started. Dive into plugins, explore [OpenAI's documentation on plugins](https://platform.openai.com/docs/plugins/introduction), and make the most of OAuth to unlock the potential of personalized interaction. Join us on this journey and let's redefine what plugins can do! + + From 7386c03dbc5fd3048084b7e5491d43cc9f19c055 Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Tue, 8 Aug 2023 18:58:04 -0700 Subject: [PATCH 18/21] update date to match releasing tomorrow --- .../account_creation.svg | 0 .../bad_times.svg | 0 .../develop_plugin1.png | Bin .../develop_plugin2.png | Bin .../develop_plugin3.png | Bin .../good_times.svg | 0 .../index.mdx | 0 .../localhost_dev.svg | 0 .../oauth-plugin-social-card.png | Bin .../oauth_101.svg | 0 .../oauth_app.svg | 0 .../oauth_combined_app.svg | 0 .../oauth_config.svg | 0 .../user_accounts.svg | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/account_creation.svg (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/bad_times.svg (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/develop_plugin1.png (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/develop_plugin2.png (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/develop_plugin3.png (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/good_times.svg (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/index.mdx (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/localhost_dev.svg (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/oauth-plugin-social-card.png (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/oauth_101.svg (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/oauth_app.svg (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/oauth_combined_app.svg (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/oauth_config.svg (100%) rename blog/{2023-08-04-oauth-plugin => 2023-08-09-oauth-plugin}/user_accounts.svg (100%) diff --git a/blog/2023-08-04-oauth-plugin/account_creation.svg b/blog/2023-08-09-oauth-plugin/account_creation.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/account_creation.svg rename to blog/2023-08-09-oauth-plugin/account_creation.svg diff --git a/blog/2023-08-04-oauth-plugin/bad_times.svg b/blog/2023-08-09-oauth-plugin/bad_times.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/bad_times.svg rename to blog/2023-08-09-oauth-plugin/bad_times.svg diff --git a/blog/2023-08-04-oauth-plugin/develop_plugin1.png b/blog/2023-08-09-oauth-plugin/develop_plugin1.png similarity index 100% rename from blog/2023-08-04-oauth-plugin/develop_plugin1.png rename to blog/2023-08-09-oauth-plugin/develop_plugin1.png diff --git a/blog/2023-08-04-oauth-plugin/develop_plugin2.png b/blog/2023-08-09-oauth-plugin/develop_plugin2.png similarity index 100% rename from blog/2023-08-04-oauth-plugin/develop_plugin2.png rename to blog/2023-08-09-oauth-plugin/develop_plugin2.png diff --git a/blog/2023-08-04-oauth-plugin/develop_plugin3.png b/blog/2023-08-09-oauth-plugin/develop_plugin3.png similarity index 100% rename from blog/2023-08-04-oauth-plugin/develop_plugin3.png rename to blog/2023-08-09-oauth-plugin/develop_plugin3.png diff --git a/blog/2023-08-04-oauth-plugin/good_times.svg b/blog/2023-08-09-oauth-plugin/good_times.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/good_times.svg rename to blog/2023-08-09-oauth-plugin/good_times.svg diff --git a/blog/2023-08-04-oauth-plugin/index.mdx b/blog/2023-08-09-oauth-plugin/index.mdx similarity index 100% rename from blog/2023-08-04-oauth-plugin/index.mdx rename to blog/2023-08-09-oauth-plugin/index.mdx diff --git a/blog/2023-08-04-oauth-plugin/localhost_dev.svg b/blog/2023-08-09-oauth-plugin/localhost_dev.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/localhost_dev.svg rename to blog/2023-08-09-oauth-plugin/localhost_dev.svg diff --git a/blog/2023-08-04-oauth-plugin/oauth-plugin-social-card.png b/blog/2023-08-09-oauth-plugin/oauth-plugin-social-card.png similarity index 100% rename from blog/2023-08-04-oauth-plugin/oauth-plugin-social-card.png rename to blog/2023-08-09-oauth-plugin/oauth-plugin-social-card.png diff --git a/blog/2023-08-04-oauth-plugin/oauth_101.svg b/blog/2023-08-09-oauth-plugin/oauth_101.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/oauth_101.svg rename to blog/2023-08-09-oauth-plugin/oauth_101.svg diff --git a/blog/2023-08-04-oauth-plugin/oauth_app.svg b/blog/2023-08-09-oauth-plugin/oauth_app.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/oauth_app.svg rename to blog/2023-08-09-oauth-plugin/oauth_app.svg diff --git a/blog/2023-08-04-oauth-plugin/oauth_combined_app.svg b/blog/2023-08-09-oauth-plugin/oauth_combined_app.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/oauth_combined_app.svg rename to blog/2023-08-09-oauth-plugin/oauth_combined_app.svg diff --git a/blog/2023-08-04-oauth-plugin/oauth_config.svg b/blog/2023-08-09-oauth-plugin/oauth_config.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/oauth_config.svg rename to blog/2023-08-09-oauth-plugin/oauth_config.svg diff --git a/blog/2023-08-04-oauth-plugin/user_accounts.svg b/blog/2023-08-09-oauth-plugin/user_accounts.svg similarity index 100% rename from blog/2023-08-04-oauth-plugin/user_accounts.svg rename to blog/2023-08-09-oauth-plugin/user_accounts.svg From f8738c1729347dc4d5def87c5ec01d54bcaecf14 Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Tue, 8 Aug 2023 20:52:42 -0700 Subject: [PATCH 19/21] introduce why OAuth section --- blog/2023-08-09-oauth-plugin/index.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/blog/2023-08-09-oauth-plugin/index.mdx b/blog/2023-08-09-oauth-plugin/index.mdx index 525a6a2..1359aa3 100644 --- a/blog/2023-08-09-oauth-plugin/index.mdx +++ b/blog/2023-08-09-oauth-plugin/index.mdx @@ -23,6 +23,8 @@ By now, everyone has played with a large language model like ChatGPT, at least a OAuth is a mechanism used to enable Single Sign-On (SSO) across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google, Github, or LinkedIn account. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. +## Why OAuth? + Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via the Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. There are many OAuth providers out there, and there's nothing stopping you from writing your own. We happen to use [Auth0](https://auth0.com/), so our examples will include their implementation details (such as `authorize` and `/oauth/token` endpoints). OpenAI and Auth0 both have good documentation about OAuth flows, I recommend reading these sections in addition to this blog post if you're working on an OAuth plugin yourself. From f35cf972448dc2bb745e8b704fbb9f9c68c292e1 Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Tue, 8 Aug 2023 21:01:54 -0700 Subject: [PATCH 20/21] create youtube embed component --- blog/2023-08-09-oauth-plugin/index.mdx | 6 +++++- src/components/YouTubeEmbed.tsx | 27 ++++++++++++++++++++++++++ src/components/styles.module.css | 18 +++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/components/YouTubeEmbed.tsx create mode 100644 src/components/styles.module.css diff --git a/blog/2023-08-09-oauth-plugin/index.mdx b/blog/2023-08-09-oauth-plugin/index.mdx index 1359aa3..f1bcd5c 100644 --- a/blog/2023-08-09-oauth-plugin/index.mdx +++ b/blog/2023-08-09-oauth-plugin/index.mdx @@ -7,6 +7,8 @@ image: "./oauth-plugin-social-card.png" tags: [chatgpt, plugins, chatgpt plugins, oauth, security, architecture] --- +import YouTubeEmbed from "@site/src/components/YouTubeEmbed"; + ## Introduction By now, everyone has played with a large language model like ChatGPT, at least a user. You've probably gone through those cycles of copying and pasting your email drafts, code snippets, or posts. There's a lot of power in giving large language models more context. The biggest way to do this is to provide access to documents directly. As a developer, you can enable this experience by writing a ChatGPT Plugin that uses OAuth. @@ -23,6 +25,8 @@ By now, everyone has played with a large language model like ChatGPT, at least a OAuth is a mechanism used to enable Single Sign-On (SSO) across applications. When you install the Noteable ChatGPT plugin, you can choose to login or sign up (it's free!) to Noteable using an existing Google, Github, or LinkedIn account. In this post, the Noteable engineering team wants to share some of the low-level details of how OAuth works, and how it's implemented in Noteable. We hope this helps other plugin developers and the community at large. + + ## Why OAuth? Let’s start with why a plugin would use OAuth, compared to “no auth” or “service level auth”. Simply put, if your plugin or downstream API needs to know about a logged in user, use OAuth. For instance, if you were writing a wikipedia-reading plugin you could skip OAuth because you don’t need to have a logged in user to read Wiki. If the large language model (LLM) is creating Notebooks and running code via the Noteable plugin, which goes through role-based access control (RBAC) permission checks and user-context-aware features, we need to know what user account the request is for. @@ -106,6 +110,6 @@ We mentioned at the top of the post that you cannot do OAuth testing in localhos ## Final Thoughts -Integrating OAuth with ChatGPT plugins opens up a world of personalized possibilities, linking the reasoning capabilities of Large Language Models with personalized content. If you're a developer inspired by the idea of creating powerful, user-centric plugins, now's the time to get started. Dive into plugins, explore [OpenAI's documentation on plugins](https://platform.openai.com/docs/plugins/introduction), and make the most of OAuth to unlock the potential of personalized interaction. Join us on this journey and let's redefine what plugins can do! +Integrating OAuth with ChatGPT plugins opens up a world of personalized possibilities, linking the reasoning capabilities of Large Language Models with personalized content. If you're a developer inspired by the idea of creating powerful, user-centric plugins, now's the time to get started. Dive into plugins, explore [OpenAI's documentation on plugins](https://platform.openai.com/docs/plugins/introduction), and make the most of OAuth to unlock the potential of personalized interaction. Join us on this journey and let's push what ChatGPT + Plugins can do! diff --git a/src/components/YouTubeEmbed.tsx b/src/components/YouTubeEmbed.tsx new file mode 100644 index 0000000..d63a7d5 --- /dev/null +++ b/src/components/YouTubeEmbed.tsx @@ -0,0 +1,27 @@ +import React from "react"; + +import styles from "./styles.module.css"; + +type Props = { + videoId: string; + title: string; +}; + +const defaultProps = { + videoId: "dQw4w9WgXcQ", + title: "YouTube Video", +}; + +const YouTubeEmbed = ({ videoId, title }: Props = defaultProps) => ( +
+