I've read about this but I don't fully understand how to choose.

I have two options:

Public client

  • "A native, browser or mobile-device app. Cognito API requests are made from user systems that are not trusted with a client secret."

Confidential client

  • "A server-side application that can securely store a client secret. Cognito API requests are made from a central server."

I'm making a website. Here is the gist of it:

  • Users can make an account and sign in
  • Once they are signed in, they can upload data, which is sent to our backend and processed in an EC2, which generates basically a list of numbers
  • These numbers are shown to the user only when the user is logged in to their account

My guess is that I should not generate a client secret, and that I should choose public client.

Note: there is no "write" access or running code access. There is simply data upload, which is processed by the same program each time, and reading what that data is (i.e. from an S3 bucket). Nothing fancy, like generating code or running complex things.

  • You have a web app so you can use confidential client. For native apps and progressive web apps, you use a public client.
    – defalt
    Oct 14, 2023 at 20:36
  • @defalt How do I actually go about making a public client? I'm hosting the React app just by posting it to a private GitHub--how would I actually handle the secrets?
    – BigMistake
    Oct 14, 2023 at 22:21
  • Use OIDC PKCE. It is designed for public client. Find an npm package that implements this protocol.
    – defalt
    Oct 15, 2023 at 8:52
  • @defalt Oops, I actually meant to type "confidential client" instead of "public client." However, that link was still helpful to me
    – BigMistake
    Oct 15, 2023 at 20:09

1 Answer 1


Since your application has a back-end that you control, you can (and should) use it as a confidential client. This means that the OAuth flow will involve a trip through the back-end at login, and likely also at refresh (if using JWTs for your session tokens). The browser will send the authorization code (along with other parameters) to the back-end, which will add the client secret and exchange the code for one or more tokens. Your back-end receives these tokens and will either generate its own session token or use the Cognito tokens directly for session management, and in either case send the token(s) back to the browser. This provides greater security than having the session initiation and management live entirely in the browser (partially but not entirely because that means you can't have a client secret).

If your app had no back-end that you control (for example, your server serves static HTML and JS, which run in the browser with no further interaction with your server, or your app was a desktop/mobile app instead of a web app at all), then you don't have any ability to keep a client secret confidential. In such cases, you must use a public client flow, but this weakens the security. To be clear, it's possible to do it securely, but it's brittle. Confidential client flows - especially authorization code with PKCE and client secret - have more defense-in-depth, such that even if one area is implemented incorrectly there's a chance for another layer to catch any problems without catastrophic failure.

  • It does have a backend, but the EC2 is inactive 99% of the time, and only starts up when a user uploads data. The website is a react app on AWS Amplify, but it is barely a webapp: we aren't doing anything fancy; all the user is able to do is log in and view the numbers sent over from the back end. I guess the reason why I'm hesitant is I don't know where to store this client secret or how to send it properly to the front end. The backend checks/uses tokens, but how and what exactly does that mean? I'd prefer not to have a server running 24/7 for cost purposes.
    – BigMistake
    Oct 14, 2023 at 22:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .