diff --git a/content/all-you-need-to-know-about-user-session-security/image153x-p-800.png b/content/all-you-need-to-know-about-user-session-security/image153x-p-800.png new file mode 100644 index 00000000..30b51afd Binary files /dev/null and b/content/all-you-need-to-know-about-user-session-security/image153x-p-800.png differ diff --git a/content/all-you-need-to-know-about-user-session-security/image163x-p-800.png b/content/all-you-need-to-know-about-user-session-security/image163x-p-800.png new file mode 100644 index 00000000..23a69d40 Binary files /dev/null and b/content/all-you-need-to-know-about-user-session-security/image163x-p-800.png differ diff --git a/content/all-you-need-to-know-about-user-session-security/image173x-p-800.png b/content/all-you-need-to-know-about-user-session-security/image173x-p-800.png new file mode 100644 index 00000000..cf1f3f73 Binary files /dev/null and b/content/all-you-need-to-know-about-user-session-security/image173x-p-800.png differ diff --git a/content/all-you-need-to-know-about-user-session-security/image183x-p-800.png b/content/all-you-need-to-know-about-user-session-security/image183x-p-800.png new file mode 100644 index 00000000..26e924e2 Binary files /dev/null and b/content/all-you-need-to-know-about-user-session-security/image183x-p-800.png differ diff --git a/content/all-you-need-to-know-about-user-session-security/image193x-p-800.png b/content/all-you-need-to-know-about-user-session-security/image193x-p-800.png new file mode 100644 index 00000000..e48a4bb8 Binary files /dev/null and b/content/all-you-need-to-know-about-user-session-security/image193x-p-800.png differ diff --git a/content/all-you-need-to-know-about-user-session-security/image203x-p-800.png b/content/all-you-need-to-know-about-user-session-security/image203x-p-800.png new file mode 100644 index 00000000..88814fad Binary files /dev/null and b/content/all-you-need-to-know-about-user-session-security/image203x-p-800.png differ diff --git a/content/all-you-need-to-know-about-user-session-security/index.md b/content/all-you-need-to-know-about-user-session-security/index.md new file mode 100644 index 00000000..c0e1665f --- /dev/null +++ b/content/all-you-need-to-know-about-user-session-security/index.md @@ -0,0 +1,284 @@ +--- +title: All you need to know about user session security +date: "2019-06-07" +description: "This article covers extensive conversations with over 70+ developers exploring different session management practices, identifying issues and converging on a solution to these issues. " +cover: "all-you-need-to-know-about-user-session-security.png" +category: "sessions, featured" +author: "Rishabh Poddar" +--- + +What follows is a 2 part series on session management — inspired by extensive conversations with over 70 developers and our own intensive research. We will explore different session management practices, identify issues and converge on a solution to these issues. Through it all, I hope to leave you with clarity on deciding how to manage user sessions (and auth tokens) for your application. In 20 minutes, we summarise all the important information it took us hundreds of hours to obtain and document. + +This is part 1 in a two-part series on session management. + +*Part 1: Introduction to session management, analysis of most commonly used session flows, and best practices* + +*[Part 2](/blog/the-best-way-to-securely-manage-user-sessions): Analysis of a new, open source session flow that is secure and easy to integrate into existing systems — provided by [SuperTokens](https://supertokens.com)* + +Specifically, in part 1, we cover + +- [Why is session security important?](#why-is-session-security-important) +- [JWT vs Opaque access tokens](#jwts-vs-opaque-access-tokens) +- [Common attacks on sessions](#common-attacks-on-sessions) +- [Detection vs Prevention of stolen auth tokens](#detection-vs-prevention-of-stolen-auth-tokens) +- [Common ways of implementing session management flows](#common-ways-of-implementing-session-management-flows) +- [Best practices for attack mitigation](#best-practices-for-attack-mitigation) + +*Note: Do not confuse session management with OAuth, as the latter is a protocol designed only for the purpose of delegation. Session management, for the purpose of this article, is about how auth tokens are handled, stored and changed during an active session — whether it be for OAuth flows, or for server-client session flows.* + + +## Why is session security important? + +Session security is an important consideration in the design of any system that requires communication between a server and a client. Improper security can lead to user accounts being vulnerable to unauthorized access. OWASP (Open Web Application Security Project — leading authority for security) considers the improper implementation of authorisation / authentication as the [second biggest risk](https://owasp.org/www-project-top-ten/2017/) to application security. Several notable hacks illustrate this point: + + +- The Docker hub database hack earlier this year resulted in stolen Github access tokens. [Source](https://www.trustedreviews.com/reviews/google-pixel-4) + +- Gitlab had a vulnerability where all its user’s auth tokens were exposed in the URLs, had no expiry time and were susceptible to brute force attacks due to their short length. [Source](https://threatpost.com/session-hijacking-bug-exposed-gitlab-users-private-tokens/127747/) + +- A software bug made it possible to steal access tokens — affecting 90 million Facebook accounts. [Source](https://about.fb.com/news/2018/09/security-update/) + +- Youtube influencers’ accounts compromised for several days via session token theft to completely hijack their account and change their video content. The tokens were stolen via a malware installed on the victim’s computer. [Source](https://twitter.com/MarcoStyleNL/status/1192179230341251075?s=09) + +It is tricky, time-consuming and expensive to correctly implement user session management. According to an [a16z](https://a16z.com/about/) operating partner (top tier VC) and former Box CSO (Chief Security Officer), **authentication and authorisation is the number one spending cost for organisations when it comes to their security budget.** [Source](https://www.youtube.com/watch?v=FdIW7BiCBtI&t=524s) + +This is the tip of the iceberg but we hope it is enough for anyone to realize that they could be the next Titanic if they do not correct their course. + +![titanic gif](./titanic.gif) + +## JWTs vs Opaque access tokens + +We’ll briefly explore the two predominant types of tokens that are used in session management. Several of the flows we discuss require an understanding of these tokens. + +### JSON Web Tokens ([JWT](https://jwt.io/)) + +- Each JWT contains specific information that can be interpreted by any party that has that token. For example, this information can contain the user ID of the user for whom it was issued. +- An advantage of using JWTs is scalability as the backend does not need to do a database lookup for every API call. +- The drawback is that revoking a single token on demand (before it expires) can be difficult if methods like blacklisting are not used (which impacts the scalability of the solution). However, one can revoke all tokens by changing the signing key. + +### Opaque Tokens +- These are random strings which act as pointers to information that is held only by the system that issues them. +- These require a database/cache lookup each time they are used. +- A single token can easily be revoked on demand. + +While these two token types have different properties, theft of either type can lead to unauthorised access to a user’s account. + +### Common attacks on sessions + +Auth tokens are stored on the frontend and the backend and are frequently sent over the network (depending on the session flow). As such, they are vulnerable to several types of attacks. + +- Man in the Middle attack +- OAuth token theft +- XSS +- CSRF +- Database/filesystem access +- Session fixation +- Brute force attack +- Social Engineering / physical access + +**While it may seem that these attacks are unlikely, it is important to take session security seriously and deploy appropriate measures.** The vulnerability of the system is based on the cumulative probabilities of all the types of attacks. + +![man waving gif](./manwavinghands.gif) + +Further on, we discuss how each of these attacks could lead to token theft and we explore best practices to mitigate against these types of attacks. + +To keep tokens safe, a system architect should not only prevent tokens from being stolen but, as a fail-safe, also ensure that should token theft occur, the system is able to detect it as quickly as possible. Detection is an important concept to consider and will be explored in the next section. + +## Detection vs Prevention of stolen auth tokens + +Prevention is a first line of defense and all attempts should be made to minimize theft. However, auth tokens are fundamentally susceptible to theft because they are transmitted to an untrusted party (the app’s frontend). Hence, detection of token theft has an important role to play in the security of the system. Existing detection methods rely largely on **heuristic algorithms** such as tracking sudden changes in IP addresses and browser (or mobile) fingerprints and flagging “unusual user behaviour”. Unfortunately, these methods themselves can be inaccurate, easy to spoof and difficult to implement. However, there is a reliable way to integrate detection of theft in the session management flow and in [part 2](/blog/the-best-way-to-securely-manage-user-sessions), we propose a flow that does that. + +On a related note, in cases where session vulnerabilities are publicly exposed, companies may release statements stating that there was no indication that the vulnerability was exploited. However, what they fail to mention is how extensively their system would be able to detect token theft in the first place! + + +## Common ways of implementing session management flows +We’ve identified the most commonly used session management flows and classified them into 5 groups. + +1. Long-lived access token +2. Short — Medium term lived access token used to get a new access token +3. Short — Medium term access token whose usage extends its expiry +4. Short-lived access token +5. Short-lived access token with long-lived refresh token + +### 1. Long-lived access token + +![live long access](./image173x-p-800.png) + +- If the user voluntarily logs out, the access token is revoked and cleared from the frontend. + +**Damage Analysis** +There are no critical auth tokens in this case. However, this method frequently exposes the user’s credentials during transit — making it susceptible to attack. + +*Effect of stolen auth tokens:
+If the token is stolen, the attacker will only be able to do damage for a short period of time.* + +*Detection of theft:
+Token theft may only be detected through the use of heuristic algorithms or if the user notifies the provider/developer of the service.* + +*Once detected:
+If the flow is implemented using JWTs, it may be difficult to revoke the token. However, stolen Opaque access tokens can be easily revoked.* + + +### 2. Short-Medium term lived access token used to get a new access token + +![access token used to get a new access token](./image153x-p-800.png) + +- The new access token can be used by the frontend even if the previous token has not expired. +- If the user voluntarily logs out, the access token is revoked on the backend and cleared from the frontend. +- It is likely that a user will be logged out if the access token is short lived. + +**Damage analysis**
+The critical auth token is perpetually exposed over three attack surfaces — the frontend, during transit and the backend. + +*Effect of stolen auth tokens:*
+An attacker must constantly renew their token to maintain unauthorised access. + +*Detection of theft:*
+To stay logged in, both the attacker and victim need to request the server for a new access token before the current (stolen) token expires. Both would do this using the same access token. If the same token is used twice for the request, then the system could deduce that there has been a theft — depending on how the frontend is implemented. A shorter-lived access token would enable quicker detection of theft, but it may also result in poor user experience due to repeated logouts when there is no theft. + +*Once detected:
+The access token associated with this session would need to be revoked. It may be complex to stop the attack if the access token is a JWT.* + +### 3. Short-Medium term lived access token whose usage extends their expiry + +![lived access token whose usage extends their expiry](./image163x-p-800.png) + +- If the user voluntarily logs out, the access token is revoked and cleared from the frontend. +**Damage Analysis**
+The critical auth token is perpetually exposed over three attack surfaces — the frontend, during transit and the backend. Note that this flow does not apply to JWTs as extended their expiry time would result in a change of the token value itself (thank you [Mehmood Deshmukh](https://medium.com/@meshde) for pointing this out). + +*Effect of stolen auth tokens:*
+As long as either the victim or the attacker is active, the attacker would be able to maintain unauthorised access. + +*Detection of theft:*
+Token theft may only be detected through the use of heuristic algorithms or if the user notifies the provider/developer of the service. + +*Once detected:*
+The access token associated with this session would need to be revoked. + +### 4. Short-lived access tokens + +![short lived access tokens](./image173x-p-800.png) + +- If the user voluntarily logs out, the access token is revoked and cleared from the frontend. + +**Damage Analysis**
+There are no critical auth tokens in this case. However, this method frequently exposes the user’s credentials during transit — making it susceptible to attack. + +*Effect of stolen auth tokens:*
+If the token is stolen, the attacker will only be able to do damage for a short period of time. + +*Detection of theft:*
+Token theft may only be detected through the use of heuristic algorithms or if the user notifies the provider/developer of the service. + +*Once detected:*
+Access tokens need not be revoked since they are short lived. However, if needed, Opaque access tokens can be revoked by removing them from the database. + +### 5. Short-lived access token with long-lived refresh token + +![short-lived access token with long-lived refresh token](./image183x-p-800.png) + +- If the user voluntarily logs out, the access token is revoked and cleared from the frontend. +**Damage analysis**
+The critical auth token (refresh token) is perpetually exposed over two attack surfaces, the frontend, and the backend and occasionally exposed over transit. + +*Effect of stolen auth tokens:*
+Access token stolen: The attacker will have unauthorised access for a short period of time (until token expiry). + +Refresh token stolen: The attacker can use the stolen refresh token to get new access tokens and have unauthorised access to the victim’s account over a long period of time. In rare scenarios (described below), this theft can be detected and the damage can be minimised. + +*Detection of theft:*
+Access token stolen: This theft may only be detected through use of heuristic algorithms or if the user notifies the provider / developer of the service. + +Refresh token stolen: Detection of theft is possible in certain scenarios and implementations. For example: + +- One implementation could result in previous access tokens being immediately revoked upon generation of a new access token. This enables the system to recognize theft in the case when the attacker and victim are online at the same time. For example: if the attacker uses the refresh token, the victim’s access token would be revoked — causing the victim to request for a new access token. This would result in another request from the attacker and so on. If the backend could detect short interval requests for new access tokens, then it would be possible to deduce that there has been a theft. + +*Once detected:*
+Access tokens need not be revoked since they are short lived. However, if needed, Opaque access tokens can be revoked easily by removing them from the database. + +*Refresh tokens can be revoked easily by removing them from the database.* + +These flows are not designed with token theft detection as a requirement. In [Part 2](/blog/the-best-way-to-securely-manage-user-sessions), we propose an alternate session flow that we believe would be far more secure. For now, we’ll revisit the types of attacks that sessions are vulnerable to and some steps to mitigate against the risks. + +## Best practices for attack mitigation + +### Man in the middle attacks + +![man in the middle attacks](./image193x-p-800.png) + +Man in the middle (MITM) attacks are possible in the following scenarios. + +1. When using HTTP or incorrectly implementing HTTPS:
If the application does not use https and secure cookies, an attacker could connect to the same network as the victim, monitor the network packets and see the auth tokens in plain text during transit. Often, even when the application has an SSL certificate, an incorrect implementation can lead to MITM attacks. For example, ESPN.com sends auth cookies over unsecured HTTP (as of 10th May 2019) and this [Netcraft](https://www.netcraft.com/blog/95-of-https-servers-vulnerable-to-trivial-mitm-attacks/) article elaborates on the prevalence of incorrectly implemented https. + +2. When using a Proxy:
Two of the last three organizations I worked at, monitored all the traffic on their network. At workplaces, devices likely use the corporate wifi network. Companies can enable the connected devices to trust their network proxy as an SSL Certificate Authority as a prerequisite to connect to the wifi. This would enable them (or a malicious actor) to see auth token information during transmission. + +**Methods of prevention:**
+The easiest way to protect against this type of attack is to use https and secure cookies throughout your application. However, this doesn’t prevent attacks that result from the use of a proxy. One could take extra precaution by using public/private keys that are fixed per device. The frontend and backend would exchange these public keys at the point of initialization (before the user logs in). For subsequent communication, the token data could be encrypted using the public keys. This limits transit attacks to only the initial public key exchange. There is a modification that would enable the prevention of replay attacks but that is not covered in this blog post. (Feel free to [reach out](mailto:team@supertokens.com) if you would like to know more). Regardless, some of the described flows (flow 5 and the proposed flow in [Part 2](/blog/the-best-way-to-securely-manage-user-sessions)) aim to minimize exposure of the critical token by reducing its frequency of transit. + +### OAuth token theft + +If an application provides access/refresh tokens to other apps via OAuth, then there is a risk of the main app’s auth tokens being stolen if the other app’s servers are compromised. For reference, see the recent docker hub case study mentioned at the start. + +The solution to this is to have appropriate measures in place to detect stolen refresh tokens and to use only short-lived access tokens. + +### XSS Attack + +In XSS, an attacker can maliciously inject Javascript code into an application running on the victim’s browser / mobile device. The injected code reads and transmits auth tokens to the attacker (read more about XSS attacks [here](https://owasp.org/www-community/attacks/xss/)). Malicious JS code can be injected in a variety of ways: Inadequate user input checking; Manipulating the user to copy & paste some JS into their browser console; Injecting malicious JS via a third party dependency the website / hybrid app depends on. + +For websites: This can be prevented fairly easily by using HttpOnly or Secure cookies to store auth tokens. [Do not use localStorage](https://dev.to/rdegges/please-stop-using-local-storage-1i04) to store auth tokens, as they are accessible by javascript. All described session flows can be protected against this attack by following this recommendation. + +For hybrid / JS-based apps (like react-native): Preventing this attack could be difficult. One way is to make sure that all the dependencies being used are “secure”, however, this is time-consuming and expensive. Ultimately, having token theft detection in place is the only real solution in this scenario. + +### CSRF + +This attack is not used to steal auth tokens — instead, it allows an attacker to piggyback on an existing active session (read more [here](https://owasp.org/www-community/attacks/csrf)). + +Prevention of CSRF attacks typically requires the use of an anti-CSRF token or SameSite cookies. However, there are other methods that can be used to solve this in a way that is seamless with the whole authentication process. Please contact us for more details. + +### Database/filesystem access + +If an attacker manages to access the database/file system (either via database injection attack or actual server access), they could potentially get hold of currently active auth tokens or the JWT / SSL private key *(theft of these keys is potentially even worse than stolen passwords).* This would enable them to easily hijack sessions — leading to serious security consequences. Do note that the attacker could be an employee within your organisation (especially for high growth startups — are all the proper access controls in place for employee database/server access?). + +To control damage caused by unauthorized access to your database or filesystem, you could do the following: + + +- Store only the hashed versions of the refresh and access tokens in your database to prevent an attacker from hijacking any live session. This recommendation is applicable to all implementations described above. + +- Using JWTs requires the private key to be stored on the server — which is susceptible to theft. If the attacker obtains the private key, they will be able to hijack both current and future sessions. To limit the damage, the private key used to sign the JWTs will need to be changed — instantly invalidating all current JWTs. In methods that use a refresh token (flow 5, Part 1 and the proposed flow in [Part 2](/blog/the-best-way-to-securely-manage-user-sessions)), changing the private key will not affect the user experience as the refresh token will be used to generate a JWT signed with the new private key. + +### Session fixation +This may be possible if you have anonymous sessions for your web application (read more [here](https://owasp.org/www-community/attacks/Session_fixation)) + +The best way to solve this is to generate a new set of auth tokens each time a user logs in and to invalidate the old ones if any. This is done per device and not per user. Doing so will safeguard all described session flows against this attack. + +### Brute force attack + + +![hulkk](./image203x-p-800.png) + +An attacker with sufficient resources can incessantly ‘guess’ auth tokens until one of the attempts proves successful. This would provide them with all the access the stolen token confers. + +The best way to prevent this is to use long auth tokens with high entropy. + +### Social engineering / Physical access + +An attacker with physical access to a victim’s device can steal auth tokens in multiple ways. + +- An attacker could simply read the cookies (even if they are secure or HttpOnly) by inspecting the application page if the service is accessible via a browser. On a mobile app, this is harder but still possible. + +- Depending on how an app’s session flows are implemented, an attacker could steal a user’s auth tokens even after the victim has logged out of the app. [This](https://www.youtube.com/watch?v=RO-K7oIkjFQ) video from 2013 shows how Twitter did not invalidate the session cookie even after the user logged out. As a commenter points out, this was still occurring even in 2016! + + +Both of the above issues are even more probable if an app is being used on a public computer — which has to be factored in. + +The only way to really fix this problem is to have token theft detection in place and to enable users to log out of all devices. This would mean being able to revoke all refresh and access tokens for that user. Some methods that have long lived JWT access tokens, might find this difficult to do. + +This wraps up the best practices to prevent common types of attacks and this section of the post. We hope it helps and provides the answers you were looking for. Please do leave any comments you have. + + +## Part 2 + +Studying all these session flows enabled us to conceptualize a flow (inspired by [IETF RFC 6819](https://datatracker.ietf.org/doc/html/rfc6819)) which enables greater security and detection of theft. We subsequently built the flow for our own service ([Qually.com](https://qually.com)) and, on request of the developer community, decided to open source our code. Click the button below to navigate to a post which discusses this flow and has links to the GitHub repo — should you be interested. Do check it out and let us know what you think! + +Go to part 2 \ No newline at end of file diff --git a/content/all-you-need-to-know-about-user-session-security/manwavinghands.gif b/content/all-you-need-to-know-about-user-session-security/manwavinghands.gif new file mode 100644 index 00000000..41e3d9bc Binary files /dev/null and b/content/all-you-need-to-know-about-user-session-security/manwavinghands.gif differ diff --git a/content/all-you-need-to-know-about-user-session-security/titanic.gif b/content/all-you-need-to-know-about-user-session-security/titanic.gif new file mode 100644 index 00000000..58119fab Binary files /dev/null and b/content/all-you-need-to-know-about-user-session-security/titanic.gif differ diff --git a/content/auth0-alternatives-auth0-vs-okta-vs-cognito-vs-supertokens/index.md b/content/auth0-alternatives-auth0-vs-okta-vs-cognito-vs-supertokens/index.md index 0fd50450..cdad76ac 100644 --- a/content/auth0-alternatives-auth0-vs-okta-vs-cognito-vs-supertokens/index.md +++ b/content/auth0-alternatives-auth0-vs-okta-vs-cognito-vs-supertokens/index.md @@ -191,8 +191,7 @@ At the time of writing this article, the SuperTokens feature set is completely f - #### Managed Service: - Free for the first **5000 MAUs** . - - **$29/month** for every **5000 MAUs** beyond the free limit of up to **50000 MAUs**. - - Custom pricing beyond **50000 MAUs** + - 2 cents / MAU post the first **5000 MAUs**. ### So is SuperTokens the way to go? SuperToken's feature set and pricing make it a great choice for startups and mid-level businesses, but it may not be the best fit for large organisations that require enterprise features. diff --git a/content/how-to-create-an-invite-only-auth-flow/index.md b/content/how-to-create-an-invite-only-auth-flow/index.md index 99cbae8c..e2243a1b 100644 --- a/content/how-to-create-an-invite-only-auth-flow/index.md +++ b/content/how-to-create-an-invite-only-auth-flow/index.md @@ -29,13 +29,13 @@ Follow the prompts on-screen and set up an app with a React frontend, and NodeJs We can now start customizing the authentication flows to enable invite-only authentication ## Step 1: Disable Sign Ups -If you were to run the example application now, you will be greeted with the authentication page. This page allows you to sign users up. We will need to disable the sign-up UI on the frontend and disable the sign up API on the backend. +If you were to run the example application now, you would be greeted with the authentication page. This page allows you to sign users up. We will need to disable the sign-up UI on the frontend and disable the sign up API on the backend. ![SuperTokens Sign Up screen](./sign-in-screen.png) ### Disable the sign up UI in SuperTokens Frontend config -We can customize the frontend UI and use CSS to to hide the sign up button. +We can customize the frontend UI and use CSS to hide the sign up button. ```tsx import SuperTokens from "supertokens-auth-react"; @@ -102,12 +102,12 @@ SuperTokens.init({ ## Step 2: Creating the invite-only flow ### Create a protected API that will create users and send invite links -To create users and send them an invite links we will need to create an API on the backend which will: +To create users and send them invite links we will need to create an API on the backend which will: - Call the `signUp` function from the SuperTokens backend SDK using the user's email and a fake password. This fake password should be unguessable and should be shared across all invited users. - Generate a password reset link and send that as an invite link to the user's email. - Once the user clicks the link, they will be shown a page asking them to input their password after which, they can login. -- Finally we add an access control check to make sure that only users with the `admin` role can add additional users. +- Finally, we add an access control check to make sure that only users with the `admin` role can add additional users. ```ts @@ -144,7 +144,7 @@ app.post("/create-user", verifySession({ >Note: > - The code above uses the default password reset path for the invite link (`/auth/reset-password`). You can create custom UI hosted on another path and use the password reset functions provided by the SuperTOkens frontend SDK to call the password reset token consumption API from the frontend. -> - Additionally the `sendResetPasswordEmail` function uses the default password reset email(or the one customized using the emailDelivery config). If you would like to create the reset password link and send it yourself, you can use the `createResetPasswordLink` function to generate the password reset string. +> - Additionally, the `sendResetPasswordEmail` function uses the default password reset email(or the one customized using the emailDelivery config). If you would like to create the reset password link and send it yourself, you can use the `createResetPasswordLink` function to generate the password reset string. ### Ensure that invited users have reset their passwords @@ -220,4 +220,4 @@ SuperTokens.init({ And that's it! Your app now only allows invited users to log in. Once a user is invited they will be sent an email asking to reset their password post which they are able to sign in. ## Conclusion -Although there a few customizations that needed to be made, setting up an invite only flow with SuperTokens is pretty straight forward. You can find the related [documentation for the invite flow here](https://supertokens.com/docs/emailpassword/common-customizations/disable-sign-up/emailpassword-changes) if you need the code for other languages/frameworks. \ No newline at end of file +Although there are a few customizations that needed to be made, setting up an invite only flow with SuperTokens is pretty straight forward. You can find the related [documentation for the invite flow here](https://supertokens.com/docs/emailpassword/common-customizations/disable-sign-up/emailpassword-changes) if you need the code for other languages/frameworks. \ No newline at end of file diff --git a/content/how-we-cut-our-aws-costs-part-2/index.md b/content/how-we-cut-our-aws-costs-part-2/index.md new file mode 100644 index 00000000..93251ea2 --- /dev/null +++ b/content/how-we-cut-our-aws-costs-part-2/index.md @@ -0,0 +1,64 @@ +--- +title: How we used multi-tenancy to cut our AWS costs by 50% +date: "2023-10-01" +description: "Part 2 in a series of howe we were able to cut down our AWS infrastructure costs by more than 50%" +cover: "how-we-cut-our-aws-costs-part-2.png" +category: "programming" +author: "Joel Coutinho" +--- + +[**Part 1: How does the SuperTokens managed service work and why does it need to change.**](./how-we-cut-our-aws-costs/) + +**Part 2: Using multi-tenancy to cut our AWS infra costs by by more than 50%** + +In this part we will go over SuperTokens Multi-tenancy feature and how it evolved our deployment cycle to cut our AWS billing by 50%. + +Here's what we covered in our [last post](./how-we-cut-our-aws-costs/): +- SuperTokens infrastructure and deployment cycle. +- Improvements made to the SuperTokens deployment cycle to speed up production deployment times by 30% +- How our infra costs were not sustainable and why it needed to change. + +## What is multi-tenancy? + +As mentioned in Part 1, "We saw multi-tenancy as an opportunity to optimize the utilization of our EC2 instances by consolidating our core instances. This would cut down our costs while also providing the expected performance"... But what does that mean? Lets break it down. Multi-tenancy is a feature, typically used by B2B SaaS companies to allow multiple organizations to sign up to their SaaS app, with the ability for each organization to have their own login methods or SSO configurations. Additionally, user pools can also be segmented. Heres how it helped us. + +## How we implemented SuperTokens Multi-tenancy + +With multi-tenancy we re-architected the way we host and manage our users. Initially whenever a signed up and created an app with SuperTokens, it would trigger the following flow: + +![SuperTokens Old Deployment Process](./supertokens-deployment-process.png) + +In this process each development and production SuperTokens core ran in their own separate EC2 instances. With Multi-tenancy we now treat all SuperTokens customers as tenants. This means that we could now host multiple users on a single SuperTokens instance. Our deployment process now looks like this: + +![SuperTokens New Deployment Process](./supertokens-deployment-process-new.png.png) + +As you can see in the new deployment strategy, when a new user signs up, we now create a new tenant in a SuperTokens instance. These instances run in `T3 large` instances. In our testing, for development mode, up to 100 tenants can be run seamlessly on a single instance and for production mode, up to 50 tenants can be created on single instance. + +![SuperTokens infrastructure](./supertokens-infrastructure.png) + +## What are the benefits of the new architecture? + +### 1. Cost Savings + +Well the biggest difference post this change is the cost savings. + +Heres a bill for the month of July before the multi-tenancy changes kicked-in: + +![SuperTokens AWS bill for July](./supertokens-aws-bill-july.png) + +And heres the bill for September, post the changes going live + +![SuperTokens AWS bill for September](./supertokens-aws-bill-september.png) + +When compared, its **54%** down + +![SuperTokens Pricing comparison](./supertokens-pricing-comparison.png) + +### 2. Improved start up time + +Another improvement was app startup time. In the new architecture, creating a new user is as simple as creating a new tenant. When compared to the old process, the new architecture is about 94% faster and new apps can be crated in seconds. + + +## Conclusion + +Multi-tenancy with SuperTokens is a powerful feature that enables businesses to create unique authentication flows for their customers, segment users into unique user pools and automatically create new new tenants. For SuperTokens, multi-tenancy allowed us to consolidate our user applications to save on resources, but, your use case maybe very different. You can learn more about how multi-tenancy works and the experiences it enables by visiting the [multi-tenancy feature page](https://supertokens.com/features/multi-tenancy) \ No newline at end of file diff --git a/content/how-we-cut-our-aws-costs-part-2/supertokens-aws-bill-july.png b/content/how-we-cut-our-aws-costs-part-2/supertokens-aws-bill-july.png new file mode 100644 index 00000000..6720f579 Binary files /dev/null and b/content/how-we-cut-our-aws-costs-part-2/supertokens-aws-bill-july.png differ diff --git a/content/how-we-cut-our-aws-costs-part-2/supertokens-aws-bill-september.png b/content/how-we-cut-our-aws-costs-part-2/supertokens-aws-bill-september.png new file mode 100644 index 00000000..5f5e5217 Binary files /dev/null and b/content/how-we-cut-our-aws-costs-part-2/supertokens-aws-bill-september.png differ diff --git a/content/how-we-cut-our-aws-costs-part-2/supertokens-deployment-process-new.png.png b/content/how-we-cut-our-aws-costs-part-2/supertokens-deployment-process-new.png.png new file mode 100644 index 00000000..9dc1c8de Binary files /dev/null and b/content/how-we-cut-our-aws-costs-part-2/supertokens-deployment-process-new.png.png differ diff --git a/content/how-we-cut-our-aws-costs-part-2/supertokens-deployment-process.png b/content/how-we-cut-our-aws-costs-part-2/supertokens-deployment-process.png new file mode 100644 index 00000000..2fee6575 Binary files /dev/null and b/content/how-we-cut-our-aws-costs-part-2/supertokens-deployment-process.png differ diff --git a/content/how-we-cut-our-aws-costs-part-2/supertokens-infrastructure.png b/content/how-we-cut-our-aws-costs-part-2/supertokens-infrastructure.png new file mode 100644 index 00000000..1cd7d0cc Binary files /dev/null and b/content/how-we-cut-our-aws-costs-part-2/supertokens-infrastructure.png differ diff --git a/content/how-we-cut-our-aws-costs-part-2/supertokens-pricing-comparison.png b/content/how-we-cut-our-aws-costs-part-2/supertokens-pricing-comparison.png new file mode 100644 index 00000000..f15def7e Binary files /dev/null and b/content/how-we-cut-our-aws-costs-part-2/supertokens-pricing-comparison.png differ diff --git a/content/how-we-cut-our-aws-costs/index.md b/content/how-we-cut-our-aws-costs/index.md index 5748b21c..13813517 100644 --- a/content/how-we-cut-our-aws-costs/index.md +++ b/content/how-we-cut-our-aws-costs/index.md @@ -11,6 +11,8 @@ In this two part series we will go over SuperTokens manged service infrastructur **Part 1: How does the SuperTokens managed service work and why does it need to change.** +[**Part 2: Using multi-tenancy to cut our AWS infra costs by by more than 50%**](./how-we-cut-our-aws-costs-part-2/) + ## Introduction The SuperTokens managed service powers numerous web products, mobile applications, and services and is primarily hosted on AWS. Our infrastructure leverages a suite of AWS tools, including AWS RDS for our database, EC2 instances for SuperToken deployments, and System Manager for instance management and automation. Over time, we've refined our deployment cycle to enhance stability, fault tolerance, and cost efficiency but our most recent update has yielded our biggest savings yet, slashing costs by over 50% while achieving [record scalability](https://twitter.com/supertokensio/status/1701600309397852270). @@ -46,7 +48,7 @@ So what prompted us to change our deployment process? ## Why we had to change our deployment process The past year has been quite a ride for SuperTokens. We released a host of new features and saw a big uptick in users. But, as our user numbers climbed, so did our infrastructure costs. With our AWS credits running out soon, we knew we had to do something to cut our expenses. -With the release of our new multi-tenancy feature we saw the opportunity to consolidate core instances to optimize the utilization of our EC2 instances to cut down our costs while also providing the expected performance. +With the release of our new multi-tenancy feature we saw it as an opportunity to optimize the utilization of our EC2 instances by consolidating our core instances. This would cut down our costs while also providing the expected performance. In part 2 we will go over the changes we made to achieve this. diff --git a/src/blog-details.js b/src/blog-details.js index 2a082f31..9c49b532 100644 --- a/src/blog-details.js +++ b/src/blog-details.js @@ -96,16 +96,4 @@ module.exports = [ cover: "the-best-way-to-securely-manage-user-sessions.png" } }, - { - fields: { - slug: "/all-you-need-to-know-about-user-session-security", - }, - frontmatter: { - title: "All you need to know about user session security", - description: "This article covers extensive conversations with over 70+ developers exploring different session management practices, identifying issues and converging on a solution to these issues. ", - category: "sessions, featured", - date: "June 07, 2019", - cover: "all-you-need-to-know-about-user-session-security.png" - } - }, ] \ No newline at end of file diff --git a/src/styles/style.css b/src/styles/style.css index 1d7c8841..46881c78 100644 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -473,4 +473,29 @@ section[itemprop="articleBody"] img[src$=".gif"] { display: block; max-width: 100%; margin: 0 auto; +} + +.primary-button{ + font-family: Rubik,sans-serif; + + display: block; + width: 200px; + margin: 40px auto; + border-radius: 6px; + background-color: #f93; + box-shadow: 2px 2px 6px 0 rgba(0,0,0,.16); + font-size: 24px; + line-height: 40px; + font-weight: 700; + text-align: center; + + padding: 9px 15px; + color: #fff; + border: 0; + text-decoration: none !important; + cursor: pointer; +} + +.primary-button:hover{ + box-shadow: 2px 2px 20px 0 rgba(0,0,0,.16); } \ No newline at end of file diff --git a/static/blog-meta-images/how-we-cut-our-aws-costs-part-2.png b/static/blog-meta-images/how-we-cut-our-aws-costs-part-2.png new file mode 100644 index 00000000..ed89a1da Binary files /dev/null and b/static/blog-meta-images/how-we-cut-our-aws-costs-part-2.png differ diff --git a/static/blog-seo/config.json b/static/blog-seo/config.json index 0100649a..b3b37cd3 100644 --- a/static/blog-seo/config.json +++ b/static/blog-seo/config.json @@ -665,5 +665,28 @@ ], "title": "How to create an invite-only auth flow in 2023", "schema": "" + }, + { + "path": "/blog/how-we-cut-our-aws-costs-part-2", + "metaTags": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + " ", + "" + ], + "title": "How we used multi-tenancy to cut our AWS costs by 50%", + "schema": "" } ] \ No newline at end of file diff --git a/static/blog-seo/sitemapconfig.json b/static/blog-seo/sitemapconfig.json index 901011d7..82f0cdee 100644 --- a/static/blog-seo/sitemapconfig.json +++ b/static/blog-seo/sitemapconfig.json @@ -70,5 +70,8 @@ }, { "location": "https://supertokens.com/blog/how-to-create-an-invite-only-auth-flow" + }, + { + "location": "https://supertokens.com/blog/how-we-cut-our-aws-costs-part-2" } ] \ No newline at end of file diff --git a/static/card_covers/how-to-create-an-invite-only-auth-flow.png b/static/card_covers/how-to-create-an-invite-only-auth-flow.png index 6b5382d1..dad48a83 100644 Binary files a/static/card_covers/how-to-create-an-invite-only-auth-flow.png and b/static/card_covers/how-to-create-an-invite-only-auth-flow.png differ diff --git a/static/card_covers/how-we-cut-our-aws-costs-part-2.png b/static/card_covers/how-we-cut-our-aws-costs-part-2.png new file mode 100644 index 00000000..ed89a1da Binary files /dev/null and b/static/card_covers/how-we-cut-our-aws-costs-part-2.png differ diff --git a/static/covers/how-to-create-an-invite-only-auth-flow.png b/static/covers/how-to-create-an-invite-only-auth-flow.png index ef96d4b6..54687865 100644 Binary files a/static/covers/how-to-create-an-invite-only-auth-flow.png and b/static/covers/how-to-create-an-invite-only-auth-flow.png differ diff --git a/static/covers/how-we-cut-our-aws-costs-part-2.png b/static/covers/how-we-cut-our-aws-costs-part-2.png new file mode 100644 index 00000000..229a33a1 Binary files /dev/null and b/static/covers/how-we-cut-our-aws-costs-part-2.png differ