Files
nexus/sreweekly/articles/438/03-from-four-to-five-9s-of-uptime-by-migrating-to-kubernetes.html
2026-09-12 17:23:01 +08:00

1505 lines
137 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><!-- Last Published: Mon Sep 07 2026 17:18:25 GMT+0000 (Coordinated Universal Time) --><html data-wf-domain="webflow.workos.com" data-wf-page="65f4ad67e93f3e3fe0aa0369" data-wf-site="621f54116cab10f6e9215d8b" lang="en" data-wf-collection="65f4ad67e93f3e3fe0aa0396" data-wf-item-slug="from-four-to-five-9s-of-uptime-by-migrating-to-kubernetes"><head><meta charset="utf-8"/><link href="https://cdn.prod.website-files.com" rel="preconnect" crossorigin="anonymous"/><title>From four to five 9s of uptime by migrating to Kubernetes — WorkOS</title><meta content="When we launched User Management along with a free tier of up to 1 million MAUs, we faced several challenges using Heroku: the lack of an SLA, limited rollout functionality, and inadequate data locality options. To address these, we migrated to Kubernetes on EKS, developing a custom platform called Terrace to streamline deployment, secret management, and automated load balancing." name="description"/><meta content="From four to five 9s of uptime by migrating to Kubernetes — WorkOS" property="og:title"/><meta content="When we launched User Management along with a free tier of up to 1 million MAUs, we faced several challenges using Heroku: the lack of an SLA, limited rollout functionality, and inadequate data locality options. To address these, we migrated to Kubernetes on EKS, developing a custom platform called Terrace to streamline deployment, secret management, and automated load balancing." property="og:description"/><meta content="From four to five 9s of uptime by migrating to Kubernetes — WorkOS" name="twitter:title"/><meta content="When we launched User Management along with a free tier of up to 1 million MAUs, we faced several challenges using Heroku: the lack of an SLA, limited rollout functionality, and inadequate data locality options. To address these, we migrated to Kubernetes on EKS, developing a custom platform called Terrace to streamline deployment, secret management, and automated load balancing." name="twitter:description"/><meta property="og:type" content="website"/><meta content="summary_large_image" name="twitter:card"/><meta content="width=device-width, initial-scale=1" name="viewport"/><link href="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/css/workos-new.shared.28543cc15.min.css" rel="stylesheet" type="text/css" integrity="sha384-KFQ8wVrS2b+8WkQcHbc9dHkk6VBemO81ObFgxFBdJ8lPyztbzbKil5mkjFkDwBsn" crossorigin="anonymous"/><link href="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/css/workos-new.65f4ad67e93f3e3fe0aa0369.6864419a4.opt.min.css" rel="stylesheet" type="text/css" integrity="sha384-aGRBmkRyQ6u9BCOv5A9afob4S6WMoysovu3D6LLIGb+x3rXuO9i4R+qNBb7/K0We" crossorigin="anonymous"/><script type="text/javascript">!function(o,c){var n=c.documentElement,t=" w-mod-";n.className+=t+"js",("ontouchstart"in o||o.DocumentTouch&&c instanceof DocumentTouch)&&(n.className+=t+"touch")}(window,document);</script><link href="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a44e9f137f7ee438717c16d_favicon%202.ico" rel="shortcut icon" type="image/x-icon"/><link href="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a44e9f14b26717fdcabf00f_favicon%202.ico" rel="icon" type="image/png" sizes="48x48"/><link href="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/621f549024eb2947f6f2f7f7_Favicon%20256x256.png" rel="apple-touch-icon"/><link href="https://workos.com/blog/from-four-to-five-9s-of-uptime-by-migrating-to-kubernetes" rel="canonical"/><link href="rss.xml" rel="alternate" title="RSS Feed" type="application/rss+xml"/><!-- Google Consent Mode v2 — region-keyed defaults -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
// Default for everyone (permissive)
gtag('consent', 'default', {
ad_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted',
analytics_storage: 'granted',
});
// Override for EEA + UK + Switzerland (Google evaluates region client-side)
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
region: ['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB', 'IS', 'LI', 'NO', 'CH'],
wait_for_update: 500,
});
</script>
<!-- Restore stored consent (returning visitors) — runs synchronously BEFORE GTM -->
<script>
(function () {
try {
var stored = localStorage.getItem('workos_consent_v1');
if (stored) {
var parsed = JSON.parse(stored);
function gtag() {
window.dataLayer.push(arguments);
}
gtag('consent', 'update', parsed);
}
} catch (e) {}
})();
</script>
<!-- Google Tag Manager -->
<script>
(function (w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != 'dataLayer' ? '&l=' + l : '';
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'GTM-NTN3Q3DV');
</script>
<!-- End Google Tag Manager -->
<link rel="describedby" type="text/markdown" href="https://workos.com/llms.txt" title="LLM-friendly index" /><meta name="image" content="https://workos.imgix.net/images/5c714f5d-4907-4321-9fce-217be7ec97b2.png?auto=format&amp;fit=clip&amp;q=80" />
<meta itemprop="image" content="https://workos.imgix.net/images/5c714f5d-4907-4321-9fce-217be7ec97b2.png?auto=format&amp;fit=clip&amp;q=80" />
<meta name="twitter:image" content="https://workos.imgix.net/images/5c714f5d-4907-4321-9fce-217be7ec97b2.png?auto=format&amp;fit=clip&amp;q=80" />
<meta property="og:image" content="https://workos.imgix.net/images/5c714f5d-4907-4321-9fce-217be7ec97b2.png?auto=format&amp;fit=clip&amp;q=80" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "From four to five 9s of uptime by migrating to Kubernetes ",
"description": "When we launched User Management along with a free tier of up to 1 million MAUs, we faced several challenges using Heroku: the lack of an SLA, limited rollout functionality, and inadequate data locality options. To address these, we migrated to Kubernetes on EKS, developing a custom platform called Terrace to streamline deployment, secret management, and automated load balancing.",
"author": {
"@type": "Organization",
"name": "WorkOS"
},
"url": "https://workos.com/blog/from-four-to-five-9s-of-uptime-by-migrating-to-kubernetes",
"datePublished": "Jun 27, 2024"
}
</script></head><body data-scroll-time="0.5"><div class="page-wrapper"><div class="w-embed"><style>
@font-face {
font-family: Untitled Fallback;
src: local('Arial');
ascent-override: 110%;
descent-override:35%;
line-gap-override: 0%;
size-adjust: 108%;
}
body{
font-family: 'Untitled Sans', 'Untitled Fallback', Arial, sans-serif;
}
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
:root{
--light-1: #29363D;
--light-2: #656B8A;
--light-3: #8F96BD;
--dark-2: #C5CAE8;
--dark-3: #878CA6;
}
a {
color: inherit;
text-decoration: inherit;
font-size: inherit;
text-underline-offset: 2px;
}
input, textarea {
-webkit-appearance: none;
outline: none !important;
}
.w-richtext>:first-child {
margin-top: 0;
}
.w-richtext>:last-child {
margin-bottom: 0;
}
.button{
user-select: none;
-webkit-user-select: none;
box-shadow: 0px 24px 22px rgba(23, 6, 100, 0.0372022), 0px 8.5846px 8.03036px rgba(23, 6, 100, 0.0532451), 0px 4.77692px 3.89859px rgba(23, 6, 100, 0.0667549), 0px 2.63479px 1.91116px rgba(23, 6, 100, 0.0827978), 0px 1.15891px 0.755676px rgba(23, 6, 100, 0.12);
}
.nav-dropdown-menu-inner, .pricing-tooltip, .email-dropdown-inner{
box-shadow: 0px 51px 80px rgba(22, 26, 41, 0.0154121), 0px 15.375px 24.1177px rgba(22, 26, 41, 0.0270905), 0px 6.38599px 10.0172px rgba(22, 26, 41, 0.0409122), 0px 0.5px 3.62304px rgba(22, 26, 41, 0.07);
}
.nav-dropdown-link:last-child{
margin-bottom: 0px;
}
.text-link:hover .text-link-icon--chevron{
left: 2px;
}
.local-nav-cta:hover .text-link-icon{
left: 2px;
}
.post-back-link:hover .post-back-link-arrow{
left: -2px;
}
.code-card{
box-shadow: 0px 100px 80px rgba(3, 3, 6, 0.07), 0px 41.7776px 33.4221px rgba(3, 3, 6, 0.0503198), 0px 22.3363px 17.869px rgba(3, 3, 6, 0.0417275), 0px 12.5216px 10.0172px rgba(3, 3, 6, 0.035), 0px 6.6501px 5.32008px rgba(3, 3, 6, 0.0282725), 0px 2.76726px 2.21381px rgba(3, 3, 6, 0.0196802);
}
.tile, .cs-cards-slide, .bottom-cta, .tile-shadow, .al-circle{
box-shadow: 0px 51px 78px rgba(17, 7, 53, 0.05), 0px 21.3066px 35.4944px rgba(17, 7, 53, 0.0359427), 0px 11.3915px 18.9418px rgba(17, 7, 53, 0.0298054), 0px 6.38599px 9.8801px rgba(17, 7, 53, 0.025), 0px 3.39155px 4.58665px rgba(17, 7, 53, 0.0201946), 0px 1.4113px 1.55262px rgba(17, 7, 53, 0.0140573), inset 0px 1px 0px rgba(41, 56, 78, 0.05);
}
.tile-shadow-dark{
box-shadow: 0px 100px 80px rgba(3, 3, 6, 0.07), 0px 41.7776px 33.4221px rgba(3, 3, 6, 0.0503198), 0px 22.3363px 17.869px rgba(3, 3, 6, 0.0417275), 0px 12.5216px 10.0172px rgba(3, 3, 6, 0.035), 0px 6.6501px 5.32008px rgba(3, 3, 6, 0.0282725), 0px 2.76726px 2.21381px rgba(3, 3, 6, 0.0196802);
}
.fake-ui-button, .mfa-input-button{
box-shadow: -5px 0px 29px 1px rgba(219, 74, 255, 0.26), 5px 0px 29px 1px rgba(23, 255, 199, 0.32);
}
.code-tooltip{
background: #030628;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
cursor: help;
}
.home-ds-feature-line-border{
width: calc(50% + 54px);
}
.isometric-shadow{
box-shadow: 0px 91px 183px rgba(38, 33, 84, 0.0196802), 0px 38.0176px 76.453px rgba(38, 33, 84, 0.0282725), 0px 20.326px 40.8754px rgba(38, 33, 84, 0.035), 0px 11.3946px 22.9144px rgba(38, 33, 84, 0.0417275), 0px 6.05159px 12.1697px rgba(38, 33, 84, 0.0503198), 0px 2.5182px 5.06408px rgba(38, 33, 84, 0.07);
}
.chip-shadow{
box-shadow: 0px 0px 74px rgba(6, 255, 255, 0.32), 0px 33px 54px rgba(0, 0, 0, 0.17), 0px 13.7866px 22.5599px rgba(0, 0, 0, 0.122205), 0px 7.37098px 12.0616px rgba(0, 0, 0, 0.101338), 0px 4.13211px 6.76164px rgba(0, 0, 0, 0.085), 0px 2.19453px 3.59106px rgba(0, 0, 0, 0.0686618), 0px 0.913195px 1.49432px rgba(0, 0, 0, 0.0477948);
}
.cs-nav-slide.swiper-slide-active .cs-nav-slide-line{
height: 4px;
}
.cs-nav-slide.swiper-slide-active .cs-nav-logo{
filter: grayscale(0);
-webkit-filter: grayscale(0);
opacity: 100;
transform: scale(1);
}
.cs-slider-nav-overlay{
pointer-events: none;
}
.pricing-toggle-circle{
box-shadow: 0px 9px 25px rgba(27, 39, 81, 0.0674749), 0px 3.75998px 10.4444px rgba(27, 39, 81, 0.0969343), 0px 2.01027px 5.58408px rgba(27, 39, 81, 0.12), 0px 1.12694px 3.13039px rgba(27, 39, 81, 0.143066), 0px 0.249053px 0.691814px rgba(27, 39, 81, 0.04), inset 0px 1px 2px 1px rgba(255, 255, 255, 0.1);
}
.body-dark #logo-text, .body-dark #logo-icon{
fill: #fff;
}
.body-dark #dropdown-arrow{
color: var(--dark-2);
}
.body-dark .nav-link{
color: #fff;
}
.body-dark .nav-link:hover{
color: var(--dark-2);
}
.body-dark .nav-cta{
color: #23F0C3;
border-color: #2B335A;
}
.body-dark .nav-cta:hover{
border-color: #23F0C3;
}
.body-dark .footer{
background: #030520;
color: var(--dark-3);
}
.body-dark .footer-link{
color: var(--dark-2);
}
.body-dark .post-rt a{
color: #23F0C3;
}
.subscribe-wrap a, .subscribe-wrap .subscribe-email-dropdown-toggle {
color: #6363F1;
}
.body-dark .subscribe-wrap a, .body-dark .subscribe-wrap .subscribe-email-dropdown-toggle {
color: #23F0C3;
}
.body-dark .nav-dropdown-menu-inner{
background-color: #181B39;
border: 1px solid #2B335A;
}
.body-dark .nav-dropdown-menu-arrow-inner{
background-color: #181B39;
}
.body-dark .nav-dropdown-menu-arrow{
background-image: linear-gradient(135deg,#2B335A,rgba(43, 51, 90, 1) 39%,rgba(43, 51, 90, 0) 40%);
}
.body-dark .nav-dropdown-link-icon{
color: #23F0C3;
}
.body-dark .nav-dropdown-menu{
color: #fff;
}
.body-dark .nav-dropdown-link:hover{
background: #24274C;
}
.body-dark .text-color-light-2{
color: var(--dark-2);
}
.body-dark .nav-link.nav-link--dropdown.w--open{
color: #C5CAE8;
}
.body-dark .mobile-nav-menu-inner{
background: #181B39;
border: 1px solid #2B335A;
}
.body-dark .mobile-nav-cta-wrap{
background: #24274C;
}
.body-dark .button--mobile-nav{
background: #23F0C3;
color: #030628;
}
.body-dark .mobile-nav-button{
border-color: #2B335A;
color: var(--dark-2);
}
.body-dark .mobile-nav-menu-close{
color: var(--dark-2);
}
.body-dark .mobile-nav-menu-divider{
background: #2B335A;
}
.body-dark .nav-context-menu{
background-color: #181B39;
}
.body-dark .context-menu-item:hover{
background-color: #24274C;
color: #fff;
}
.cs-cards-slide.swiper-slide{
user-select: none;
-webkit-user-select: none;
}
hr {
background-image: url('https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/623b019ae77ec09f6fa640c6_hr-purple.svg');
background-position: center;
background-repeat: no-repeat;
height: 10px;
border:none;
margin: 36px 0;
}
.text-gradient-light {
-webkit-box-decoration-break: clone;
}
.terms-paragraph a{
text-decoration: underline;
}
p a{
color: #6363F1;
}
.code-tabs-menu::-webkit-scrollbar, .blog-filters-wrap::-webkit-scrollbar, .jobs-tabs-menu::-webkit-scrollbar {
display: none;
}
.video-cta-thumbnail:hover{
box-shadow: -5px 0px 29px 1px rgba(219, 74, 255, 0.26), 5px 0px 29px 1px rgba(23, 255, 199, 0.32);
}
.absolute-link{
pointer-events: none;
}
@media only screen and (max-width: 1090px) and (min-width: 992px){
.button, .text-link, .secondary-button{
font-size: 14px !important;
}
}
.post-rt em, .post-rt i{
font-family: "Georgia";
}
blockquote em{
font-family: 'Untitled sans',sans-serif !important;
font-style: normal;
}
.bottom-cta:hover{
box-shadow: 0px 61px 48px rgba(17, 7, 53, 0.1), 0px 21.3066px 35.4944px rgba(17, 7, 53, 0.0759), 0px 11.3915px 18.9418px rgba(17, 7, 53, 0.0498), 0px 6.38599px 9.8801px rgba(17, 7, 53, 0.035), 0px 3.39155px 4.58665px rgba(17, 7, 53, 0.0201946), 0px 1.4113px 1.55262px rgba(17, 7, 53, 0.0140573), inset 0px 1px 0px rgba(41, 56, 78, 0.05);
}
.tippy-box[data-theme~='workos'] {
background-color: #fff;
color: #29363D;
border: 1px solid #DDDDE3;
border-radius: 8px;
padding: 10px;
}
textarea { resize: vertical; }
.nav-context-menu.show-menu{
display: block;
}
.multiple-authors-wrap .blog-author:nth-child(1){
z-index: 8;
}
.multiple-authors-wrap .blog-author:nth-child(2){
z-index: 7;
}
.multiple-authors-wrap .blog-author:nth-child(3){
z-index: 6;
}
.multiple-authors-wrap .blog-author:nth-child(4){
z-index: 5;
}
.multiple-authors-wrap .blog-author:nth-child(5){
z-index: 4;
}
.multiple-authors-wrap .blog-author:nth-child(6){
z-index: 3;
}
.multiple-authors-wrap .blog-author:nth-child(7){
z-index: 2;
}
.multiple-authors-wrap .blog-author:nth-child(8){
z-index: 1;
}
.nav-link--dropdown.w--open{
pointer-events: none;
}
@media (max-width:1100px) and (min-width:992px){
.nav-dropdown-menu.nav-dropdown-menu--features.cc-products{
left:120%;
}
.nav-dropdown-menu-arrow.cc-products{
left:42%;
}
}
</style></div><div class="w-embed"><link
href="https://unpkg.com/prism-theme-night-owl@1.4.0/build/light-no-italics.css"
rel="stylesheet"
/>
<style>
.video-container {
overflow: hidden;
position: relative;
width:100%;
}
.video-container::after {
padding-top: 56.25%;
display: block;
content: '';
}
.video-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.code-toolbar pre code {
font-size: 14px;
font-family: ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;
}
.code-toolbar pre {
border-radius: 8px;
}
.code-toolbar {
position: relative;
}
.code-toolbar > .toolbar {
position: absolute;
top: .3em;
right: .2em;
border-radius: .5em;
}
.code-toolbar > .toolbar a {
color: #bbb;
font-size: .8em;
cursor: pointer;
padding: 0 .5em;
}
.code-toolbar > .toolbar a:hover,
.code-toolbar > .toolbar a:focus,
.code-toolbar > .toolbar a.zeroclipboard-is-hover {
color: inherit;
}
.code-toolbar ::selection {
background-color: #6363F1 !important;
color: #FFF;
}
.toolbar {
display: none;
}
.code-toolbar:hover .toolbar {
display:block;
}
.copy-to-clipboard-button span{
display: none;
}
.code-toolbar:hover .copy-to-clipboard-button[data-copy-state="copy"] {
display:block;
background-color:transparent;
background-repeat: no-repeat;
margin:12px;
width:16px;
height:16px;
background-image: url("data:image/svg+xml,%3Csvg width='16px' height='16px' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6665 2.6665H11.9998C12.3534 2.6665 12.6926 2.80697 12.9426 3.05702C13.1927 3.30707 13.3331 3.64621 13.3331 3.99983V13.3332C13.3331 13.6868 13.1927 14.026 12.9426 14.276C12.6926 14.5261 12.3534 14.6665 11.9998 14.6665H3.99984C3.64622 14.6665 3.30708 14.5261 3.05703 14.276C2.80698 14.026 2.6665 13.6868 2.6665 13.3332V3.99983C2.6665 3.64621 2.80698 3.30707 3.05703 3.05702C3.30708 2.80697 3.64622 2.6665 3.99984 2.6665H5.33317' stroke='black' stroke-width='1.33' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M10.0002 1.3335H6.00016C5.63197 1.3335 5.3335 1.63198 5.3335 2.00017V3.3335C5.3335 3.70169 5.63197 4.00017 6.00016 4.00017H10.0002C10.3684 4.00017 10.6669 3.70169 10.6669 3.3335V2.00017C10.6669 1.63198 10.3684 1.3335 10.0002 1.3335Z' stroke='black' stroke-width='1.33' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.code-toolbar:hover .copy-to-clipboard-button[data-copy-state="copy-success"] {
display:block;
background-color:transparent;
background-repeat: no-repeat;
margin:12px;
width:16px;
height:16px;
background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.66675 8.00013L6.00008 11.3334L12.3334 5.00013L13.2476 4.08594' stroke='black' stroke-width='1.33' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.post-rt p code,
.post-rt blockquote code,
.post-rt li code,
.post-rt h2 code,
.post-rt h3 code,
.post-rt h4 code{
background-color: #f5f7f9;
font-family: ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;
font-size: 0.875em;
font-weight: 400;
color: #343a40;
border-radius: 6px;
padding: 3px 6px;
}
body .gist .gist-data {
max-width: calc(100vw - 24px);
margin-bottom: 18px;
margin-top: 0px;
}
[data-tippy-content]{
top: 0;
left: 0;
}
.tippy-box[data-theme~='custom'] {
background-color: #f5f5ff;
color: #656b8a;
padding: 8px;
white-space: nowrap;
}
.tippy-box[data-theme~='custom'][data-placement^='top'] {
bottom: 6px;
}
.tippy-box[data-theme~='custom'][data-placement^='bottom'] {
bottom: -6px;
}
.tippy-box[data-theme~='custom'][data-placement^='top'] > .tippy-arrow::before {
border-top-color: #f5f5ff;
}
.tippy-box[data-theme~='custom'][data-placement^='bottom'] > .tippy-arrow::before {
border-bottom-color: #f5f5ff;
}
</style>
<style>
@media only screen and (min-width: 992px) {
.w-richtext-figure-type-image.w-richtext-align-fullwidth {
position: relative;
min-width: 746px !important;
left: 50%;
transform: translateX(-50%);
}
.w-richtext-figure-type-image.w-richtext-align-fullwidth figcaption {
width: 650px;
margin-left: auto;
margin-right: auto;
}
}
.w-richtext-figure-type-image div {
max-width: none !important;
display: block !important;
}
.article-container .section-heading {
text-wrap: balance;
}
.article-summary {
text-wrap: pretty;
}
.post-rt p,
.post-rt li {
color: rgba(41, 54, 61, 0.92);
}
.post-rt h2 + h3 {
margin-top: 28px;
}
.post-rt li p {
margin-bottom: 0px;
}
.post-rt pre {
background-color: #fbfbfb !important;
}
pre[class*="language-"] {
margin-bottom: 32px;
}
.multiple-authors-wrap:hover .blog-author {
margin-right: 8px;
}
.toc-link.w--current .toc-link-dot {
opacity: 100%;
}
.article-content-section {
scroll-margin-top: 64px;
}
.toc-item {
display: flex;
align-items: start;
}
.toc-item.active > a {
color: var(--black);
}
.post-toc-wrap {
--toc-transition-duration: 0.25s;
--toc-easing: ease;
--toc-line-width: 18;
--toc-line-width-px: 18px;
--toc-line-height: 2px;
--toc-line-color: #d1d3da;
--toc-line-color-active: var(--black);
transition: transform var(--toc-transition-duration) var(--toc-easing);
}
.post-toc-inner {
height: var(--initial-toc-height);
transition: transform var(--toc-transition-duration) var(--toc-easing);
}
/* Collapsed state */
.post-toc-inner.toc-collapsed {
transform: /*translateY(calc(50vh - 50% - 48px))*/ translateX(
calc(-1 * (100vw - 1200px - 64px) / 2)
);
}
@media (max-width: 1312px) and (min-width: 992px) {
.post-toc-inner.toc-collapsed {
transform: translateX(-40px);
}
}
.toc-a {
position: relative;
display: flex;
align-items: center;
/*will-change: transform;*/
transition: transform var(--toc-transition-duration) var(--toc-easing),
height var(--toc-transition-duration) var(--toc-easing);
transform-origin: left;
height: var(--expanded-link-height);
}
/* Line behind text that's always present but scaled to 0 by default */
.toc-line {
position: absolute;
left: 0;
top: calc(50% - var(--toc-line-height) / 2);
opacity: 0;
width: var(--toc-line-width-px);
height: var(--toc-line-height);
background-color: var(--toc-line-color);
border-radius: var(--toc-line-height);
transform: scale(calc(var(--expanded-link-width) / var(--toc-line-width)), 5);
transform-origin: left center;
will-change: transform;
transition: transform var(--toc-transition-duration) var(--toc-easing),
opacity var(--toc-transition-duration) var(--toc-easing),
background-color var(--toc-transition-duration) var(--toc-easing);
}
.toc-text {
/*
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 180px;
*/
transform-origin: left center;
will-change: transform;
transition: transform var(--toc-transition-duration) var(--toc-easing),
opacity var(--toc-transition-duration) var(--toc-easing),
color var(--toc-transition-duration) var(--toc-easing);
}
.toc-text-inner {
display: inline;
}
.toc-label {
transform-origin: left center;
transition: transform var(--toc-transition-duration) var(--toc-easing),
opacity var(--toc-transition-duration) var(--toc-easing);
}
.toc-a::before {
content: "";
position: absolute;
left: -8px;
top: 3px;
bottom: 3px;
width: 1.5px;
border-radius: 2px;
background-color: currentColor;
transition: opacity var(--toc-transition-duration) var(--toc-easing);
opacity: 0;
}
.toc-item.active .toc-a::before {
opacity: 1;
}
/* Collapsed state styles */
.toc-collapsed .toc-a {
height: 1px;
}
.toc-collapsed .toc-label {
opacity: 0;
transform: scale(0.4);
}
.toc-collapsed .toc-text {
transform: scale(
calc(var(--toc-line-width) / var(--expanded-link-width)),
0.2
);
opacity: 0;
}
.toc-collapsed .toc-line {
transform: scaleX(1);
opacity: 1;
}
/* Active link styles */
.toc-collapsed .toc-item.active .toc-line {
background-color: var(--toc-line-color-active);
transform: scale(1.3, 1);
}
.toc-collapsed .toc-item.active .toc-a::before {
opacity: 0;
}
/* Hover state */
.toc-collapsed:hover .toc-a {
height: var(--expanded-link-height);
}
.toc-collapsed:hover .toc-line {
transform: scale(calc(var(--expanded-link-width) / var(--toc-line-width)), 5);
opacity: 0;
}
.toc-collapsed:hover .toc-item.active .toc-line {
transform: scale(calc(var(--expanded-link-width) / var(--toc-line-width)), 5);
background-color: var(--toc-line-color);
}
.toc-collapsed:hover .toc-a .toc-text {
transform: scale(1, 1);
opacity: 1;
}
.toc-collapsed:hover .toc-item.active .toc-a {
color: var(--black);
}
.toc-collapsed:hover .toc-item.active .toc-a::before {
opacity: 1;
}
.toc-a:hover .toc-text {
color: var(--black);
}
.transitioning .toc-a {
cursor: default;
}
.article-note {
background-color: #f5f5f7;
padding: 20px 20px 20px 48px;
border-radius: 10px;
position: relative;
font-size: 16px;
margin-top: 32px !important;
margin-bottom: 32px !important;
line-height: 1.5 !important;
}
.article-note::before {
content: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7.9999 1.44043C4.09837 1.44043 0.935547 4.60325 0.935547 8.50478C0.935547 12.4063 4.09837 15.5692 7.9999 15.5692C11.9014 15.5692 15.0642 12.4063 15.0642 8.50478C15.0642 4.60325 11.9014 1.44043 7.9999 1.44043ZM1.94887 8.50478C1.94887 5.1629 4.65802 2.45376 7.9999 2.45376C11.3418 2.45376 14.0509 5.1629 14.0509 8.50478C14.0509 11.8466 11.3418 14.5559 7.9999 14.5559C4.65802 14.5559 1.94887 11.8466 1.94887 8.50478ZM8.79991 5.30507C8.79991 5.74689 8.44174 6.10507 7.99991 6.10507C7.55809 6.10507 7.19991 5.74689 7.19991 5.30507C7.19991 4.86323 7.55809 4.50507 7.99991 4.50507C8.44174 4.50507 8.79991 4.86323 8.79991 5.30507ZM6.40003 6.90507H6.93336H8.00003C8.29459 6.90507 8.53336 7.14384 8.53336 7.4384V11.1717H9.0667H9.60003V12.2384H9.0667H8.00003H6.93336H6.40003V11.1717H6.93336H7.4667V7.97173H6.93336H6.40003V6.90507Z' fill='currentColor'/%3E%3C/svg%3E");
position: absolute;
left: 20px;
top: 22px;
opacity: 0.6;
}
.post-rt li ul, .post-rt li ol{
margin-bottom: 0px;
}
.summarize-menu-item{
opacity: 0;
transform: translateY(1px);
transition: opacity 150ms ease-out, transform 150ms ease-out;
}
.summarize-menu.w--open .summarize-menu-item.cc-2{
transition-delay: 0.025s;
}
.summarize-menu.w--open .summarize-menu-item.cc-1{
transition-delay: 0.05s;
}
.summarize-menu {
visibility: hidden;
}
.summarize-menu.w--open {
visibility: visible;
}
.summarize-menu.w--open .summarize-menu-item {
opacity: 1;
transform: translateY(0px);
transition: opacity 500ms ease, filter 500ms ease, transform 500ms ease;
}
@media only screen and (max-width: 1280px){
.summarize-wrap{
display: none;
}
}
</style></div><nav class="nav"><div class="page-padding"><div class="container"><div class="nav-inner"><a aria-label="WorkOS Home" href="/" class="nav-logo-link w-inline-block"><div class="nav-logo-img w-embed"><svg width="126" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M36.518 3.613h3.479l2.505 10.321c.464 1.948.556 3.108.556 3.108h.047s.162-1.136.626-3.108l2.388-10.32h3.943l2.527 10.32c.487 2.018.604 3.108.604 3.108h.07s.046-1.09.509-3.108l2.412-10.32h3.479l-4.406 16.93h-3.873l-2.666-10.252c-.557-2.226-.604-3.223-.604-3.223h-.047s-.047.997-.556 3.223l-2.505 10.251h-3.988l-4.5-16.93ZM59.082 14.393c0-3.874 2.505-6.378 6.286-6.378 3.757 0 6.261 2.504 6.261 6.377 0 3.896-2.505 6.425-6.261 6.425-3.78-.001-6.286-2.529-6.286-6.425Zm9.3 0c0-2.505-1.206-3.92-3.014-3.92-1.948 0-3.039 1.577-3.039 3.92 0 2.551 1.206 3.965 3.039 3.965 1.948 0 3.014-1.578 3.014-3.966ZM73.182 8.204h3.084v2.274h.07c.534-1.183 1.808-2.366 3.988-2.366.37 0 .603.047.765.092v3.084h-.092s-.278-.092-1.044-.092c-2.388 0-3.687 1.414-3.687 4.058v5.287h-3.084V8.204ZM82.527 3.613h3.084V9.04c0 3.2-.047 3.78-.047 3.78h.047l4.592-4.615h3.849l-5.378 5.334 6.239 7.004H91.27l-4.5-5.103-1.16 1.136v3.965h-3.084V3.613ZM94.957 12.14c0-5.218 3.248-8.696 8.118-8.696s8.117 3.478 8.117 8.696-3.247 8.696-8.117 8.696c-4.87 0-8.118-3.478-8.118-8.696Zm12.871 0c0-3.548-1.901-5.938-4.755-5.938s-4.753 2.39-4.753 5.938c0 3.548 1.9 5.938 4.753 5.938 2.852 0 4.755-2.39 4.755-5.938ZM112.372 14.908h3.526c0 1.995 1.369 3.108 3.456 3.108 1.762 0 2.969-.882 2.969-2.134 0-1.414-.927-1.786-3.874-2.365-2.69-.534-5.543-1.439-5.543-4.964 0-2.945 2.505-5.171 6.331-5.171 3.988 0 6.448 2.087 6.448 5.24h-3.526c0-1.53-1.182-2.482-2.922-2.482-1.762 0-2.852.858-2.852 2.11 0 1.322.765 1.831 3.131 2.318 3.501.743 6.377 1.136 6.377 5.032 0 3.087-2.69 5.174-6.656 5.174-4.035 0-6.865-2.342-6.865-5.866Z" id="logo-text" fill="#29363D"/><path d="M0 12c0 .526.138 1.052.406 1.505l4.856 8.409c.498.858 1.255 1.56 2.196 1.874a3.94 3.94 0 0 0 4.69-1.763l1.172-2.031L8.695 12l4.883-8.465 1.173-2.03A4.78 4.78 0 0 1 16.126 0H8.594C7.274 0 6.055.702 5.4 1.846l-4.994 8.65A2.968 2.968 0 0 0 0 12Z" id="logo-icon" fill="#6363F1"/><path d="M27.692 12c0-.526-.138-1.053-.406-1.505l-4.92-8.52a3.962 3.962 0 0 0-4.69-1.763c-.94.314-1.698 1.015-2.196 1.874l-1.108 1.91L18.997 12l-4.883 8.464-1.173 2.031c-.35.6-.821 1.108-1.375 1.505h7.532c1.32 0 2.539-.702 3.194-1.846l4.994-8.65c.268-.452.406-.978.406-1.504Z" id="logo-icon" fill="#6363F1"/></svg></div></a><div class="nav-menu"><div class="nav-menu-item"><div data-hover="true" data-delay="0" class="nav-dropdown w-dropdown"><div class="nav-link nav-link--dropdown w-dropdown-toggle"><div>Products</div><div class="nav-dropdown-arrow w-embed"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 4.5L6 7.5L9 4.5" id="dropdown-arrow" stroke="currentColor" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div></div><nav class="nav-dropdown-menu nav-dropdown-menu--features cc-products w-dropdown-list"><div class="nav-dropdown-menu-inner"><div class="nav-dropdown-menu-arrow cc-products"><div class="nav-dropdown-menu-arrow-inner"></div></div><div class="nav-dropdown-products"><a href="/user-management" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/656545520bd5f04e20a3a6a7_um.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">User Management</div><div class="text-color-light-2">Complete auth &amp; user management platform</div></div></a><a href="/single-sign-on" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/63e1062ae62bc2260203e96f_icon-sso.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Enterprise SSO</div><div class="text-color-light-2">Unified SSO integration for any identity provider</div></div></a><a href="/radar" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/673b4ed27842047837086d7a_icon-radar-nav.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Radar</div><div class="text-color-light-2">Real-time protection against bots, fraud, and abuse<br/></div></div></a><a href="https://authkit.com" target="_blank" class="nav-dropdown-link nav-dropdown-link--features cc-last w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/65654341bfdb733f6715f944_authkit.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">AuthKit</div><div class="text-color-light-2">Customizable UI for all authentication types</div></div></a><a href="/directory-sync" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/63e10629cdacaa53e05c2a95_icon-directory-sync.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Directory Sync</div><div class="text-color-light-2">User lifecycle management from corporate directories</div></div></a><a href="/rbac" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/68752d3fceb13184116f219f_icon-rbac.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Role-Based Access Control</div><div class="text-color-light-2">Powerful and flexible permissions for your users</div></div></a><a href="/mcp" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/68c8802359b1c7df06378d44_icon-mcp-auth.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">MCP Auth</div><div class="text-color-light-2">Secure auth for MCP servers</div></div></a><a href="/admin-portal" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/63e1062a21fa47cd37a717f5_icon-admin-portal.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Admin Portal</div><div class="text-color-light-2">Self-serve onboarding for corporate IT admins</div></div></a><a href="/vault" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/67daf11719d8c412f176a3d4_icon-vault.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Vault</div><div class="text-color-light-2">EKM for encrypting and optionally storing objects</div></div></a><a href="/multi-factor-authentication" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a3017a8e767a6e6a2078ef1_icon-mfa.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Multi-Factor Authentication</div><div class="text-color-light-2">Advanced auth methods</div></div></a><a href="/audit-logs" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/63e1062a39c3d330594d5a66_icon-audit-logs.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Audit Logs</div><div class="text-color-light-2">Event logging, exporting, and streaming</div></div></a><a href="https://workos.com/pipes" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a3018b0e0c172dcc18705c9_icon-pipes.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Pipes</div><div class="text-color-light-2">Integrations for your apps &amp; agents</div></div></a><a href="https://workos.com/auth-md" class="nav-dropdown-link nav-dropdown-link--features cc-last w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a955cecbf0c7b36d1ba654e_auth-md.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">auth.md</div><div class="text-color-light-2">User registration for agents</div></div></a><a href="https://workos.com/atlas" class="nav-dropdown-link nav-dropdown-link--features cc-last w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a955cebb120ee1805ecc813_atlas.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Atlas</div><div class="text-color-light-2">Your AI coworker</div></div></a><a href="https://workos.com/airlock" class="nav-dropdown-link nav-dropdown-link--features cc-last w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a955cecf7876373dee2020c_airlock.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Airlock</div><div class="text-color-light-2">Intent-Based Access Control</div></div></a></div></div></nav></div></div><div class="nav-menu-item"><a role="button" href="https://workos.com/docs" class="nav-link">Docs</a></div><div class="nav-menu-item"><a role="button" href="https://workos.com/customers" class="nav-link">Customers</a></div><div class="nav-menu-item"><div data-hover="true" data-delay="0" class="nav-dropdown w-dropdown"><div class="nav-link nav-link--dropdown w-dropdown-toggle"><div>Resources</div><div class="nav-dropdown-arrow w-embed"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 4.5L6 7.5L9 4.5" id="dropdown-arrow" stroke="currentColor" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div></div><nav class="nav-dropdown-menu w-dropdown-list"><div class="nav-dropdown-menu-inner"><div class="nav-dropdown-menu-arrow"><div class="nav-dropdown-menu-arrow-inner"></div></div><div class="nav-links-wrap"><a href="/changelog" class="nav-dropdown-link nav-dropdown-link--desktop-only w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 5C13.1797 5 19 10.8203 19 18M6 11C9.86599 11 13 14.134 13 18M7 18C7 18.5523 6.55228 19 6 19C5.44772 19 5 18.5523 5 18C5 17.4477 5.44772 17 6 17C6.55228 17 7 17.4477 7 18Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Changelog</div></a><a href="/blog" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 20H20" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 20.0001V21.0001C8.26522 21.0001 8.51957 20.8947 8.70711 20.7072L8 20.0001ZM4 20.0001H3C3 20.5524 3.44772 21.0001 4 21.0001V20.0001ZM4 16.0001L3.29289 15.293C3.10536 15.4805 3 15.7349 3 16.0001H4ZM15.2929 4.7072L16 5.41431L16 5.41431L15.2929 4.7072ZM16.7071 4.7072L16 5.41431L16 5.41431L16.7071 4.7072ZM19.2929 7.29299L20 6.58588V6.58588L19.2929 7.29299ZM19.2929 8.7072L18.5858 8.00009L19.2929 8.7072ZM8 19.0001H4V21.0001H8V19.0001ZM5 20.0001V16.0001H3V20.0001H5ZM4.70711 16.7072L16 5.41431L14.5858 4.00009L3.29289 15.293L4.70711 16.7072ZM16 5.41431L18.5858 8.00009L20 6.58588L17.4142 4.00009L16 5.41431ZM18.5858 8.00009L7.29289 19.293L8.70711 20.7072L20 9.41431L18.5858 8.00009ZM18.5858 8.00009V8.00009L20 9.41431C20.781 8.63326 20.781 7.36693 20 6.58588L18.5858 8.00009ZM16 5.41431H16L17.4142 4.00009C16.6332 3.21904 15.3668 3.21904 14.5858 4.00009L16 5.41431Z" fill="currentColor"/>
<path d="M12 8L16 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Blog</div></a><a href="/guides" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.0513 20.8162C11.226 21.3402 11.7923 21.6233 12.3162 21.4487C12.8402 21.274 13.1233 20.7077 12.9487 20.1838L11.0513 20.8162ZM12.9487 20.1838L12.7464 19.577L10.8491 20.2094L11.0513 20.8162L12.9487 20.1838ZM8.47734 16.5H4V18.5H8.47734V16.5ZM4 16.5V6H2V16.5H4ZM4 6H9V4H4V6ZM11 8V19H13V8H11ZM9 6C10.1046 6 11 6.89543 11 8H13C13 5.79086 11.2091 4 9 4V6ZM4 6L4 6V4C2.89543 4 2 4.89543 2 6H4ZM4 16.5V16.5H2C2 17.6046 2.89543 18.5 4 18.5V16.5ZM12.7464 19.577C12.1339 17.7394 10.4143 16.5 8.47734 16.5V18.5C9.55342 18.5 10.5088 19.1886 10.8491 20.2094L12.7464 19.577Z" fill="currentColor"/>
<path d="M12.9487 20.8162C12.774 21.3402 12.2077 21.6233 11.6838 21.4487C11.1598 21.274 10.8767 20.7077 11.0513 20.1838L12.9487 20.8162ZM11.0513 20.1838L11.2536 19.577L13.1509 20.2094L12.9487 20.8162L11.0513 20.1838ZM15.5227 16.5H20V18.5H15.5227V16.5ZM20 16.5V6H22V16.5H20ZM20 6H15V4H20V6ZM13 8V19H11V8H13ZM15 6C13.8954 6 13 6.89543 13 8H11C11 5.79086 12.7909 4 15 4V6ZM20 6L20 6V4C21.1046 4 22 4.89543 22 6H20ZM20 16.5V16.5H22C22 17.6046 21.1046 18.5 20 18.5V16.5ZM11.2536 19.577C11.8661 17.7394 13.5857 16.5 15.5227 16.5V18.5C14.4466 18.5 13.4912 19.1886 13.1509 20.2094L11.2536 19.577Z" fill="currentColor"/>
</svg></div><div>Guides</div></a><a href="/podcast" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 13H22C22 12.4477 21.5523 12 21 12V13ZM21 12H17V14H21V12ZM15 14V19H17V14H15ZM17 21H20V19H17V21ZM22 19V13H20V19H22ZM20 21C21.1046 21 22 20.1046 22 19H20V21ZM15 19C15 20.1046 15.8954 21 17 21V19H15ZM17 12C15.8954 12 15 12.8954 15 14H17V12Z" fill="currentColor"/>
<path d="M3 13V12C2.44772 12 2 12.4477 2 13H3ZM3 14H7V12H3V14ZM7 14V19H9V14H7ZM7 19H4V21H7V19ZM4 19V13H2V19H4ZM4 19L4 19H2C2 20.1046 2.89543 21 4 21V19ZM7 19V21C8.10457 21 9 20.1046 9 19H7ZM7 14H9C9 12.8954 8.10457 12 7 12V14Z" fill="currentColor"/>
<path d="M3 13C3 8.02944 7.02944 4 12 4C16.9706 4 21 8.02944 21 13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Podcast</div></a><a href="/about" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="25" height="26" viewBox="0 0 25 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 13.0007C2 13.3515 2.08586 13.7023 2.25186 14.0039L5.26274 19.6106C5.57184 20.1829 6.04121 20.6507 6.62507 20.8599C7.77562 21.2722 8.96623 20.743 9.53291 19.6844L10.2599 18.3304L7.3921 13.0007L10.4201 7.35714L11.1471 6.00317C11.3646 5.59698 11.6566 5.26464 12 5H11.6852H7.32914C6.51059 5 5.75501 5.46773 5.3486 6.23088L2.25186 11.9976C2.08586 12.2991 2 12.6499 2 13.0007Z" stroke="currentColor" stroke-width="2"/>
<path d="M22 12.9976C22 12.6468 21.9141 12.2959 21.7481 11.9943L18.6972 6.31259C18.1305 5.25998 16.9399 4.73059 15.7894 5.13686C15.2055 5.34615 14.7361 5.81398 14.427 6.38646L13.7401 7.66068L16.6079 12.9976L13.5799 18.6424L12.8529 19.9966C12.6354 20.3967 12.3434 20.7353 12 21H12.3148H16.6709C17.4894 21 18.245 20.5322 18.6514 19.7689L21.7481 14.001C21.9141 13.6994 22 13.3485 22 12.9976Z" stroke="currentColor" stroke-width="2"/>
</svg></div><div>Company</div></a><a href="/careers" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 8H4C3.44772 8 3 8.44772 3 9V19C3 19.5523 3.44772 20 4 20H20C20.5523 20 21 19.5523 21 19V9C21 8.44772 20.5523 8 20 8Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 8C8 5.79086 9.79086 4 12 4C14.2091 4 16 5.79086 16 8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Careers</div></a><a href="/security" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.2902 20.8968L12.6452 21.8317L12.6452 21.8317L12.2902 20.8968ZM11.7098 20.8968L11.3548 21.8317L11.3548 21.8317L11.7098 20.8968ZM5 4H19V2H5V4ZM19 4V10.1649H21V4H19ZM5 10.1649V4H3V10.1649H5ZM19 10.1649C19 16.8586 13.3228 19.435 11.9351 19.962L12.6452 21.8317C14.1289 21.2682 21 18.2341 21 10.1649H19ZM3 10.1649C3 18.2341 9.87108 21.2682 11.3548 21.8317L12.0649 19.962C10.6772 19.435 5 16.8586 5 10.1649H3ZM11.9351 19.962C11.95 19.9564 11.9725 19.951 12 19.951C12.0275 19.951 12.05 19.9564 12.0649 19.962L11.3548 21.8317C11.7737 21.9908 12.2263 21.9908 12.6452 21.8317L11.9351 19.962ZM19 4V4H21C21 2.89543 20.1046 2 19 2V4ZM5 2C3.89543 2 3 2.89543 3 4H5V4V2Z" fill="currentColor"/>
<path d="M15.7071 9.70711C16.0976 9.31658 16.0976 8.68342 15.7071 8.29289C15.3166 7.90237 14.6834 7.90237 14.2929 8.29289L15.7071 9.70711ZM11 13L10.2929 13.7071C10.6834 14.0976 11.3166 14.0976 11.7071 13.7071L11 13ZM9.70711 10.2929C9.31658 9.90237 8.68342 9.90237 8.29289 10.2929C7.90237 10.6834 7.90237 11.3166 8.29289 11.7071L9.70711 10.2929ZM14.2929 8.29289L10.2929 12.2929L11.7071 13.7071L15.7071 9.70711L14.2929 8.29289ZM11.7071 12.2929L9.70711 10.2929L8.29289 11.7071L10.2929 13.7071L11.7071 12.2929Z" fill="currentColor"/>
</svg></div><div>Security</div></a><a href="/support-plans" class="nav-dropdown-link nav-dropdown-link--last w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.68497 19.605L8.2207 18.7606C7.96683 18.5996 7.65397 18.5613 7.36874 18.6563L7.68497 19.605ZM3.5 21L2.55132 20.6838C2.43154 21.0431 2.52506 21.4393 2.79289 21.7071C3.06073 21.9749 3.45689 22.0685 3.81623 21.9487L3.5 21ZM4.89499 16.815L5.84367 17.1313C5.93875 16.846 5.90045 16.5332 5.73938 16.2793L4.89499 16.815ZM12.5 22C18.0228 22 22.5 17.5228 22.5 12H20.5C20.5 16.4183 16.9183 20 12.5 20V22ZM7.14923 20.4494C8.69708 21.4315 10.5337 22 12.5 22V20C10.9242 20 9.45764 19.5454 8.2207 18.7606L7.14923 20.4494ZM7.36874 18.6563L3.18377 20.0513L3.81623 21.9487L8.0012 20.5537L7.36874 18.6563ZM4.44868 21.3162L5.84367 17.1313L3.94631 16.4988L2.55132 20.6838L4.44868 21.3162ZM2.5 12C2.5 13.9663 3.06855 15.8029 4.0506 17.3508L5.73938 16.2793C4.95458 15.0424 4.5 13.5758 4.5 12H2.5ZM12.5 2C6.97715 2 2.5 6.47715 2.5 12H4.5C4.5 7.58172 8.08172 4 12.5 4V2ZM22.5 12C22.5 6.47715 18.0228 2 12.5 2V4C16.9183 4 20.5 7.58172 20.5 12H22.5Z" fill="currentColor"/>
</svg></div><div>Support Plans</div></a><a href="https://workos.com/customers" class="nav-dropdown-link nav-dropdown-link--mobile-only w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 20C7 18.3431 9.23858 17 12 17C14.7614 17 17 18.3431 17 20" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M18 14.2495C19.7659 14.7124 21 15.7697 21 16.9999" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M6 14.2495C4.2341 14.7124 3 15.7697 3 16.9999" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M12 14C13.6569 14 15 12.6569 15 11C15 9.34315 13.6569 8 12 8C10.3431 8 9 9.34315 9 11C9 12.6569 10.3431 14 12 14Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M18 10.2361C18.6137 9.68679 19 8.8885 19 8C19 6.34315 17.6569 5 16 5C15.2316 5 14.5308 5.28885 14 5.76389" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M6 10.2361C5.38625 9.68679 5 8.8885 5 8C5 6.34315 6.34315 5 8 5C8.76835 5 9.46924 5.28885 10 5.76389" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg></div><div>Customers</div></a><a href="/pricing" class="nav-dropdown-link nav-dropdown-link--mobile-only w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9811 19.9661L11.274 20.6732H11.274L11.9811 19.9661ZM4.53411 12.5191L3.827 13.2263H3.827L4.53411 12.5191ZM13.0194 4.03386L13.7265 3.32676V3.32676L13.0194 4.03386ZM20.4664 11.4808L21.1735 10.7737V10.7737L20.4664 11.4808ZM20.4664 12.8951L19.7593 12.188L20.4664 12.8951ZM13.3953 19.9661L14.1024 20.6732L13.3953 19.9661ZM4.24532 11.7215L5.24122 11.812H5.24122L4.24532 11.7215ZM4.83458 5.23969L5.83047 5.33023L4.83458 5.23969ZM5.73993 4.33433L5.83047 5.33023H5.83047L5.73993 4.33433ZM12.2217 3.74508L12.3123 4.74097L12.2217 3.74508ZM12.6882 19.259L5.24122 11.812L3.827 13.2263L11.274 20.6732L12.6882 19.259ZM12.3123 4.74097L19.7593 12.188L21.1735 10.7737L13.7265 3.32676L12.3123 4.74097ZM19.7593 12.188L12.6882 19.259L14.1024 20.6732L21.1735 13.6022L19.7593 12.188ZM5.24122 11.812L5.83047 5.33023L3.83868 5.14916L3.24943 11.631L5.24122 11.812ZM5.83047 5.33023L12.3123 4.74097L12.1312 2.74919L5.6494 3.33844L5.83047 5.33023ZM5.83047 5.33023L5.83047 5.33023L5.6494 3.33844C4.6879 3.42585 3.92609 4.18765 3.83868 5.14916L5.83047 5.33023ZM19.7593 12.188L19.7593 12.188L21.1735 13.6022C21.9545 12.8211 21.9545 11.5548 21.1735 10.7737L19.7593 12.188ZM13.7265 3.32676C13.3068 2.90705 12.7223 2.69545 12.1312 2.74919L12.3123 4.74097H12.3123L13.7265 3.32676ZM5.24122 11.812H5.24122L3.24943 11.631C3.19569 12.2221 3.40729 12.8065 3.827 13.2263L5.24122 11.812ZM11.274 20.6732C12.055 21.4543 13.3214 21.4543 14.1024 20.6732L12.6882 19.259L12.6882 19.259L11.274 20.6732Z" fill="currentColor"/>
<path d="M8.79875 8.29875C9.18928 7.90823 9.82244 7.90823 10.213 8.29875C10.6035 8.68928 10.6035 9.32244 10.213 9.71297C9.82244 10.1035 9.18928 10.1035 8.79875 9.71297C8.40823 9.32244 8.40823 8.68928 8.79875 8.29875Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Pricing</div></a></div></div></nav></div></div><div class="nav-menu-item"><a role="button" href="/pricing" class="nav-link">Pricing</a></div><a id="sign-in" role="button" href="https://workos.com/signin" class="nav-cta w-inline-block"><div>Sign in</div></a><a id="dashboard" role="button" href="https://dashboard.workos.com" class="button cc-dashboard w-inline-block"><div>Dashboard</div><div class="svg-embed w-embed"><svg width="14" height="14" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 12L10 8L6 4" stroke="currentColor" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div></a></div><div data-w-id="80f81b27-826c-538b-6c5f-1bc11ce6570d" class="mobile-nav-button"><div class="icon-embed w-embed"><svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.16667 14.1665H15.8333" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.16667 10H15.8333" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.16667 5.8335H15.8333" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div></div><div role="menu" class="nav-context-menu"><div id="copy-logo" role="menuitem" class="context-menu-item"><div class="icon-embed cc-context-menu w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.19995 14.4002C4.19995 15.3943 5.00584 16.2002 5.99995 16.2002H7.79995V15.0002H5.99995C5.66858 15.0002 5.39995 14.7316 5.39995 14.4002V6.0002C5.39995 5.66883 5.66858 5.4002 5.99995 5.4002H14.4C14.7313 5.4002 15 5.66883 15 6.0002V7.80015H9.59995C8.60585 7.80015 7.79995 8.60603 7.79995 9.60015V18.0001C7.79995 18.9942 8.60585 19.8001 9.59995 19.8001H18C18.994 19.8001 19.8 18.9942 19.8 18.0001V9.60015C19.8 8.60603 18.994 7.80015 18 7.80015H16.2V6.0002C16.2 5.00608 15.394 4.2002 14.4 4.2002H5.99995C5.00584 4.2002 4.19995 5.00608 4.19995 6.0002V14.4002ZM8.99995 9.60015C8.99995 9.26878 9.26858 9.00015 9.59995 9.00015H18C18.3313 9.00015 18.6 9.26878 18.6 9.60015V18.0001C18.6 18.3316 18.3313 18.6001 18 18.6001H9.59995C9.26858 18.6001 8.99995 18.3316 8.99995 18.0001V9.60015Z" fill="currentColor"/>
</svg></div><div class="context-menu-item-text">Copy logo as SVG</div></div><div id="copy-brandmark" role="menuitem" class="context-menu-item"><div class="icon-embed cc-context-menu w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.8406 20C16.6806 20 17.4646 19.56 17.8966 18.8328L21.2574 13.2353C21.7134 12.4753 21.7134 11.5241 21.2574 10.7641L18.0486 5.42258C17.7366 4.90258 17.2886 4.46339 16.7286 4.23139C15.3526 3.6554 13.8719 4.19939 13.1679 5.37458L12.5119 6.46177C12.4319 6.58977 12.4319 6.74977 12.5119 6.86976L15.4646 11.7953C15.5366 11.9233 15.5366 12.0833 15.4646 12.2033L11.3919 18.976C11.1519 19.376 10.8319 19.72 10.4639 19.9912H15.8246L15.8406 20Z" stroke="currentColor" stroke-width="1.33333" stroke-linecap="round"/>
<path d="M8.15925 4.00022C7.31926 4.00022 6.53447 4.44021 6.10247 5.16741L2.74251 10.7649C2.28651 11.5249 2.28651 12.4761 2.74251 13.2361L5.95127 18.5777C6.26327 19.0977 6.71127 19.5369 7.27126 19.7689C8.64725 20.3448 10.128 19.8009 10.832 18.6257L11.488 17.5385C11.568 17.4105 11.568 17.2505 11.488 17.1305L8.53525 12.2049C8.46325 12.0769 8.46325 11.9169 8.53525 11.7969L12.608 5.02421C12.832 4.61621 13.152 4.27222 13.52 4.00022H8.15925Z" stroke="currentColor" stroke-width="1.33333" stroke-linecap="round"/>
</svg></div><div class="context-menu-item-text">Copy brandmark as SVG</div></div><div class="context-menu-divider"></div><a role="menuitem" href="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6908e076c85d9ad71e6c6b6b_WorkOS%20Logos.zip" target="_blank" class="context-menu-item context-menu-item--last w-inline-block"><div class="icon-embed cc-context-menu w-embed"><svg width="12" height="14" viewBox="0 0 12 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.27344 11.4766C5.36133 11.5645 5.47852 11.5938 5.625 11.5938C5.74219 11.5938 5.85938 11.5645 5.94727 11.4766L10.166 7.25781C10.3418 7.08203 10.3418 6.75977 10.166 6.58398C9.99023 6.4082 9.66797 6.4082 9.49219 6.58398L6.09375 10.0117V1.28125C6.09375 1.04688 5.85938 0.8125 5.625 0.8125C5.36133 0.8125 5.15625 1.04688 5.15625 1.28125V10.0117L1.72852 6.58398C1.55273 6.4082 1.23047 6.4082 1.05469 6.58398C0.878906 6.75977 0.878906 7.08203 1.05469 7.25781L5.27344 11.4766ZM10.7812 13H0.46875C0.205078 13 0 13.2344 0 13.4688C0 13.7324 0.205078 13.9375 0.46875 13.9375H10.7812C11.0156 13.9375 11.25 13.7324 11.25 13.4688C11.25 13.2344 11.0156 13 10.7812 13Z" fill="currentColor"/>
</svg></div><div>Download brand kit</div></a></div></div></div></div><div class="mobile-nav-menu"><div class="mobile-nav-menu-inner tile-shadow"><div data-w-id="80f81b27-826c-538b-6c5f-1bc11ce65711" class="mobile-nav-menu-close"><div class="icon-embed w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 18L6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18 6L5.99994 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div></div><div class="mobile-nav-menu-section"><div class="allcaps-label allcaps-label--mobile-nav">Products</div><div class="nav-dropdown-products"><a href="/user-management" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/656545520bd5f04e20a3a6a7_um.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">User Management</div><div class="text-color-light-2">Complete auth &amp; user management platform</div></div></a><a href="/single-sign-on" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/63e1062ae62bc2260203e96f_icon-sso.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Enterprise SSO</div><div class="text-color-light-2">Unified SSO integration for any identity provider</div></div></a><a href="/radar" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/673b4ed27842047837086d7a_icon-radar-nav.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Radar</div><div class="text-color-light-2">Real-time protection against bots, fraud, and abuse<br/></div></div></a><a href="https://authkit.com" target="_blank" class="nav-dropdown-link nav-dropdown-link--features cc-last w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/65654341bfdb733f6715f944_authkit.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">AuthKit</div><div class="text-color-light-2">Customizable UI for all authentication types</div></div></a><a href="/directory-sync" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/63e10629cdacaa53e05c2a95_icon-directory-sync.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Directory Sync</div><div class="text-color-light-2">User lifecycle management from corporate directories</div></div></a><a href="/rbac" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/68752d3fceb13184116f219f_icon-rbac.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Role-Based Access Control</div><div class="text-color-light-2">Powerful and flexible permissions for your users</div></div></a><a href="/mcp" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/68c8802359b1c7df06378d44_icon-mcp-auth.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">MCP Auth</div><div class="text-color-light-2">Secure auth for MCP servers</div></div></a><a href="/admin-portal" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/63e1062a21fa47cd37a717f5_icon-admin-portal.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Admin Portal</div><div class="text-color-light-2">Self-serve onboarding for corporate IT admins</div></div></a><a href="/vault" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/67daf11719d8c412f176a3d4_icon-vault.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Vault</div><div class="text-color-light-2">EKM for encrypting and optionally storing objects</div></div></a><a href="/multi-factor-authentication" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a3017a8e767a6e6a2078ef1_icon-mfa.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Multi-Factor Authentication</div><div class="text-color-light-2">Advanced auth methods</div></div></a><a href="/audit-logs" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/63e1062a39c3d330594d5a66_icon-audit-logs.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Audit Logs</div><div class="text-color-light-2">Event logging, exporting, and streaming</div></div></a><a href="https://workos.com/pipes" class="nav-dropdown-link nav-dropdown-link--features w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a3018b0e0c172dcc18705c9_icon-pipes.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Pipes</div><div class="text-color-light-2">Integrations for your apps &amp; agents</div></div></a><a href="https://workos.com/auth-md" class="nav-dropdown-link nav-dropdown-link--features cc-last w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a955cecbf0c7b36d1ba654e_auth-md.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">auth.md</div><div class="text-color-light-2">User registration for agents</div></div></a><a href="https://workos.com/atlas" class="nav-dropdown-link nav-dropdown-link--features cc-last w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a955cebb120ee1805ecc813_atlas.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Atlas</div><div class="text-color-light-2">Your AI coworker</div></div></a><a href="https://workos.com/airlock" class="nav-dropdown-link nav-dropdown-link--features cc-last w-inline-block"><img src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/6a955cecf7876373dee2020c_airlock.png" loading="lazy" width="40" height="41" alt="" class="nav-product-icon"/><div><div class="nav-dropdown-features-title">Airlock</div><div class="text-color-light-2">Intent-Based Access Control</div></div></a></div></div><div class="mobile-nav-menu-divider"></div><div class="mobile-nav-menu-section"><div class="allcaps-label allcaps-label--mobile-nav">Developers</div><div class="nav-links-wrap"><a href="https://workos.com/docs" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.11872 6.88128L7.5 6.26256L6.26256 7.5L6.88128 8.11872L8.11872 6.88128ZM9.5 9.5L10.1187 10.1187L10.7374 9.5L10.1187 8.88128L9.5 9.5ZM6.88128 10.8813L6.26256 11.5L7.5 12.7374L8.11872 12.1187L6.88128 10.8813ZM11.5 11.125H10.625V12.875H11.5V11.125ZM13.5 12.875H14.375V11.125H13.5V12.875ZM20.125 7V21H21.875V7H20.125ZM20 21.125H10V22.875H20V21.125ZM17 6.875H20V5.125H17V6.875ZM9.875 21V18H8.125V21H9.875ZM10 21.125C9.93096 21.125 9.875 21.069 9.875 21H8.125C8.125 22.0355 8.96447 22.875 10 22.875V21.125ZM20.125 21C20.125 21.069 20.069 21.125 20 21.125V22.875C21.0355 22.875 21.875 22.0355 21.875 21H20.125ZM21.875 7C21.875 5.96447 21.0355 5.125 20 5.125V6.875C20.069 6.875 20.125 6.93096 20.125 7H21.875ZM5 2.875H16V1.125H5V2.875ZM16.125 3V17H17.875V3H16.125ZM16 17.125H5V18.875H16V17.125ZM4.875 17V3H3.125V17H4.875ZM5 17.125C4.93096 17.125 4.875 17.069 4.875 17H3.125C3.125 18.0355 3.96447 18.875 5 18.875V17.125ZM16.125 17C16.125 17.069 16.069 17.125 16 17.125V18.875C17.0355 18.875 17.875 18.0355 17.875 17H16.125ZM16 2.875C16.069 2.875 16.125 2.93096 16.125 3H17.875C17.875 1.96447 17.0355 1.125 16 1.125V2.875ZM5 1.125C3.96447 1.125 3.125 1.96447 3.125 3H4.875C4.875 2.93096 4.93096 2.875 5 2.875V1.125ZM6.88128 8.11872L8.88128 10.1187L10.1187 8.88128L8.11872 6.88128L6.88128 8.11872ZM8.88128 8.88128L6.88128 10.8813L8.11872 12.1187L10.1187 10.1187L8.88128 8.88128ZM11.5 12.875H13.5V11.125H11.5V12.875Z" fill="currentColor"/>
</svg></div><div>Documentation</div></a><a href="/changelog" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 5C13.1797 5 19 10.8203 19 18M6 11C9.86599 11 13 14.134 13 18M7 18C7 18.5523 6.55228 19 6 19C5.44772 19 5 18.5523 5 18C5 17.4477 5.44772 17 6 17C6.55228 17 7 17.4477 7 18Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Changelog</div></a><a href="https://status.workos.com" target="_blank" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" stroke="currentColor" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 12H21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 21C13.6569 21 15 16.9706 15 12C15 7.02944 13.6569 3 12 3C10.3431 3 9 7.02944 9 12C9 16.9706 10.3431 21 12 21Z" stroke="currentColor" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>API Status</div><div class="nav-dropdown-link-external-icon w-embed"><svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.5 16L16.5 8" stroke="#8F96BD" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.5 8H16.5V14" stroke="#8F96BD" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div></a></div></div><div class="mobile-nav-menu-divider"></div><div class="mobile-nav-menu-section"><div class="allcaps-label allcaps-label--mobile-nav">Resources</div><div class="nav-links-wrap"><a href="/changelog" class="nav-dropdown-link nav-dropdown-link--desktop-only w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 5C13.1797 5 19 10.8203 19 18M6 11C9.86599 11 13 14.134 13 18M7 18C7 18.5523 6.55228 19 6 19C5.44772 19 5 18.5523 5 18C5 17.4477 5.44772 17 6 17C6.55228 17 7 17.4477 7 18Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Changelog</div></a><a href="/blog" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 20H20" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 20.0001V21.0001C8.26522 21.0001 8.51957 20.8947 8.70711 20.7072L8 20.0001ZM4 20.0001H3C3 20.5524 3.44772 21.0001 4 21.0001V20.0001ZM4 16.0001L3.29289 15.293C3.10536 15.4805 3 15.7349 3 16.0001H4ZM15.2929 4.7072L16 5.41431L16 5.41431L15.2929 4.7072ZM16.7071 4.7072L16 5.41431L16 5.41431L16.7071 4.7072ZM19.2929 7.29299L20 6.58588V6.58588L19.2929 7.29299ZM19.2929 8.7072L18.5858 8.00009L19.2929 8.7072ZM8 19.0001H4V21.0001H8V19.0001ZM5 20.0001V16.0001H3V20.0001H5ZM4.70711 16.7072L16 5.41431L14.5858 4.00009L3.29289 15.293L4.70711 16.7072ZM16 5.41431L18.5858 8.00009L20 6.58588L17.4142 4.00009L16 5.41431ZM18.5858 8.00009L7.29289 19.293L8.70711 20.7072L20 9.41431L18.5858 8.00009ZM18.5858 8.00009V8.00009L20 9.41431C20.781 8.63326 20.781 7.36693 20 6.58588L18.5858 8.00009ZM16 5.41431H16L17.4142 4.00009C16.6332 3.21904 15.3668 3.21904 14.5858 4.00009L16 5.41431Z" fill="currentColor"/>
<path d="M12 8L16 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Blog</div></a><a href="/guides" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.0513 20.8162C11.226 21.3402 11.7923 21.6233 12.3162 21.4487C12.8402 21.274 13.1233 20.7077 12.9487 20.1838L11.0513 20.8162ZM12.9487 20.1838L12.7464 19.577L10.8491 20.2094L11.0513 20.8162L12.9487 20.1838ZM8.47734 16.5H4V18.5H8.47734V16.5ZM4 16.5V6H2V16.5H4ZM4 6H9V4H4V6ZM11 8V19H13V8H11ZM9 6C10.1046 6 11 6.89543 11 8H13C13 5.79086 11.2091 4 9 4V6ZM4 6L4 6V4C2.89543 4 2 4.89543 2 6H4ZM4 16.5V16.5H2C2 17.6046 2.89543 18.5 4 18.5V16.5ZM12.7464 19.577C12.1339 17.7394 10.4143 16.5 8.47734 16.5V18.5C9.55342 18.5 10.5088 19.1886 10.8491 20.2094L12.7464 19.577Z" fill="currentColor"/>
<path d="M12.9487 20.8162C12.774 21.3402 12.2077 21.6233 11.6838 21.4487C11.1598 21.274 10.8767 20.7077 11.0513 20.1838L12.9487 20.8162ZM11.0513 20.1838L11.2536 19.577L13.1509 20.2094L12.9487 20.8162L11.0513 20.1838ZM15.5227 16.5H20V18.5H15.5227V16.5ZM20 16.5V6H22V16.5H20ZM20 6H15V4H20V6ZM13 8V19H11V8H13ZM15 6C13.8954 6 13 6.89543 13 8H11C11 5.79086 12.7909 4 15 4V6ZM20 6L20 6V4C21.1046 4 22 4.89543 22 6H20ZM20 16.5V16.5H22C22 17.6046 21.1046 18.5 20 18.5V16.5ZM11.2536 19.577C11.8661 17.7394 13.5857 16.5 15.5227 16.5V18.5C14.4466 18.5 13.4912 19.1886 13.1509 20.2094L11.2536 19.577Z" fill="currentColor"/>
</svg></div><div>Guides</div></a><a href="/podcast" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 13H22C22 12.4477 21.5523 12 21 12V13ZM21 12H17V14H21V12ZM15 14V19H17V14H15ZM17 21H20V19H17V21ZM22 19V13H20V19H22ZM20 21C21.1046 21 22 20.1046 22 19H20V21ZM15 19C15 20.1046 15.8954 21 17 21V19H15ZM17 12C15.8954 12 15 12.8954 15 14H17V12Z" fill="currentColor"/>
<path d="M3 13V12C2.44772 12 2 12.4477 2 13H3ZM3 14H7V12H3V14ZM7 14V19H9V14H7ZM7 19H4V21H7V19ZM4 19V13H2V19H4ZM4 19L4 19H2C2 20.1046 2.89543 21 4 21V19ZM7 19V21C8.10457 21 9 20.1046 9 19H7ZM7 14H9C9 12.8954 8.10457 12 7 12V14Z" fill="currentColor"/>
<path d="M3 13C3 8.02944 7.02944 4 12 4C16.9706 4 21 8.02944 21 13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Podcast</div></a><a href="/about" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="25" height="26" viewBox="0 0 25 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 13.0007C2 13.3515 2.08586 13.7023 2.25186 14.0039L5.26274 19.6106C5.57184 20.1829 6.04121 20.6507 6.62507 20.8599C7.77562 21.2722 8.96623 20.743 9.53291 19.6844L10.2599 18.3304L7.3921 13.0007L10.4201 7.35714L11.1471 6.00317C11.3646 5.59698 11.6566 5.26464 12 5H11.6852H7.32914C6.51059 5 5.75501 5.46773 5.3486 6.23088L2.25186 11.9976C2.08586 12.2991 2 12.6499 2 13.0007Z" stroke="currentColor" stroke-width="2"/>
<path d="M22 12.9976C22 12.6468 21.9141 12.2959 21.7481 11.9943L18.6972 6.31259C18.1305 5.25998 16.9399 4.73059 15.7894 5.13686C15.2055 5.34615 14.7361 5.81398 14.427 6.38646L13.7401 7.66068L16.6079 12.9976L13.5799 18.6424L12.8529 19.9966C12.6354 20.3967 12.3434 20.7353 12 21H12.3148H16.6709C17.4894 21 18.245 20.5322 18.6514 19.7689L21.7481 14.001C21.9141 13.6994 22 13.3485 22 12.9976Z" stroke="currentColor" stroke-width="2"/>
</svg></div><div>Company</div></a><a href="/careers" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 8H4C3.44772 8 3 8.44772 3 9V19C3 19.5523 3.44772 20 4 20H20C20.5523 20 21 19.5523 21 19V9C21 8.44772 20.5523 8 20 8Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 8C8 5.79086 9.79086 4 12 4C14.2091 4 16 5.79086 16 8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Careers</div></a><a href="/security" class="nav-dropdown-link w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.2902 20.8968L12.6452 21.8317L12.6452 21.8317L12.2902 20.8968ZM11.7098 20.8968L11.3548 21.8317L11.3548 21.8317L11.7098 20.8968ZM5 4H19V2H5V4ZM19 4V10.1649H21V4H19ZM5 10.1649V4H3V10.1649H5ZM19 10.1649C19 16.8586 13.3228 19.435 11.9351 19.962L12.6452 21.8317C14.1289 21.2682 21 18.2341 21 10.1649H19ZM3 10.1649C3 18.2341 9.87108 21.2682 11.3548 21.8317L12.0649 19.962C10.6772 19.435 5 16.8586 5 10.1649H3ZM11.9351 19.962C11.95 19.9564 11.9725 19.951 12 19.951C12.0275 19.951 12.05 19.9564 12.0649 19.962L11.3548 21.8317C11.7737 21.9908 12.2263 21.9908 12.6452 21.8317L11.9351 19.962ZM19 4V4H21C21 2.89543 20.1046 2 19 2V4ZM5 2C3.89543 2 3 2.89543 3 4H5V4V2Z" fill="currentColor"/>
<path d="M15.7071 9.70711C16.0976 9.31658 16.0976 8.68342 15.7071 8.29289C15.3166 7.90237 14.6834 7.90237 14.2929 8.29289L15.7071 9.70711ZM11 13L10.2929 13.7071C10.6834 14.0976 11.3166 14.0976 11.7071 13.7071L11 13ZM9.70711 10.2929C9.31658 9.90237 8.68342 9.90237 8.29289 10.2929C7.90237 10.6834 7.90237 11.3166 8.29289 11.7071L9.70711 10.2929ZM14.2929 8.29289L10.2929 12.2929L11.7071 13.7071L15.7071 9.70711L14.2929 8.29289ZM11.7071 12.2929L9.70711 10.2929L8.29289 11.7071L10.2929 13.7071L11.7071 12.2929Z" fill="currentColor"/>
</svg></div><div>Security</div></a><a href="/support-plans" class="nav-dropdown-link nav-dropdown-link--last w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.68497 19.605L8.2207 18.7606C7.96683 18.5996 7.65397 18.5613 7.36874 18.6563L7.68497 19.605ZM3.5 21L2.55132 20.6838C2.43154 21.0431 2.52506 21.4393 2.79289 21.7071C3.06073 21.9749 3.45689 22.0685 3.81623 21.9487L3.5 21ZM4.89499 16.815L5.84367 17.1313C5.93875 16.846 5.90045 16.5332 5.73938 16.2793L4.89499 16.815ZM12.5 22C18.0228 22 22.5 17.5228 22.5 12H20.5C20.5 16.4183 16.9183 20 12.5 20V22ZM7.14923 20.4494C8.69708 21.4315 10.5337 22 12.5 22V20C10.9242 20 9.45764 19.5454 8.2207 18.7606L7.14923 20.4494ZM7.36874 18.6563L3.18377 20.0513L3.81623 21.9487L8.0012 20.5537L7.36874 18.6563ZM4.44868 21.3162L5.84367 17.1313L3.94631 16.4988L2.55132 20.6838L4.44868 21.3162ZM2.5 12C2.5 13.9663 3.06855 15.8029 4.0506 17.3508L5.73938 16.2793C4.95458 15.0424 4.5 13.5758 4.5 12H2.5ZM12.5 2C6.97715 2 2.5 6.47715 2.5 12H4.5C4.5 7.58172 8.08172 4 12.5 4V2ZM22.5 12C22.5 6.47715 18.0228 2 12.5 2V4C16.9183 4 20.5 7.58172 20.5 12H22.5Z" fill="currentColor"/>
</svg></div><div>Support Plans</div></a><a href="https://workos.com/customers" class="nav-dropdown-link nav-dropdown-link--mobile-only w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 20C7 18.3431 9.23858 17 12 17C14.7614 17 17 18.3431 17 20" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M18 14.2495C19.7659 14.7124 21 15.7697 21 16.9999" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M6 14.2495C4.2341 14.7124 3 15.7697 3 16.9999" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M12 14C13.6569 14 15 12.6569 15 11C15 9.34315 13.6569 8 12 8C10.3431 8 9 9.34315 9 11C9 12.6569 10.3431 14 12 14Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M18 10.2361C18.6137 9.68679 19 8.8885 19 8C19 6.34315 17.6569 5 16 5C15.2316 5 14.5308 5.28885 14 5.76389" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M6 10.2361C5.38625 9.68679 5 8.8885 5 8C5 6.34315 6.34315 5 8 5C8.76835 5 9.46924 5.28885 10 5.76389" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg></div><div>Customers</div></a><a href="/pricing" class="nav-dropdown-link nav-dropdown-link--mobile-only w-inline-block"><div class="nav-dropdown-link-icon w-embed"><svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9811 19.9661L11.274 20.6732H11.274L11.9811 19.9661ZM4.53411 12.5191L3.827 13.2263H3.827L4.53411 12.5191ZM13.0194 4.03386L13.7265 3.32676V3.32676L13.0194 4.03386ZM20.4664 11.4808L21.1735 10.7737V10.7737L20.4664 11.4808ZM20.4664 12.8951L19.7593 12.188L20.4664 12.8951ZM13.3953 19.9661L14.1024 20.6732L13.3953 19.9661ZM4.24532 11.7215L5.24122 11.812H5.24122L4.24532 11.7215ZM4.83458 5.23969L5.83047 5.33023L4.83458 5.23969ZM5.73993 4.33433L5.83047 5.33023H5.83047L5.73993 4.33433ZM12.2217 3.74508L12.3123 4.74097L12.2217 3.74508ZM12.6882 19.259L5.24122 11.812L3.827 13.2263L11.274 20.6732L12.6882 19.259ZM12.3123 4.74097L19.7593 12.188L21.1735 10.7737L13.7265 3.32676L12.3123 4.74097ZM19.7593 12.188L12.6882 19.259L14.1024 20.6732L21.1735 13.6022L19.7593 12.188ZM5.24122 11.812L5.83047 5.33023L3.83868 5.14916L3.24943 11.631L5.24122 11.812ZM5.83047 5.33023L12.3123 4.74097L12.1312 2.74919L5.6494 3.33844L5.83047 5.33023ZM5.83047 5.33023L5.83047 5.33023L5.6494 3.33844C4.6879 3.42585 3.92609 4.18765 3.83868 5.14916L5.83047 5.33023ZM19.7593 12.188L19.7593 12.188L21.1735 13.6022C21.9545 12.8211 21.9545 11.5548 21.1735 10.7737L19.7593 12.188ZM13.7265 3.32676C13.3068 2.90705 12.7223 2.69545 12.1312 2.74919L12.3123 4.74097H12.3123L13.7265 3.32676ZM5.24122 11.812H5.24122L3.24943 11.631C3.19569 12.2221 3.40729 12.8065 3.827 13.2263L5.24122 11.812ZM11.274 20.6732C12.055 21.4543 13.3214 21.4543 14.1024 20.6732L12.6882 19.259L12.6882 19.259L11.274 20.6732Z" fill="currentColor"/>
<path d="M8.79875 8.29875C9.18928 7.90823 9.82244 7.90823 10.213 8.29875C10.6035 8.68928 10.6035 9.32244 10.213 9.71297C9.82244 10.1035 9.18928 10.1035 8.79875 9.71297C8.40823 9.32244 8.40823 8.68928 8.79875 8.29875Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div>Pricing</div></a></div></div><div class="mobile-nav-cta-wrap"><a role="button" href="https://workos.com/signin" class="button button--mobile-nav w-inline-block"><div>Sign in</div></a><a role="button" href="https://workos.com/signup" class="nav-cta w-inline-block"><div>Sign up</div></a></div></div></div></nav><main class="main"><section class="hero cc-article"><div class="page-padding"><div class="container"><div class="article-wrapper"><div class="post-toc-wrap"><div class="post-toc-inner"><div class="toc-label">In this article</div></div></div><div class="article-container"><div class="article-header"><div class="text-color-light-2 u-mb-16 hidden-on-mobile w-condition-invisible">June 27, 2024</div><div class="text-color-light-2 u-mb-16 text-small mobile-only">June 27, 2024</div><h1 class="section-heading cc-article">From four to five 9s of uptime by migrating to Kubernetes </h1><p class="article-summary w-condition-invisible w-dyn-bind-empty"></p><p class="article-summary">When we launched User Management along with a free tier of up to 1 million MAUs, we faced several challenges using Heroku: the lack of an SLA, limited rollout functionality, and inadequate data locality options. To address these, we migrated to Kubernetes on EKS, developing a custom platform called Terrace to streamline deployment, secret management, and automated load balancing.</p><div class="blog-post-info"><div class="blog-author"><img height="24" loading="eager" width="24" src="https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667d68d344a485251d1ea59c_TBDJCFH1R-U03PM55RB89-5706012f7eb2-512.png" alt="" sizes="24px" srcset="https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667d68d344a485251d1ea59c_TBDJCFH1R-U03PM55RB89-5706012f7eb2-512-p-500.png 500w, https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667d68d344a485251d1ea59c_TBDJCFH1R-U03PM55RB89-5706012f7eb2-512.png 512w" class="blog-avatar cc-margin cc-small"/><div>Matheus Lichtnow</div></div><div class="multiple-authors-wrap w-condition-invisible"><div class="blog-author w-condition-invisible"><img height="24" loading="eager" width="24" src="https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667d68d344a485251d1ea59c_TBDJCFH1R-U03PM55RB89-5706012f7eb2-512.png" alt="" sizes="100vw" srcset="https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667d68d344a485251d1ea59c_TBDJCFH1R-U03PM55RB89-5706012f7eb2-512-p-500.png 500w, https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667d68d344a485251d1ea59c_TBDJCFH1R-U03PM55RB89-5706012f7eb2-512.png 512w" class="blog-avatar cc-small"/><div class="w-embed"><div style="position:absolute; width:100%; height:100%;" data-tippy-content="Matheus Lichtnow"></div></div></div><div class="blog-author"><img height="24" loading="eager" width="24" src="" alt="" class="blog-avatar cc-small w-dyn-bind-empty"/><div class="w-embed"><div style="position:absolute; width:100%; height:100%;" data-tippy-content=""></div></div></div><div class="blog-author w-condition-invisible"><img height="24" loading="eager" width="24" src="" alt="" class="blog-avatar cc-small w-dyn-bind-empty"/><div class="w-embed"><div style="position:absolute; width:100%; height:100%;" data-tippy-content=""></div></div></div><div class="blog-author w-condition-invisible"><div class="w-embed"><div style="position:absolute; width:100%; height:100%;" data-tippy-content=""></div></div><img height="24" loading="eager" width="24" src="" alt="" class="blog-avatar cc-small w-dyn-bind-empty"/></div><div class="blog-author w-condition-invisible"><div class="w-embed"><div style="position:absolute; width:100%; height:100%;" data-tippy-content=""></div></div><img height="24" loading="eager" width="24" src="" alt="" class="blog-avatar cc-small w-dyn-bind-empty"/></div><div class="blog-author w-condition-invisible"><div class="w-embed"><div style="position:absolute; width:100%; height:100%;" data-tippy-content=""></div></div><img height="24" loading="eager" width="24" src="" alt="" class="blog-avatar cc-small w-dyn-bind-empty"/></div><div class="blog-author w-condition-invisible"><div class="w-embed"><div style="position:absolute; width:100%; height:100%;" data-tippy-content=""></div></div><img height="24" loading="eager" width="24" src="" alt="" class="blog-avatar cc-small w-dyn-bind-empty"/></div><div class="blog-author w-condition-invisible"><div class="w-embed"><div style="position:absolute; width:100%; height:100%;" data-tippy-content=""></div></div><img height="24" loading="eager" width="24" src="" alt="" class="blog-avatar cc-small w-dyn-bind-empty"/></div></div><div class="text-color-light-2 hidden-on-mobile">June 27, 2024</div></div></div><div class="article-ai-wrap"><div class="allcaps-label article-ai">Explore with AI</div><div class="article-ai-links"><a id="summarize-chatgpt" href="#" target="_blank" class="article-ai-item w-inline-block"><div class="svg-embed w-embed"><svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.9258 6.13819C14.0936 5.63311 14.1516 5.09806 14.096 4.56877C14.0404 4.03949 13.8725 3.52816 13.6035 3.06894C13.2048 2.37483 12.5959 1.82528 11.8646 1.49954C11.1334 1.17379 10.3176 1.08866 9.53491 1.25644C9.09023 0.761789 8.52321 0.392857 7.89082 0.186695C7.25843 -0.019467 6.58292 -0.0556004 5.93215 0.081924C5.28137 0.219448 4.67824 0.525789 4.18333 0.970177C3.68841 1.41457 3.31914 1.98136 3.1126 2.61362C2.59114 2.72056 2.09851 2.93755 1.66763 3.25012C1.23675 3.56269 0.877554 3.96362 0.614036 4.42613C0.210933 5.11908 0.038649 5.92227 0.122093 6.71959C0.205536 7.5169 0.540383 8.26702 1.07822 8.8615C0.909889 9.36633 0.851301 9.90129 0.906379 10.4306C0.961457 10.9599 1.12893 11.4713 1.3976 11.9307C1.79687 12.6251 2.4063 13.1747 3.13804 13.5005C3.86979 13.8262 4.68606 13.9112 5.46922 13.7433C5.82251 14.1411 6.25661 14.459 6.74254 14.6757C7.22847 14.8924 7.75504 15.003 8.2871 15C9.08937 15.0007 9.87113 14.7465 10.5195 14.2741C11.1679 13.8016 11.6494 13.1353 11.8945 12.3714C12.4159 12.2643 12.9084 12.0472 13.3393 11.7346C13.7701 11.4221 14.1294 11.0212 14.393 10.5588C14.7914 9.86688 14.9607 9.0667 14.8768 8.27272C14.7929 7.47874 14.46 6.73157 13.9258 6.13819ZM8.2871 14.0182C7.63005 14.0193 6.9936 13.789 6.48935 13.3677L6.57804 13.3175L9.56447 11.5936C9.6388 11.55 9.70051 11.4879 9.74354 11.4132C9.78657 11.3385 9.80945 11.254 9.80991 11.1678V6.95725L11.0724 7.68763C11.0787 7.69079 11.0841 7.69538 11.0882 7.70103C11.0923 7.70668 11.095 7.71322 11.0962 7.72012V11.2092C11.0946 11.9538 10.7981 12.6673 10.2717 13.1938C9.74519 13.7202 9.03162 14.0167 8.2871 14.0182ZM2.24916 11.4399C1.91964 10.8709 1.80133 10.2039 1.91504 9.55631L2.00379 9.60956L4.99316 11.3334C5.06713 11.3768 5.15134 11.3997 5.2371 11.3997C5.32286 11.3997 5.40707 11.3768 5.48104 11.3334L9.13279 9.22812V10.6859C9.13244 10.6934 9.1304 10.7008 9.12681 10.7075C9.12321 10.7141 9.11816 10.7199 9.11204 10.7243L6.08716 12.4689C5.44162 12.8408 4.67488 12.9413 3.95529 12.7483C3.23571 12.5554 2.62209 12.0848 2.24916 11.4399ZM1.46266 4.93475C1.79446 4.36211 2.31818 3.92533 2.9411 3.70175V7.25C2.93997 7.33572 2.96188 7.42017 3.00452 7.49455C3.04716 7.56892 3.10899 7.63048 3.18354 7.67281L6.81754 9.76925L5.55497 10.4996C5.54814 10.5032 5.54052 10.5051 5.53279 10.5051C5.52505 10.5051 5.51743 10.5032 5.5106 10.4996L2.49166 8.758C1.84732 8.38451 1.37725 7.7709 1.18439 7.05155C0.991525 6.3322 1.09159 5.56573 1.46266 4.92V4.93475ZM11.8353 7.34462L8.18954 5.2275L9.44916 4.5C9.45599 4.49637 9.46361 4.49447 9.47135 4.49447C9.47909 4.49447 9.4867 4.49637 9.49354 4.5L12.5125 6.24456C12.9741 6.51091 13.3504 6.90307 13.5974 7.37525C13.8445 7.84744 13.9522 8.38017 13.9079 8.91125C13.8635 9.44233 13.669 9.94984 13.3471 10.3745C13.0251 10.7992 12.589 11.1236 12.0897 11.3097V7.76144C12.087 7.67586 12.0622 7.59243 12.0176 7.51935C11.973 7.44626 11.9103 7.38609 11.8353 7.34462ZM13.092 5.45519L13.0033 5.40194L10.0198 3.66331C9.94543 3.61964 9.8607 3.59662 9.77441 3.59662C9.68812 3.59662 9.60339 3.61964 9.52897 3.66331L5.88029 5.76856V4.31087C5.87951 4.30346 5.88075 4.29598 5.88387 4.28921C5.887 4.28245 5.89189 4.27665 5.89804 4.27244L8.91697 2.53081C9.37967 2.26426 9.90869 2.13496 10.4422 2.15804C10.9757 2.18111 11.4915 2.35561 11.9295 2.66111C12.3674 2.96662 12.7094 3.39051 12.9152 3.88321C13.1211 4.3759 13.1825 4.91703 13.0921 5.44331L13.092 5.45519ZM5.19122 8.03937L3.92872 7.312C3.92241 7.3082 3.91701 7.30305 3.9129 7.29693C3.9088 7.2908 3.90609 7.28385 3.90497 7.27656V3.79638C3.90567 3.26248 4.05834 2.73982 4.34513 2.2895C4.63192 1.83918 5.04099 1.4798 5.5245 1.2534C6.00801 1.02699 6.54598 0.942913 7.07551 1.01099C7.60505 1.07906 8.10426 1.29648 8.51479 1.63781L8.42604 1.68813L5.43966 3.41188C5.36533 3.45547 5.30362 3.51765 5.26059 3.5923C5.21756 3.66696 5.19469 3.75152 5.19422 3.83769L5.19122 8.03937ZM5.87722 6.561L7.50347 5.62362L9.13279 6.561V8.43562L7.50941 9.37294L5.88022 8.43562L5.87722 6.561Z" fill="currentColor"/>
</svg></div><div>Open in ChatGPT</div></a><a id="summarize-claude" href="#" target="_blank" class="article-ai-item w-inline-block"><div class="svg-embed w-embed"><svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.8151 2.21312H8.52019L12.7052 12.7869H15L10.8151 2.21312ZM4.18494 2.21312L0 12.7869H2.34012L3.19594 10.5664H7.57419L8.43 12.7869H10.7701L6.58519 2.21306L4.18494 2.21312ZM3.95294 8.60262L5.38506 4.88662L6.81719 8.60262H3.95294Z" fill="currentColor"/>
</svg></div><div>Open in Claude</div></a><a id="summarize-perplexity" href="#" target="_blank" class="article-ai-item w-inline-block"><div class="svg-embed w-embed"><svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.3656 0V4.545H14.0625V11.0125H12.2281V15L7.83 11.1287V14.9694H7.14813V11.1244L2.745 15V10.9594H0.9375V4.4925H2.74V0L7.14813 4.05875V0.11875H7.82938V4.175L12.3656 0ZM7.83 5.6525V10.2269L11.5463 13.4981V9.025L7.83 5.6525ZM7.14312 5.6025L3.42687 8.97625V13.4981L7.14312 10.2269V5.60313V5.6025ZM12.2281 10.34H13.3806V5.21812H8.4125L12.2281 8.68062V10.34ZM6.61438 5.165H1.61875V10.2869H2.74375V8.67688L6.61375 5.16437L6.61438 5.165ZM3.42187 1.5475V4.49125H6.61875L3.42187 1.5475ZM11.6838 1.5475L8.48688 4.49125H11.6838V1.5475Z" fill="currentColor"/>
</svg></div><div>Open in Perplexity</div></a></div></div><div class="post-rt w-richtext"><h2>User Management and Scale</h2><p>In 2023 we launched <a href="https://workos.com/docs/user-management">WorkOS User Management</a> with a free tier that includes 1 million monthly active users. We quickly realized that Heroku couldn&#x27;t support a vision that big. Here are the four biggest challenges we faced:</p><ul role="list"><li>No SLA —  Heroku does not provide an SLA, making it much more difficult for us to provide one to our customers.</li><li>Limiting rollout functionality — With the 99.99% of uptime target, we needed a platform that could both quickly rollout a new version and support more sophisticated rollout strategies, such as blue/green and canary deployments.</li><li>Security — Heroku’s Private Spaces run within AWS VPCs, but given its platform nature, it is very difficult to address vectors of attack. <a href="https://status.heroku.com/incidents/2413">See Heroku’s most recent severe incident</a>.</li><li>Fine grained data locality — While Heroku allows apps to be deployed in multiple regions, they will always lag behind in availability when compared to the underlying Infrastructure as a Service (IaaS), which is AWS.</li></ul><p>Since the initial stages of the migration, we sought for a platform that would allow us to customize it to fit our needs. We knew that the migration was going to be a risky and lengthy process, and we wanted to do it only once, so any custom bits we needed, we could either reach for OSS or build it ourselves.</p><p>We evaluated various vendors, including ECS, OpenShift, Render, and fly.io, to see if they could meet our needs. While each had promising features, they either lacked one of our key requirements or didn&#x27;t offer the customization tools we wanted. Ultimately, we chose Kubernetes on EKS as the underlying platform.</p><h2>Our Own Kubernetes Flavor</h2><p>Our main goal with this new platform was to create a seamless, efficient way to deploy new services. We wanted the &quot;golden path&quot; to be fast and easy, and even when deviating from it, the experience would remain user-friendly.</p><p>To provide this experience to our users, we built Terrace, a Heroku like platform on top of EKS that allowed engineers to create their own apps in TypeScript without having to learn about the nooks and crannies of Kubernetes.</p><p>The team had mixed experiences with Kubernetes, and one key lesson we learned was to avoid having special clusters, meaning treating them like cattle, not pets. Clusters can break, and when they do, the remediation that follows can be painful. To address this, we aimed to use Terraform for our clusters, making it easy, fast, and automated to bring them up or down. This included both the clusters themselves and their Operators and Controllers.</p><p>With clusters up and running, we identified the functionalities in Heroku that we wanted to replicate in Terrace.</p><h3>Secret Injection</h3><p>Heroku has the concept of <a href="https://devcenter.heroku.com/articles/config-vars">Config Vars</a>, which are key value pairs that are injected as environment variables into each app. It also offers the functionality to synchronize these values from 3rd party vendors, such as AWS SSM, Doppler and Vault. We wanted to maintain this ability, which can be summarized in two steps:</p><ol role="list"><li>Synchronize secrets through the integration</li><li>Rollout new replicas with the updated secrets</li></ol><p>First, we decided to use the <a href="https://external-secrets.io/latest/">External Secrets Operator</a>, which allows us to pull secrets from multiple vendors and inject them as Secret resources in our clusters.</p><p>Next, we went with <a href="https://docs.stakater.com/reloader/">Reloader</a>. This Kubernetes Controller watches for changes in Secret resources and triggers rolling upgrades on the tied Workloads.</p><p>The final workflow should feel familiar to engineers, as it is similar to how Heroku operates. Engineers will update the secrets in the third-party vendor, which will then sync with the Secret resources in the clusters and trigger a rolling upgrade on the corresponding workload.</p><h3>Automated Load Balancing, TLS  and DNS</h3><p>Choosing the right Ingress Controller is a common topic when migrating to Kubernetes since there are a lot of different implementations, each one focusing on specific use cases (<a href="https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/">curated list by The Kubernetes Authors</a>). We ended up choosing the <a href="https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/">AWS Application Load Balancer Controller</a> for its robust EKS integration and automated TLS management by leveraging its <a href="https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/annotations/#certificate-arn">AWS Certificate Manager integration</a>. This meant that we could automatically spin up load balancers with their TLS certificates getting automatically renewed.</p><p>On the DNS side, we wanted our CNAME records to be automatically created and synced with whatever records the load balancers had, so we leveraged the <a href="https://kubernetes-sigs.github.io/external-dns/v0.14.2/">ExternalDNS controller</a>. This detects the hosts present on the rules of each Ingress resource and creates the appropriate DNS records in the configured DNS provider.</p><h3>Machine Provisioning</h3><p>When using an IaaS abstraction like Heroku, we wanted to avoid thinking about provisioning machines to run our apps. For example, if we had to scale it to a million replicas, the platform should do the heavy lifting and give us the hardware to run it. There were two options to address this: <a href="https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler">Cluster Autoscaler</a> and <a href="https://karpenter.sh/">Karpenter</a>. We decided to go with the latter due to its more complete feature set and documentation.</p><h3>Application Management</h3><p>Although the <code>kubectl</code> CLI is in a very good state today, managing complex apps can become very difficult. We evaluated two options for managing our apps, <a href="https://argo-cd.readthedocs.io/en/stable/">ArgoCD</a> and <a href="https://www.argonaut.dev/">Argonaut</a>. We decided to go with ArgoCD on this one due to its extension capabilities and maturity as a solution.</p><p>With the necessary tools in place, we faced another important decision: should our infrastructure team manage every service, or should we make it self-serve for other teams? To decide, we considered our team sizes and our automation goals. We chose the self-serve option, but with clearly defined escape hatches. This approach would create an abstraction layer for most engineers to work with, while still allowing them to manage their own Kubernetes tasks if needed.</p><h3>The Path to Self Serving</h3><p>The abstraction we chose was similar to Heroku’s Apps and Processes, where each App could contain multiple processes that would be deployed to multiple clusters. Since our codebase is mostly done with TypeScript, we decided to go with the same tech stack. Enter <a href="https://cdk8s.io/">cdk8s</a>, which is a tool that allows writing Kubernetes resources in multiple languages, including TypeScript.</p><p>Here&#x27;s the flow we envisioned for generating the Kubernetes manifests:</p><figure style="max-width:2250px" class="w-richtext-align-fullwidth w-richtext-figure-type-image"><div><img alt="" src="https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/6761c8ca9c6ca82f8d51c350_667d7d9f9e9335a855417493_kubernetes-manifests.webp" loading="lazy"/></div></figure><p>This direction provided us with more flexibility for building apps when compared to other popular solutions like Helm. This meant that instead of just templating, we had all of the Node.js ecosystem at our disposal, so customizing each app was easy. This is especially true with cdk8s, since its own abstraction allows us to attach any Kubernetes resources to its <a href="https://cdk8s.io/docs/latest/basics/chart/">Chart</a> object.</p><p>With our abstraction on top of cdk8s done, all that was left was a way to get the generated Kubernetes resources from our apps to be managed by ArgoCD, our application manager. We had two options here, either a Git artifact repository where we would push changes on every deploy or extending ArgoCD and make it understand cdk8s. Since automation was a general theme of this migration, we went with latter. Luckily, ArgoCD was just moving its <a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/config-management-plugins/#sidecar-plugin">Sidecar Plugin</a> functionality out of beta, which we took advantage of.</p><p>For the Sidecar Plugin to work, we had to first build a Docker image with the proper <a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/config-management-plugins/#write-the-plugin-configuration-file">Config Management Plugin</a> file located at<code> /home/argocd/cmp-server/config/plugin.yaml</code> and add it as a sidecar container of ArgoCD’s Repo Server. Here’s an example <code>plugin.yaml</code> file:</p><div class="w-embed"><pre>
<code class="language-yaml" data-prismjs-copy="">
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: cdk8s
spec:
version: v1.0
init:
command: [sh, -ce]
args:
# Install your dependencies here. Caching is highly recommended, since it will
# run this step on every ArgoCD Sync.
- npm install
generate:
command: [sh, -ce]
args:
- |
# Synthesize your cdk8s Chart, but output only to stderr, so that ArgoCD
# can pick up errors if they happen.
cdk8s synth 1> /dev/null
# Output your generated Kubernetes resources in the end. ArgoCD will consider
# everything emitted to stdout as part of the your ArgoCD app manifest.
cat dist/app.k8s.yaml
</code>
</pre></div><p>Now we can build the Docker image with the YAML file above and attach it as a sidecar container in ArgoCD’s Repo Server:</p><div class="w-embed"><pre>
<code class="language-yaml" data-prismjs-copy="">
FROM node:<NODE_VERSION>-alpine
WORKDIR /home/argocd/cmp-server/config/
COPY plugin.yaml .
# Follow with any additional setup needed by your repository
</code>
</pre></div><p>Follow by adding the Docker image above as an ArgoCD’s Repo Server sidecar container:</p><div class="w-embed"><pre>
<code class="language-yaml" data-prismjs-copy="">
containers:
...
# Sidecar container definition
- command:
- /var/run/argocd/argocd-cmp-server
image: <YOUR_IMAGE_TAG>
name: cdk8s
securityContext:
runAsNonRoot: true
runAsUser: 999
volumeMounts:
# The init containers will inject the executables in this mounted volume
- mountPath: /var/run/argocd
name: var-files
- mountPath: /home/argocd/cmp-server/plugins
name: plugins
- mountPath: /tmp
name: cmp-tmp
volumes:
- emptyDir: {}
name: cmp-tmp
</code>
</pre></div><p>Now you are able to create an ArgoCD Application resources using the new plugin. Here’s how it looks like:</p><div class="w-embed"><pre>
<code class="language-yaml" data-prismjs-copy="">
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
source:
path: <PATH_WHERE_PLUGIN_WILL_RUN_THE_COMMANDS>
plugin:
name: cdk8s-v1.0 # This comes from the plugin definition's name and version
</code>
</pre></div><p>For further configuration on how to leverage parameters and environment variables in the plugin, check out<a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/config-management-plugins/#sidecar-plugin"> ArgoCD’s docs</a>.</p><h2>Migration and Results</h2><p>During the migration process, we decided to do two different types of load tests in our apps. We started out with short bursts of requests and after making sure that it was working properly on those scenarios, we performed soak tests that mimicked the network traffic we had in production. The idea here was to understand how normal operations, such as deployments, including ones that could bring the service down, would impact the system reliability.</p><p>During the soak tests, we discovered some configurations that needed tweaking. More importantly, we gained the ability to fully understand what was happening throughout our system. With Heroku, we struggled with observability because most of the stack was a black box to us. Now, we can identify and understand all the failure modes in our system.</p><p>After the migration, our uptime improved significantly, from four nines to consistently achieving five nines over 7 and 30-day periods across all services. This increase is directly related to our improved ability to gain insights from our systems and fine-tune them accordingly.</p><p>Another factor enhancing our system&#x27;s reliability is the speed at which we can roll out changes. On Heroku, deploying a new version could take up to 12 minutes. In Terrace, new versions are rolled out in just 2-3 minutes. This speed difference can elevate uptime from three to four nines in a 7-day window.</p><h2>The Future of Terrace</h2><p>Reflecting on our initial goals, the only need we haven&#x27;t yet implemented is deploying to different data localities. However, we have the capability to achieve this easily, so it will be our focus in the near future.</p><p>Currently, we use rolling updates for rollouts. While this approach allows us to move quickly, we want to ensure that critical paths in our product remain bug-free and reliable. To achieve this, we plan to experiment with blue/green and canary deployment strategies.</p><p>Additionally, our strategy with ArgoCD’s Sidecar Plugin has some downsides, particularly with ArgoCD’s UI. The UI can feel sluggish because it attempts to go through the plugin flow on page loads within the Application view. To address this, we plan to build a Terrace Operator. This operator will apply a single <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/">Custom Resource</a> containing all the app and process definitions, and then create all the necessary resources for them to work efficiently.</p></div></div></div></div></div></section><section class="section section--bottom-cta"><div class="page-padding"><div class="container"><div class="bottom-cta-grid"><a href="/careers" class="bottom-cta w-inline-block"><div class="bottom-cta-icon w-embed"><svg width="35" height="34" viewBox="0 0 35 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.91699 28.1667H32.0837" stroke="#D8D9FA" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14.8285 11.5423L15.8309 10.4264L15.8309 10.4264L14.8285 11.5423ZM21.391 17.438L20.3885 18.5538L20.3885 18.5538L21.391 17.438ZM21.8747 28.1667V29.6667C22.7031 29.6667 23.3747 28.9951 23.3747 28.1667H21.8747ZM6.31673 17.438L7.31919 18.5538H7.31919L6.31673 17.438ZM12.8792 11.5423L13.8817 12.6581V12.6581L12.8792 11.5423ZM13.826 12.6581L20.3885 18.5538L22.3934 16.3222L15.8309 10.4264L13.826 12.6581ZM20.3747 18.5228V28.1667H23.3747V18.5228H20.3747ZM7.33301 26.7083V18.5228H4.33301V26.7083H7.33301ZM7.31919 18.5538L13.8817 12.6581L11.8768 10.4264L5.31427 16.3222L7.31919 18.5538ZM21.8747 26.6667H7.29134V29.6667H21.8747V26.6667ZM7.33301 18.5228C7.33301 18.5346 7.32798 18.5459 7.31919 18.5538L5.31427 16.3222C4.68973 16.8832 4.33301 17.6833 4.33301 18.5228H7.33301ZM4.33301 26.7083C4.33301 28.3422 5.6575 29.6667 7.29134 29.6667V26.6667C7.29433 26.6667 7.30095 26.6676 7.30802 26.6706C7.31409 26.6731 7.31812 26.6762 7.3208 26.6789C7.32348 26.6816 7.32655 26.6856 7.32912 26.6917C7.33211 26.6987 7.33301 26.7054 7.33301 26.7083H4.33301ZM20.3885 18.5538C20.3797 18.5459 20.3747 18.5346 20.3747 18.5228H23.3747C23.3747 17.6833 23.018 16.8832 22.3934 16.3222L20.3885 18.5538ZM15.8309 10.4264C14.7064 9.41621 13.0012 9.4162 11.8768 10.4264L13.8817 12.6581C13.8658 12.6723 13.8418 12.6723 13.826 12.6581L15.8309 10.4264Z" fill="#D8D9FA"/>
<path d="M21.6924 28.1666H27.708C28.5134 28.1666 29.1663 27.5137 29.1663 26.7083V6.29165C29.1663 5.48623 28.5134 4.83331 27.708 4.83331H11.6663C10.8609 4.83331 10.208 5.48623 10.208 6.29165V13.5833" stroke="#D8D9FA" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div><div class="bottom-cta-inner"><div class="bottom-cta-content"><div class="bottom-cta-title">We’re hiring</div><p>Our global team is growing and we’re hiring all types of roles.</p></div><div class="secondary-button cc-bottom-cta"><div>View open roles</div><div class="sec-button-chevron w-embed"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.25 10.5L8.75 7L5.25 3.5" stroke="#B1B3F6" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div></div></div></a><a href="/about" class="bottom-cta w-inline-block"><div class="bottom-cta-icon w-embed"><svg width="35" height="30" viewBox="0 0 35 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 14.9831C0 15.6401 0.175001 16.297 0.513335 16.8618L6.65003 27.3615C7.28003 28.4333 8.2367 29.3093 9.42671 29.7011C11.7717 30.4733 14.1984 29.4822 15.3534 27.4998L16.8351 24.9642L10.99 14.9831L17.1617 4.41426L18.6434 1.87865C19.0867 1.11797 19.6817 0.495595 20.3818 0H19.7401H10.8617C9.19337 0 7.65337 0.875936 6.82503 2.30509L0.513335 13.1045C0.175001 13.6692 0 14.3262 0 14.9831Z" fill="currentColor"/>
<path d="M34.9999 14.9831C34.9999 14.3261 34.8249 13.6692 34.4866 13.1044L28.2682 2.46641C27.1132 0.495551 24.6865 -0.49564 22.3415 0.265041C21.1515 0.656907 20.1949 1.53284 19.5649 2.60471L18.1648 4.99048L24.0099 14.9831L17.8382 25.5519L16.3565 28.0875C15.9132 28.8367 15.3182 29.4706 14.6182 29.9662H15.2598H24.1382C25.8065 29.9662 27.3466 29.0902 28.1749 27.6611L34.4866 16.8617C34.8249 16.297 34.9999 15.64 34.9999 14.9831Z" fill="currentColor"/>
</svg></div><div class="bottom-cta-inner"><div class="bottom-cta-content"><div class="bottom-cta-title">About us</div><p>WorkOS builds developer tools for quickly adding enterprise features to applications.</p></div><div class="secondary-button cc-bottom-cta"><div>Learn more</div><div class="sec-button-chevron w-embed"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.25 10.5L8.75 7L5.25 3.5" stroke="#B1B3F6" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
</svg></div></div></div></a></div></div></div></section></main><footer class="footer"><div class="page-padding"><div class="container"><div class="footer-menu"><a aria-label="Homepage" href="#" class="footer-logo-link w-inline-block"><div class="icon-embed w-embed"><svg width="59" height="51" viewBox="0 0 59 51" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 25.4002C0 26.5139 0.293079 27.6276 0.859699 28.585L11.137 46.3847C12.1921 48.2018 13.7943 49.6867 15.7872 50.351C19.7145 51.6601 23.7785 49.9798 25.7128 46.6192L28.1942 42.3207L18.4054 25.4002L28.7413 7.48329L31.2227 3.1848C31.9652 1.89525 32.9617 0.840161 34.134 0H33.0594H18.1905C15.3964 0 12.8173 1.48494 11.4301 3.90772L0.859699 22.2154C0.293079 23.1728 0 24.2865 0 25.4002Z" fill="currentColor"/>
<path d="M58.6151 25.4001C58.6151 24.2864 58.322 23.1727 57.7554 22.2153L47.3413 4.18118C45.407 0.840078 41.343 -0.840243 37.4157 0.449306C35.4228 1.11362 33.8206 2.59855 32.7655 4.41565L30.4209 8.46014L40.2097 25.4001L29.8738 43.317L27.3924 47.6155C26.6499 48.8856 25.6535 49.9602 24.4811 50.8003H25.5558H40.4247C43.2187 50.8003 45.7978 49.3154 47.185 46.8926L57.7554 28.5849C58.322 27.6275 58.6151 26.5138 58.6151 25.4001Z" fill="currentColor"/>
</svg></div></a><div class="footer-menu-cell"><div>Products</div><a href="/user-management" class="footer-link">User Management</a><a href="/single-sign-on" class="footer-link">Enterprise SSO</a><a href="/directory-sync" class="footer-link">Directory Sync</a><a href="/admin-portal" class="footer-link">Admin Portal</a><a href="/audit-logs" class="footer-link">Audit Logs</a><a href="https://authkit.com" target="_blank" class="footer-link">AuthKit</a><a href="/multi-factor-authentication" class="footer-link">Multi-Factor Authentication</a><a href="/rbac" class="footer-link">Role-Based Access Control</a><a href="/radar" class="footer-link">Radar</a><a href="/vault" class="footer-link">Vault</a><a href="https://workos.com/pipes" class="footer-link">Pipes</a><a href="https://workos.com/airlock" class="footer-link">Airlock</a><a href="https://workos.com/auth-md" class="footer-link">auth.md</a><a href="https://workos.com/atlas" class="footer-link">Atlas</a></div><div class="footer-menu-cell"><div>Developers</div><a href="https://workos.com/docs" class="footer-link">Documentation</a><a href="/changelog" class="footer-link">Changelog</a><a href="https://status.workos.com/" class="footer-link">API Status</a></div><div class="footer-menu-cell"><div>Resources</div><a href="/blog" class="footer-link">Blog</a><a href="/guides" class="footer-link">Guides</a><a href="/podcast" class="footer-link">Podcast</a><a href="/pricing" class="footer-link">Pricing</a><a href="/startups" class="footer-link">Startups</a><a href="/support-plans" class="footer-link">Support Plans</a><a href="/legal/sla" class="footer-link">Enterprise SLA</a></div><div class="footer-menu-cell"><div>Company</div><a href="/about" class="footer-link">About</a><a href="/customers" class="footer-link">Customers</a><a href="/careers" class="footer-link">Careers</a><a href="/security" class="footer-link">Security</a><a href="/legal/policies" class="footer-link">Legal</a><a href="https://trust.workos.com/" target="_blank" class="footer-link">Trust Center</a><a href="/contact" class="footer-link">Contact</a></div></div><div class="footer-bottom"><div class="footer-copyright">© WorkOS, Inc.</div><div class="footer-social"><a aria-label="GitHub" href="https://github.com/workos" target="_blank" class="footer-social-link w-inline-block"><div class="icon-embed w-embed"><svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#a)" fill="currentColor">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 .417c-2.374 0-4.67.842-6.478 2.372a9.931 9.931 0 0 0-3.39 5.98 9.898 9.898 0 0 0 1.315 6.738 9.992 9.992 0 0 0 5.39 4.287c.497.092.684-.216.684-.477 0-.262-.01-1.021-.013-1.851-2.782.6-3.37-1.174-3.37-1.174-.453-1.153-1.11-1.456-1.11-1.456-.907-.615.069-.604.069-.604 1.005.071 1.533 1.026 1.533 1.026.891 1.52 2.34 1.08 2.91.823.089-.644.349-1.082.635-1.33-2.222-.25-4.557-1.103-4.557-4.913a3.839 3.839 0 0 1 1.03-2.67c-.102-.25-.445-1.26.098-2.634 0 0 .84-.266 2.75 1.02a9.544 9.544 0 0 1 5.008 0c1.91-1.286 2.747-1.02 2.747-1.02.545 1.37.202 2.381.1 2.635a3.83 3.83 0 0 1 1.031 2.672c0 3.818-2.34 4.66-4.565 4.905.357.31.677.914.677 1.842 0 1.33-.012 2.4-.012 2.729 0 .265.18.574.688.477a9.991 9.991 0 0 0 5.39-4.288 9.897 9.897 0 0 0 1.314-6.74 9.93 9.93 0 0 0-3.391-5.979 10.036 10.036 0 0 0-6.48-2.37H10Z"/>
<path d="M3.787 14.694c-.022.049-.101.064-.166.03-.064-.035-.112-.1-.089-.15.023-.052.101-.065.166-.03.064.034.114.1.089.15Zm.406.449a.166.166 0 0 1-.206-.046c-.064-.07-.077-.165-.028-.208.05-.043.14-.023.204.046.065.07.08.165.03.208Zm.394.571c-.061.043-.166 0-.224-.085a.166.166 0 0 1-.037-.183.166.166 0 0 1 .037-.054c.062-.042.166 0 .224.084.058.083.06.195 0 .238Zm.535.553c-.055.061-.166.045-.257-.037-.091-.083-.113-.195-.058-.254.055-.06.166-.043.26.038.094.08.113.194.055.253Zm.75.323c-.025.078-.138.112-.25.08-.113-.034-.187-.126-.166-.205.022-.079.136-.115.25-.079.114.036.187.124.166.204Zm.818.056c0 .08-.093.15-.212.151-.12.002-.217-.064-.217-.145 0-.08.093-.15.212-.151.12-.002.217.063.217.145Zm.762-.126c.014.08-.068.164-.188.184-.119.02-.223-.028-.238-.107-.015-.08.071-.165.187-.186.116-.022.224.028.239.108Z"/>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h20v20H0z"/>
</clipPath>
</defs>
</svg></div></a><a aria-label="Twitter" href="https://twitter.com/workos" target="_blank" class="footer-social-link w-inline-block"><div class="icon-embed w-embed"><svg width="21" height="20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#a)">
<path d="M6.792 18.125c7.545 0 11.673-6.253 11.673-11.673 0-.176-.004-.356-.012-.532A8.332 8.332 0 0 0 20.5 3.796a8.09 8.09 0 0 1-2.355.645 4.125 4.125 0 0 0 1.804-2.27 8.247 8.247 0 0 1-2.605.996A4.108 4.108 0 0 0 10.35 6.91a11.654 11.654 0 0 1-8.456-4.284A4.108 4.108 0 0 0 3.164 8.1a4.108 4.108 0 0 1-1.86-.512v.051a4.102 4.102 0 0 0 3.293 4.024 4.078 4.078 0 0 1-1.851.07 4.111 4.111 0 0 0 3.831 2.851A8.23 8.23 0 0 1 .5 16.282a11.64 11.64 0 0 0 6.292 1.843Z" fill="currentColor"/>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" transform="translate(.5)" d="M0 0h20v20H0z"/>
</clipPath>
</defs>
</svg></div></a><a aria-label="LinkedIn" href="https://www.linkedin.com/company/workos-inc" target="_blank" class="footer-social-link w-inline-block"><div class="icon-embed w-embed"><svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.5195 0H1.47656C0.660156 0 0 0.644531 0 1.44141V18.5547C0 19.3516 0.660156 20 1.47656 20H18.5195C19.3359 20 20 19.3516 20 18.5586V1.44141C20 0.644531 19.3359 0 18.5195 0ZM5.93359 17.043H2.96484V7.49609H5.93359V17.043ZM4.44922 6.19531C3.49609 6.19531 2.72656 5.42578 2.72656 4.47656C2.72656 3.52734 3.49609 2.75781 4.44922 2.75781C5.39844 2.75781 6.16797 3.52734 6.16797 4.47656C6.16797 5.42188 5.39844 6.19531 4.44922 6.19531ZM17.043 17.043H14.0781V12.4023C14.0781 11.2969 14.0586 9.87109 12.5352 9.87109C10.9922 9.87109 10.7578 11.0781 10.7578 12.3242V17.043H7.79688V7.49609H10.6406V8.80078H10.6797C11.0742 8.05078 12.043 7.25781 13.4844 7.25781C16.4883 7.25781 17.043 9.23438 17.043 11.8047V17.043Z" fill="currentColor"/>
</svg></div></a><a aria-label="LinkedIn" href="https://www.youtube.com/@WorkOS/videos" target="_blank" class="footer-social-link w-inline-block"><div class="icon-embed w-embed"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.499 6.203c-.277-1.045-1.093-1.86-2.139-2.139C19.62 3.5 12 3.5 12 3.5s-7.62 0-9.36.564C1.593 4.344.777 5.16.5 6.203.001 8.097 0 12 0 12s0 3.903.5 5.797c.277 1.045 1.093 1.86 2.139 2.139C4.38 20.5 12 20.5 12 20.5s7.62 0 9.36-.564c1.045-.279 1.86-1.094 2.139-2.139.5-1.894.5-5.797.5-5.797s0-3.903-.5-5.797zM9.75 15.002v-6l6 3-6 3z" fill="currentColor"/>
</svg></div></a></div></div></div></div></footer></div><script src="https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.5.1.min.dc5e7f18c8.js?site=621f54116cab10f6e9215d8b" type="text/javascript" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script><script src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/js/workos-new.schunk.36b8fb49256177c8.js" type="text/javascript" integrity="sha384-4abIlA5/v7XaW1HMXKBgnUuhnjBYJ/Z9C1OSg4OhmVw9O3QeHJ/qJqFBERCDPv7G" crossorigin="anonymous"></script><script src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/js/workos-new.schunk.71c836a850663cac.js" type="text/javascript" integrity="sha384-oyVwhlc5rRCCSb+TImiz8PjCNu8bWzoSiFSc7pr6OgVxXRgugWKmDQlc85expOQS" crossorigin="anonymous"></script><script src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/js/workos-new.81ece094.be57a8ded090c867.js" type="text/javascript" integrity="sha384-Y4tW2OnUEH2bsibix1xR8VHweAaZSVNUcBNhDYLbI59TWkLdeBJisxnoYiR2VpCM" crossorigin="anonymous"></script><style>
#consent-banner {
display: none;
position: fixed;
right: 24px;
bottom: 24px;
width: 340px;
max-width: calc(100% - 32px);
padding: 16px;
font-size: 13.8px !important;
line-height: 1.4286 !important;
z-index: 9999;
border-radius: 10px;
border: 1px solid transparent !important;
font-family: inherit;
}
#consent-banner p {
margin: 0 0 12px 0 !important;
font-size: 13.8px !important;
line-height: 1.4286 !important;
}
#consent-banner a {
text-decoration: none !important;
}
#consent-banner a:hover {
text-decoration: underline !important;
text-decoration-thickness: 1px !important;
text-underline-offset: 2px !important;
}
#consent-banner-buttons {
display: flex;
gap: 8px;
}
#consent-banner button {
border: none;
height: 32px;
padding: 0 12px;
font-weight: 500;
cursor: pointer;
border-radius: 4px;
font-size: 13.8px !important;
font-family: inherit;
line-height: 1 !important;
}
#consent-accept {
background: rgb(101, 101, 236) !important;
color: #ffffff !important;
}
/* Dark theme */
#consent-banner.theme-dark {
background: #18191b !important;
color: #edeef0 !important;
border-color: rgba(217, 237, 254, 0.145) !important;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
#consent-banner.theme-dark p {
color: #edeef0 !important;
}
#consent-banner.theme-dark a {
color: #b1a9ff !important;
}
#consent-banner.theme-dark a:hover {
text-decoration-color: rgba(177, 169, 255, 0.5) !important;
}
#consent-banner.theme-dark #consent-accept:hover {
background: #6e6ade !important;
background: color(display-p3 0.428 0.416 0.843) !important;
}
#consent-banner.theme-dark #consent-reject {
background: transparent !important;
color: #edeef0 !important;
border: 1px solid rgba(217, 237, 255, 0.251) !important;
}
#consent-banner.theme-dark #consent-reject:hover {
background: rgba(221, 234, 248, 0.13) !important;
}
/* Light theme */
#consent-banner.theme-light {
background: #ffffff !important;
color: #1c2024 !important;
border-color: rgba(0, 9, 50, 0.122) !important;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}
#consent-banner.theme-light p {
color: #1c2024 !important;
}
#consent-banner.theme-light a {
color: rgba(6, 0, 171, 0.673) !important;
}
#consent-banner.theme-light a:hover {
text-decoration-color: rgba(6, 0, 171, 0.4) !important;
}
#consent-banner.theme-light #consent-accept:hover {
background: #5151cd !important;
background: color(display-p3 0.318 0.318 0.774) !important;
}
#consent-banner.theme-light #consent-reject {
background: transparent !important;
color: #1c2024 !important;
border: 1px solid rgba(0, 6, 46, 0.197) !important;
}
#consent-banner.theme-light #consent-reject:hover {
background: rgba(0, 0, 51, 0.09) !important;
}
@media (max-width: 480px) {
#consent-banner {
right: 16px;
left: 16px;
bottom: 16px;
width: auto;
}
}
</style>
<!-- Consent Banner markup -->
<!-- Change "theme-light" to "theme-dark" to flip the banner appearance. -->
<div id="consent-banner" class="theme-light" role="dialog" aria-label="Cookie consent">
<p>
We use cookies for analytics and advertising. See our
<a href="/cookies">cookie policy</a>
for details.
</p>
<div id="consent-banner-buttons">
<button id="consent-accept">Accept</button>
<button id="consent-reject">Reject</button>
</div>
</div>
<script>
(function () {
var STORAGE_KEY = 'workos_consent_v1'; // bump version to reset all stored choices
var EU_COUNTRIES = ['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB', 'IS', 'LI', 'NO', 'CH'];
var ALL_DENIED = { ad_storage: 'denied', ad_user_data: 'denied', ad_personalization: 'denied', analytics_storage: 'denied' };
var ALL_GRANTED = { ad_storage: 'granted', ad_user_data: 'granted', ad_personalization: 'granted', analytics_storage: 'granted' };
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
function showBanner() {
var el = document.getElementById('consent-banner');
if (el) el.style.display = 'block';
}
function hideBanner() {
var el = document.getElementById('consent-banner');
if (el) el.style.display = 'none';
}
function persist(consent) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(consent));
} catch (e) {}
}
// Apply consent + persist + emit Custom Event for non-Google tags (LinkedIn, Unifygtm).
// Only emits the Custom Event when at least one consent type is granted —
// GTM uses `cookie_consent_update` as the trigger for non-Google tags.
function applyConsent(consent) {
gtag('consent', 'update', consent);
persist(consent);
var anyGranted = Object.keys(consent).some(function (k) {
return consent[k] === 'granted';
});
if (anyGranted) {
dataLayer.push({ event: 'cookie_consent_update', consent: consent });
}
}
// Returning visitor: head already restored consent. Push the Custom Event
// so non-Google tags fire (if their stored choice included any granted state).
function earlyConsent() {
var stored = null;
try {
stored = localStorage.getItem(STORAGE_KEY);
} catch (e) {}
if (stored) {
try {
var parsed = JSON.parse(stored);
var anyGranted = Object.keys(parsed).some(function (k) {
return parsed[k] === 'granted';
});
if (anyGranted) dataLayer.push({ event: 'cookie_consent_update', consent: parsed });
} catch (e) {}
return true;
}
return false;
}
// First-time visitor: geo-check via Cloudflare /cdn-cgi/trace (workos.com only).
// On any other host (e.g., staging workos-new.webflow.io) assume US.
function init() {
var handleCountry = function (country) {
if (EU_COUNTRIES.indexOf(country) !== -1) {
showBanner();
} else {
applyConsent(ALL_GRANTED);
}
};
if (location.hostname !== 'workos.com') {
handleCountry('US');
} else {
fetch('/cdn-cgi/trace')
.then(function (r) {
return r.text();
})
.then(function (text) {
var match = text.match(/^loc=(.+)$/m);
handleCountry(match ? match[1] : '');
})
.catch(function () {
showBanner();
});
}
}
function wireButtons() {
var accept = document.getElementById('consent-accept');
var reject = document.getElementById('consent-reject');
if (accept) {
accept.addEventListener('click', function () {
applyConsent(ALL_GRANTED);
hideBanner();
});
}
if (reject) {
reject.addEventListener('click', function () {
applyConsent(ALL_DENIED);
hideBanner();
});
}
}
// Run early consent synchronously (before DOMContentLoaded) — minimizes timing race
var handled = earlyConsent();
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function () {
wireButtons();
if (!handled) init();
});
} else {
wireButtons();
if (!handled) init();
}
})();
</script>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NTN3Q3DV" height="0" width="0" style="display: none; visibility: hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<script src="https://cdn.jsdelivr.net/npm/js-cookie@rc/dist/js.cookie.min.js"></script>
<!-- BEGIN Structured Data -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Corporation",
"name": "WorkOS",
"@id": "https://workos.com/#organization",
"legalName": "WorkOS, Inc.",
"url": "https://workos.com/",
"description": "Enterprise APIs for SSO, SCIM Directory Sync, MFA, AuthKit user management, Audit Logs, and more. Free up to 1M monthly active users.",
"logo": "https://images.workoscdn.com/brand/v2/favicon@256x256.png",
"address": {
"@type": "PostalAddress",
"streetAddress": "660 Market St",
"addressLocality": "San Francisco",
"addressRegion": "CA",
"postalCode": "94104",
"addressCountry": "US"
},
"contactPoint": [
{
"@type": "ContactPoint",
"url": "https://workos.com/",
"email": "hello@workos.com",
"contactType": "customer support"
}
],
"foundingDate": "2019-05-20",
"founders": [
{
"@type": "Person",
"name": "Michael Grinich"
}
],
"sameAs": [
"https://twitter.com/workos",
"https://www.linkedin.com/company/workos-inc/",
"https://github.com/workos",
"https://wellfound.com/company/workos"
]
}
</script>
<!-- END Structured Data -->
<!-- BEGIN Cookies for UTM Attribution and Referrer -->
<script type="text/javascript">
(() => {
// UTM Attribution
const utmCookieName = 'workos_utm_attribution';
const utmCookie = Cookies.get(utmCookieName);
if (!utmCookie && location.search && location.search.includes('utm')) {
Cookies.set(utmCookieName, location.search, { domain: 'workos.com', expires: 7 });
}
// Referrer
const referrerCookieName = 'workos_referrer';
const referrerCookie = Cookies.get(referrerCookieName);
if (!referrerCookie && document.referrer && !document.referrer.includes('workos.com')) {
Cookies.set(referrerCookieName, document.referrer, { domain: 'workos.com', expires: 7 });
}
})();
</script>
<!-- END Cookies for UTM Attribution and Referrer -->
<!-- Start of HubSpot Embed Code -->
<script type="text/javascript" id="hs-script-loader" async defer src="//js-na1.hs-scripts.com/20433186.js"></script>
<!-- End of HubSpot Embed Code -->
<script>
const navLogo = document.querySelector('.nav-logo-link');
const contextMenu = document.querySelector('.nav-context-menu');
const copyLogoButton = document.getElementById('copy-logo');
const copyBrandmarkButton = document.getElementById('copy-brandmark');
if (navLogo && contextMenu && copyLogoButton && copyBrandmarkButton) {
navLogo.addEventListener('contextmenu', function (e) {
e.preventDefault();
contextMenu.classList.add('show-menu');
document.addEventListener('click', closeContextMenu);
});
function closeContextMenu(e) {
if (!contextMenu.contains(e.target)) {
contextMenu.classList.remove('show-menu');
document.removeEventListener('click', closeContextMenu);
}
}
copyLogoButton.addEventListener('click', function () {
copyToClipboard(logoSVG, copyLogoButton);
});
copyBrandmarkButton.addEventListener('click', function () {
copyToClipboard(wordmarkSVG, copyBrandmarkButton);
});
}
function copyToClipboard(text, button) {
navigator.clipboard
.writeText(text)
.then(() => {
const text = button.querySelector('.context-menu-item-text');
// Change button text to "Copied!"
const originalText = text.textContent;
text.textContent = 'Copied!';
// Revert back to the original text after 2 seconds
setTimeout(() => {
text.textContent = originalText;
contextMenu.classList.remove('show-menu');
document.removeEventListener('click', closeContextMenu);
}, 400);
})
.catch((err) => {
console.error('Failed to copy: ', err);
});
}
const logoSVG = `<svg xmlns="http://www.w3.org/2000/svg" width="558" height="164" fill="none" viewBox="0 0 558 164"><path fill="#2B333B" d="M485.175 92.905h-13.694c0 13.687 10.992 22.787 26.665 22.787 15.403 0 25.854-8.107 25.854-20.098 0-14.366-10.07-16.47-22.725-19.114-.676-.141-1.359-.284-2.048-.43-9.188-1.892-12.161-3.871-12.161-9.005 0-4.864 4.236-8.195 11.08-8.195 6.755 0 11.349 3.695 11.349 9.64h13.694c0-12.248-9.553-20.354-25.043-20.354-14.863 0-24.591 8.647-24.591 20.084 0 13.694 11.079 17.207 21.53 19.28 11.444 2.25 15.045 3.696 15.045 9.188 0 4.865-4.688 8.29-11.532 8.29-8.106 0-13.423-4.324-13.423-12.073Z"/><path fill="#2B333B" fill-rule="evenodd" d="M403.837 82.155c0-20.267 12.613-33.779 31.529-33.779s31.528 13.512 31.528 33.779c0 20.267-12.612 33.778-31.528 33.778-18.916 0-31.529-13.511-31.529-33.778Zm49.992 0c0-13.782-7.384-23.064-18.47-23.064-11.086 0-18.463 9.282-18.463 23.064 0 13.781 7.384 23.064 18.463 23.064s18.47-9.283 18.47-23.064Z" clip-rule="evenodd"/><path fill="#2B333B" d="M190.358 49.035h-13.511l17.477 65.759h15.49l9.729-39.817c1.979-8.648 2.161-12.519 2.161-12.519h.183s.182 3.871 2.344 12.519l10.356 39.817h15.045l17.112-65.76h-13.511l-9.37 40.089c-1.797 7.836-1.979 12.072-1.979 12.072h-.271s-.452-4.236-2.344-12.072l-9.816-40.088h-15.315l-9.275 40.088c-1.804 7.66-2.433 12.072-2.433 12.072h-.182s-.358-4.506-2.162-12.072l-9.728-40.088Z"/><path fill="#2B333B" fill-rule="evenodd" d="M288.903 66.133c-14.686 0-24.415 9.728-24.415 24.773 0 15.132 9.735 24.948 24.415 24.955 14.593 0 24.321-9.823 24.321-24.955 0-15.045-9.728-24.773-24.321-24.773Zm0 9.545c7.026 0 11.708 5.5 11.708 15.228 0 9.275-4.141 15.403-11.708 15.403-7.12 0-11.802-5.493-11.802-15.403 0-9.1 4.236-15.228 11.802-15.228Z" clip-rule="evenodd"/><path fill="#2B333B" d="M319.257 66.87h11.978v8.83h.27c2.074-4.594 7.026-9.188 15.491-9.188 1.439 0 2.344.182 2.973.358v11.978h-.358s-1.081-.358-4.054-.358c-9.275 0-14.322 5.492-14.322 15.76v20.538h-11.978V66.87Zm48.276-17.835h-11.978v65.753h11.978V99.385l4.506-4.412 17.477 19.821h14.146L379.43 87.589l20.888-20.72h-14.95l-17.835 17.923h-.182s.182-2.25.182-14.68V49.035Z"/><path fill="#6363F1" d="M35 81.61c0 2.044.538 4.088 1.578 5.845l18.86 32.664c1.935 3.334 4.875 6.059 8.532 7.278 7.207 2.402 14.665-.681 18.215-6.848l4.553-7.888-17.963-31.05 23.52-40.767c1.363-2.366 3.192-4.302 5.343-5.844H68.38c-5.127 0-9.86 2.725-12.405 7.17L36.578 75.768C35.538 77.523 35 79.567 35 81.61Z"/><path fill="#6363F1" d="M142.563 81.61c0-2.043-.537-4.087-1.577-5.844l-19.111-33.093c-3.549-6.131-11.007-9.215-18.214-6.849-3.657 1.22-6.597 3.945-8.533 7.279l-4.303 7.422 17.963 31.086-23.52 40.766a18.946 18.946 0 0 1-5.342 5.844h29.257c5.127 0 9.86-2.724 12.406-7.17l19.397-33.596c1.04-1.757 1.577-3.8 1.577-5.844Z"/></svg>`;
const wordmarkSVG = `<svg width="124" height="124" viewBox="0 0 124 124" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 60.8894C2 63.1207 2.58718 65.352 3.72241 67.2701L24.313 102.932C26.4269 106.572 29.6368 109.547 33.6297 110.878C41.498 113.501 49.6403 110.135 53.5157 103.402L58.4872 94.7895L38.8752 60.8894L64.5548 16.3807C66.0423 13.7971 68.0387 11.6833 70.3875 10H38.4446C32.8468 10 27.6796 12.9751 24.9002 17.8291L3.72241 54.5086C2.58718 56.4268 2 58.6581 2 60.8894Z" fill="#6363F1"/><path d="M119.437 60.8892C119.437 58.6579 118.85 56.4266 117.715 54.5084L96.8499 18.377C92.9745 11.6831 84.8322 8.31655 76.9639 10.9002C72.971 12.2311 69.7611 15.2062 67.6472 18.8467L62.9497 26.9499L82.5617 60.8892L56.8822 105.398C55.3946 107.942 53.3982 110.095 51.0495 111.779H82.9923C88.5902 111.779 93.7574 108.803 96.5367 103.949L117.715 67.2699C118.85 65.3518 119.437 63.1205 119.437 60.8892Z" fill="#6363F1"/></svg>`;
</script>
<script>
function getCookie(name) {
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
return match ? match[2] : null;
}
const hasDashboardCookie = getCookie('workos_homepage_dashboard_user');
const signInButton = document.getElementById('sign-in');
const dashboardButton = document.getElementById('dashboard');
if (hasDashboardCookie) {
//if(window.location.hostname == "workos-test.com"){
//dashboardButton.href = "dashboard.workos-test.com";
//}
if (signInButton) signInButton.style.display = 'none';
if (dashboardButton) dashboardButton.style.display = 'flex';
} else {
if (signInButton) signInButton.style.display = 'block';
if (dashboardButton) dashboardButton.style.display = 'none';
}
</script>
<script defer src="https://cdn.jsdelivr.net/npm/quicklink@3.0.1/dist/quicklink.umd.js"></script>
<script>
window.addEventListener('load', () => {
quicklink.listen();
});
</script><script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/components/prism-python.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/plugins/toolbar/prism-toolbar.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/plugins/unescaped-markup/prism-unescaped-markup.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/components/prism-typescript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/2.0.1/showdown.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/plugins/normalize-whitespace/prism-normalize-whitespace.min.js"></script>
<link href="
https://cdn.jsdelivr.net/npm/tippy.js@6.0.0/dist/tippy.min.css
" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tippy.js@6.0.0/dist/tippy.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/medium-zoom@1.1.0/dist/medium-zoom.min.js"></script>
<script>
/* Convert backticks to inline code snippets */
if (!document.querySelector('.post-rt p code')) {
const converter = new showdown.Converter();
const paragraphs = document.querySelectorAll('.post-rt p');
const blockquotes = document.querySelectorAll('post-rt blockquote');
const listItems = document.querySelectorAll('.post-rt ul li');
convertMarkdownToHtml(paragraphs);
convertMarkdownToHtml(blockquotes);
convertMarkdownToHtml(listItems);
function convertMarkdownToHtml(collection) {
collection.forEach(element => {
element.innerHTML = converter.makeHtml(element.innerHTML)
})
}
}
/* Add canonical URL */
if ('') {
const link = document.createElement('link');
link.href = '';
link.rel = 'canonical';
document.getElementsByTagName('head')[0].appendChild(link);
}
/* Add Open Graph image */
if ('https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667c966c7ae39b3d72131363_developer-week-infra-square.webp') {
const api = 'https://i.microlink.io/'
const cardUrl = `https://cards.microlink.io/?preset=workos&authorName=Matheus Lichtnow&authorUrl=https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667d68d344a485251d1ea59c_TBDJCFH1R-U03PM55RB89-5706012f7eb2-512.png&category=Engineering&title=From four to five 9s of uptime by migrating to Kubernetes &imageUrl=https://cdn.prod.website-files.com/621f84dc15b5ed16dc85a18a/667c966c7ae39b3d72131363_developer-week-infra-square.webp`;
const meta = document.createElement('meta');
meta.setAttribute('property', 'custom:og');
meta.content = `${api}${encodeURIComponent(cardUrl)}`;
document.getElementsByTagName('head')[0].appendChild(meta);
}
</script>
<script>
tippy('[data-tippy-content]', {
theme: 'custom',
placement: 'bottom',
appendTo: 'parent',
});
</script>
<script>
window.addEventListener('load', function() {
mediumZoom('.w-richtext-figure-type-image img', {
margin: 24,
background: 'rgba(0, 0, 0, 0.85)',
scrollOffset: 0,
});
});
</script>
<script>
(()=>{const t=()=>window.innerWidth>1200;if(!t())return;const e=document.querySelectorAll(".post-rt h2"),n=document.querySelector(".post-toc-wrap"),o=document.querySelector(".post-toc-inner");if(e.length<2||!n)return void(o&&(o.style.display="none"));const s={};e.forEach((t=>{const e=t.textContent.trim();s[e]=(s[e]||0)+1}));const r={},i=t=>{const e=t.toLowerCase().trim().replace(/^[\d.]+\s*/,"").replace(/[^a-z0-9]+/g,"-").replace(/(^-|-$)/g,"");return 1===s[t]?e:(r[t]=(r[t]||0)+1,`${e}-${r[t]}`)},c="introduction",a=document.createElement("div");a.classList.add("article-content-section"),a.id=c,e.forEach((t=>{const e=i(t.textContent),n=document.createElement("div");n.classList.add("article-content-section"),n.id=e,t.parentNode.insertBefore(n,t),n.appendChild(t);let o=n.nextSibling;for(;o&&!o.matches("h2");){const t=o;o=o.nextSibling,n.appendChild(t)}}));const l=document.querySelector(".post-rt");if(l&&(l.insertBefore(a,l.firstChild),e.length>0)){const t=e[0].parentNode;let n=l.firstChild;for(;n&&n!==t;){const t=n.nextSibling;n===a||n.matches("h2")||a.appendChild(n),n=t}}const d=document.createElement("ul");d.classList.add("toc-list");const h=`\n <li class="toc-item active">\n <a href="#${c}" class="toc-a">\n <div class="toc-line"></div>\n <div class="toc-text">\n <span class="toc-text-inner">Introduction</span>\n </div>\n </a>\n </li>\n ${Array.from(e).map((t=>{const e=t.textContent.trim(),n=i(e);return t.parentElement.id=n,`\n <li class="toc-item">\n <a href="#${n}" class="toc-a">\n <div class="toc-line"></div>\n <div class="toc-text">\n <span class="toc-text-inner">${e}</span>\n </div>\n </a>\n </li>\n `})).join("")}\n `;d.innerHTML=h,o.appendChild(d);const m=d.querySelector(`a[href="#${c}"]`);m.addEventListener("click",(t=>{t.preventDefault(),window.scrollTo({top:0,behavior:"smooth"}),y(a)}));let u=m;const p=o.querySelectorAll(".toc-a");requestAnimationFrame((()=>{const t=o.offsetHeight;o.style.setProperty("--initial-toc-height",`${t}px`),p.forEach((t=>{const e=t.offsetHeight,n=t.querySelector(".toc-text-inner").offsetWidth;t.style.setProperty("--expanded-link-height",`${e}px`),t.style.setProperty("--expanded-link-width",`${n}`)})),o&&(o.style.opacity="1")}));const f=document.querySelectorAll(".article-content-section");let g,v=!1;const y=t=>{if(!t)return;const e=n.querySelector(`a[href="#${t.id}"]`);e!==u&&requestAnimationFrame((()=>{var t;u&&(null==(t=u.closest(".toc-item"))||t.classList.remove("active")),requestAnimationFrame((()=>{var t;e&&(null==(t=e.closest(".toc-item"))||t.classList.add("active"),u=e)}))}))};n.addEventListener("click",(t=>{t.stopPropagation();const e=t.target.closest("a");if(!e||!e.hash)return;if(e.hash===`#${c}`)return;t.preventDefault();const n=document.querySelector(e.hash);n&&(v=!0,clearTimeout(g),g=setTimeout((()=>{v=!1}),2e3),n.scrollIntoView({behavior:"smooth"}),y(n))}));const x=new IntersectionObserver((t=>{if(v)return;const e=t.sort(((t,e)=>t.target.getBoundingClientRect().top-e.target.getBoundingClientRect().top));for(const n of e){const{isIntersecting:t,target:e,boundingClientRect:o,rootBounds:s}=n;if(s&&!(s.bottom-o.bottom>s.bottom/2)){if(t){y(e);break}{const t=Array.from(f),n=t.indexOf(e);if(o.top>0){const e=t[Math.max(n-1,0)];y(e);break}}}}}),{threshold:[0],rootMargin:"0% 0% -50% 0%"});requestAnimationFrame((()=>{document.documentElement.style.scrollBehavior="smooth"})),f.forEach((t=>{x.observe(t)}));const L=document.querySelector(".article-header h1");if(L){new IntersectionObserver((([t])=>{o.classList.toggle("toc-collapsed",!t.isIntersecting)}),{threshold:0,rootMargin:"0px 0px 0px 0px"}).observe(L)}o.addEventListener("mouseenter",(()=>{o.classList.contains("toc-collapsed")&&(o.classList.add("transitioning"),setTimeout((()=>{o.classList.remove("transitioning")}),250))})),window.addEventListener("resize",(()=>{const e=t();!e&&o?o.style.display="none":e&&o&&(o.style.display="")}))})();const t=document.querySelector(".post-rt");if(t){const e=t.getElementsByTagName("p");Array.from(e).forEach((t=>{const e=t.innerHTML,n=t.textContent;n.startsWith("!!")&&n.endsWith("!!")&&e.startsWith("!!")&&e.endsWith("!!")&&(t.innerHTML=e.slice(2,-2),t.classList.add("article-note"))}))}
</script>
<script>
(function () {
// Build a summarization prompt from this page
const pageTitle = "From four to five 9s of uptime by migrating to Kubernetes ";
const pageUrl = "https://workos.com/blog/from-four-to-five-9s-of-uptime-by-migrating-to-kubernetes";
const prompt =
`Read this article: ${pageUrl}. In a short paragraph, tell me what it's about, what's new or interesting about it, and whether it's worth reading in full.`;
const encodedPrompt = encodeURIComponent(prompt);
// Deep links
const chatgptLink = `https://chatgpt.com/?q=${encodedPrompt}`;
const claudeLink = `https://claude.ai/new?q=${encodedPrompt}`;
const perplexityLink = `https://www.perplexity.ai/?q=${encodedPrompt}`;
// Attach to buttons
const chatgptButton = document.getElementById("summarize-chatgpt");
const claudeButton = document.getElementById("summarize-claude");
const perplexityButton = document.getElementById("summarize-perplexity");
if (chatgptButton) chatgptButton.href = chatgptLink;
if (claudeButton) claudeButton.href = claudeLink;
if (perplexityButton) perplexityButton.href = perplexityLink;
})();
</script></body></html>