# Descope 101

From [Descope Fundamentals](https://learn.descope.io/c/foundations) — Learn the platform by configuring your own project — every module ends in work the app checks for real.

Take this course interactively at https://learn.descope.io/c/foundations/descope-101

---

![Authentication Actions. 3 minutes.](video:descope-101-authentication-actions)

Four actions account for most authentication journeys, and they differ in exactly one way that matters: what each of them does when the user already exists. Choosing the wrong one is the most common cause of a journey that behaves correctly for you and rejects half your users.

Sign up creates a new user and authenticates them. If a user with that login ID already exists it fails, because creating a second account for the same identity is not something you want a flow doing quietly. Reach for it when registration is genuinely a separate journey with its own screens, its own consent copy, or its own required fields.

Sign in authenticates an existing user and does not create one. If the login ID is unknown it fails, which is the correct behavior for a login screen and a liability everywhere else: a returning-users-only journey turns every new visitor into a support ticket. It is also the action with a user-enumeration consideration attached, since a flow that fails differently for unknown addresses tells an attacker which addresses are registered.

Sign up or in is the one most applications actually want. It creates the user if they are new and authenticates them if they are not, from a single screen, which removes the "do I have an account?" question that no user has ever enjoyed answering. It also removes the enumeration problem, because the journey looks identical either way.

> [!NOTE]
> Sign up or in hides whether the user was new, and sometimes you need to know — to show onboarding, seed a default tenant, or fire an analytics event. You do not need a different action for that: branch inside the flow on whether the user has a distinguishing attribute yet, and set it on the way past.

Update user is the odd one out, because it does not establish identity at all: it changes an identity that is already authenticated. Adding a password to an account that has only ever used a magic link, attaching a phone number, adding a second login ID — all Update user. It therefore requires an existing session, and a journey built around it belongs behind a login rather than in front of one.

## Choosing between them

- The user must be new — Sign up. Fails if they already exist.
- The user must already exist — Sign in. Fails if they do not, and reveals which addresses are registered.
- Either is fine, which is usually the answer — Sign up or in.
- The user is already signed in and you are changing their identity — Update user. Requires a session.

![Three authentication actions on a flow canvas, each wired from START to the screen that follows it. The purple blocks are the actions — Sign In / OTP / Email, Sign Up or In / Magic Link / Email, Sign Up or In / OTP / Instant Message — and the rows inside each one are its outputs: `Email Sent` leads to the screen that collects the code, `Successful authentication` skips ahead. Which outputs an action offers is what you wire the rest of the journey to.](descope-101-authentication-actions)

## Summary

- What each of the four actions does when the user already exists, which is the only difference that matters
- Why sign-in-only journeys generate support tickets and leak which accounts exist
- That sign up or in is the sensible default, and how to still tell a new user from a returning one
- That Update user modifies an authenticated identity rather than establishing one, so it needs a session

---

![How Users Prove Who They Are. 3 minutes.](video:descope-101-authentication-methods-overview)

## The families

- Passwords — something the user knows. Familiar, universally understood, and the weakest of the options: reused, phished, and leaked in other people's breaches.
- One-time codes (OTP) — a short code sent to an inbox or a phone. Proves the user controls that channel, with nothing to remember.
- Links (Magic, Enchanted, Embedded) — the same idea as a code, delivered as something to click rather than something to type.
- Passkeys (WebAuthn/FIDO2) — a key pair where the private half never leaves the device, unlocked by a fingerprint, face, or PIN. The strongest of the passwordless options and the only one that is phishing-resistant by construction.
- Social login (OAuth) — reuse an account the user already has with Google, Apple, GitHub, and others, so there is no new credential at all.
- Authenticator apps (TOTP) — a rotating code generated on the device from a shared secret, which works with no network and no messaging channel.

None of these is a whole strategy on its own. Real projects combine them: a primary method for the common case, a fallback for devices or people the primary cannot serve, and a second factor where the risk justifies it.

> [!NOTE]
> "Passwordless" is not one method. It is the decision to make the primary path something other than a remembered secret, and there are several ways to honor it. Passkeys with an OTP fallback is a passwordless strategy; so is magic link with social login beside it.

Two things stay the same no matter which family you choose. The user record is the same user record, identified by the same login ID. And the end of a successful journey is the same signed session token, which means the rest of your application does not need to know or care how the person got there.

That session token is a JWT, and the term is used from here to the end of the series, so it is worth a minute now.

A JWT — a JSON Web Token, usually said "jot" — is a small piece of JSON that Descope signs. It carries claims: who the user is, which project issued it, when it expires, and how they authenticated. It is not encrypted, so anyone holding one can read it; what the signature buys you is that nobody can change it without the change being detectable.

That property is the whole point. Your backend does not have to call Descope to ask whether a token is real. It checks the signature against the project's public key, and a valid signature means the claims inside are exactly the ones Descope issued.

> [!NOTE]
> Readable, not secret. A JWT is base64-encoded rather than encrypted, so treat one as public once issued: never put anything in a custom claim that a user should not see. Keeping a token out of the wrong hands is a separate job from what the signature does.

Sessions and Tokens covers the rest — the session and refresh pair, expiry, and rotation. What matters here is only that every method in this lesson ends at the same signed object.

That is why this is worth reading before the deep material rather than after: the method is a decision you can revisit, and changing it later does not change what your backend does with the result.

![Authentication Methods, with every method Descope offers down the left and One-time Password open. Each method has its own settings page like this one: expiry, retry count, the window retries are counted in, and which connector and template deliver the message.](descope-101-authentication-methods-overview)

## Summary

- The three factor types, and that most security and friction differences follow from them
- The six method families and what each one asks of the user
- That passwordless is a strategy rather than a single method
- That every method ends in the same session token, so the choice is revisitable
- What a JWT is, that its claims are signed rather than hidden, and why that lets your backend verify without calling Descope

---

![Ways to Connect Your App. 3 minutes.](video:descope-101-integration-options-overview)

## The four options

- Embedded — a Descope component renders the flow inside your own page. No redirect, no change of origin, and the surrounding design stays entirely yours.
- Hosted — Descope serves the flow at its own URL. You redirect there and the user comes back authenticated, with no frontend authentication code at all.
- Direct API and SDK calls — you build every screen yourself and call individual authentication methods. Total control over the interface, and you own every state that goes with it.
- Federation — Descope acts as an identity provider over OIDC or SAML for something you did not build, or as the authorization server guarding your own APIs.

Three questions settle most of it. Do you have a frontend and want a seamless, same-origin experience? Embed. Are you integrating with a platform or partner tool you do not control? Hosted, or federation. Is authentication itself the product surface you need to design pixel by pixel? Direct calls, and accept the work that comes with it.

> [!NOTE]
> These are not exclusive, and most real projects use more than one. Embedded login in the web app, hosted login for a partner integration that speaks OIDC, and native flows on mobile — all from the same project and the same flow configuration.

Whichever you choose, the split of responsibility does not move. A client SDK holds tokens, renders flows, and exposes session state; it never decides whether a request is allowed. That decision belongs to your backend, validating the token's signature on every protected request. A user fully controls their own browser, so anything decided there is a suggestion rather than a security boundary.

The reason this belongs in the introduction is that it determines what the later modules mean to you. If you are going hosted, the Flows module is about configuring a journey you will never render yourself. If you are going embedded, it is about a component you are about to install. Same material, different reading.

![The Integrate step of the Console's getting-started wizard, which hands you both halves of an integration at once: a frontend snippet that mounts the flow by ID — switchable between React, Vue, AngularJS, Next.js and a plain Web Component — and a backend snippet that validates the session the flow issues, in Go, Node, Python, Java, .NET, PHP or Ruby. The live preview on the right runs the flow you actually built.](descope-101-integration-options-overview)

## Summary

- The four ways to connect, and the three questions that choose between them
- That they combine, and most projects use several at once
- That the client never authorizes and the backend always does, regardless of which you pick
- Why this choice changes how you should read the modules that follow

---

![What Descope is, and how its pieces fit together. 96 seconds.](video:descope-101-platform-overview)

Every app with user accounts has to answer two questions about each person who shows up: who are you, and what are you allowed to do? Building that yourself means writing and maintaining login screens, password resets, MFA prompts, session handling, and secure credential storage — all of it security-sensitive, all of it easy to get wrong, and none of it the thing your product is actually for.

Descope is a customer identity and access management (CIAM) platform: the authentication and authorization layer for applications whose users are customers. Its defining feature is that you build the login experience visually rather than writing it. You assemble a journey on a canvas as a Flow — screens, authentication steps, branching, calls out to other services — and your application points at that flow by ID. Token issuance, credential storage, session handling and MFA all happen behind it.

That split is worth holding on to, because almost everything later in this course is an instance of it. The journey is configuration, held in the Console and changeable without a deploy. Your application holds a flow ID and validates the session that comes back. Swapping a password for a passkey, adding a step-up challenge before a sensitive action, routing one customer's users to their own identity provider — all of it happens on the canvas, and none of it is a release.

## The building blocks

- **Flows** — the visual canvas where a journey is assembled from screens, actions, conditions and connectors. This is the centerpiece, and it has a module of its own.
- **SDKs** — client, backend and mobile libraries. The client renders a flow and keeps the session; the backend validates it on every request using Descope's public keys, without calling Descope per request.
- **APIs** — the Management API and its SDKs, for everything you would otherwise click: creating users, tenants, roles and access keys, and automating any of it from your own systems.
- **Widgets** — pre-built interface components you embed in your app, so a user can manage their own profile and a customer's admin can manage their own team without touching the Console.
- **Tenants** — the unit of customer organization. One project, many customers, each with their own users, roles, domains and settings.
- **Connectors** — configured integrations with outside services, callable mid-journey: your own API, a fraud check, a CRM, a messaging provider.

These compose rather than operate side by side. A Flow calls a connector and ends by issuing a session; an SDK consumes that session; a widget renders against the same users the Management API creates; roles mean one thing at project level and another inside a tenant. Noticing the seams between them now makes every later module easier to place.

## What CIAM means for the platform

- The people signing in are your customers, not your staff — consumers in a B2C product, or employees of the businesses you sell to in a B2B one.
- Sign-up is part of the product, so the journey has to convert, not just authenticate.
- Volume is unpredictable and unbounded, which is why sessions are validated with a public key rather than a call home.
- People expect to help themselves — resetting their own password, adding their own second factor, managing their own team.
- Self-service extends to your customers' administrators, which is what tenants, widgets and the admin portal exist for.

The shorthand you will see throughout this course is B2C and B2B: business-to-consumer, where each user is an individual with their own account, and business-to-business, where users belong to an organization that is itself your customer. Descope handles both from one project, and the difference between them is mostly whether tenants are in play. Fundamentals covers the B2C shape; the Enterprise Identity course covers what changes when a customer is a company.

## Key terms

- **CIAM (Customer Identity and Access Management)** — identity and access management for the external users of an application: its customers, consumers and business partners.
- **B2C / B2B** — business-to-consumer, where a user is an individual; and business-to-business, where a user belongs to an organization that is your customer.
- **Flow** — the visual, drag-and-drop canvas where an authentication journey is assembled instead of hand-coded.
- **Project** — the container holding everything in this list: your users, flows, settings and keys.

## Summary

- That Descope is a CIAM platform, and that its defining feature is building the login experience visually rather than writing it
- The split that runs through the whole platform: the journey is configuration in a Flow, your app holds a flow ID and validates the session
- The six building blocks, what each one is for, and that they compose rather than stand alone
- What having customers as your users changes — conversion, scale, and self-service for both users and their administrators
- What B2C and B2B mean, and which course covers which

---

![Projects, Environments, and Console Navigation. 3 minutes.](video:descope-101-projects-environments-console)

> [!NOTE]
> Environments are not a toggle inside a project. Each of dev, staging, and production is its own separate Descope project with its own Project ID. Configuration moves between them by clone, export, and import — there is no sync mechanism.

## Company level (Company Settings)

- Projects — the list of all projects, and where you create new ones
- Descopers — the admins who can access the Console, and their permissions
- Management Keys — company-wide credentials for programmatic administration
- Console Access Controls — SSO/SCIM for Console login, enforced SSO, and MFA for Descopers

## Project level (inside a project)

- Flows
- Users
- Authentication Methods
- Authorization — roles and permissions
- Connectors
- Applications — for SSO/OIDC scenarios
- Project Settings
- Audit / Logs

So, adding a teammate who can administer Descope itself is Company Settings → Descopers, while enabling passkeys for the end users of one app is that project's Authentication Methods. The same split decides which credential you need: a script provisioning users across your account requires a management key, whereas a single service validating sessions for one app uses an access key from that project. Picking the right credential type starts with picking the right tier.

## Where common configuration lives

- Project ID and project name — Project Settings
- Session and token settings — project level, and where applicable, the tenant level
- Custom domains — Project Settings
- Management keys — Company Settings
- Roles and permissions — the Authorization area at the project level, or a specific tenant's Authorization tab

![The Console home for one project. The left rail is grouped the way the work is: Build for authentication methods, flows and authorization, Connect for the application features, Manage for users, access keys and tenants. The project switcher sits above it, and the dashboard behind counts daily and total users for the range you pick.](descope-101-projects-environments-console)

## Summary

- A project is the container for everything, identified by the unique Project ID your app connects with, and projects are isolated by default
- Each environment is its own project; promote configuration with clone, export, and import
- Which settings are company-level (projects, Descopers, management keys) and which are project-level (Flows, Users, Authentication Methods, Authorization, Connectors, Project Settings)

---

![Users, Login IDs, and Identity Model. 63 seconds.](video:descope-101-users-login-ids-identity-model)

The identity model is the concept most worth getting right early. A large share of real-world integration problems trace back to an incorrect assumption about what identifies a user.

A login ID is the value a user is known by when they sign in — usually an email address or a phone number. It is the only field a user record actually requires; everything else (email, phone, display name, roles, tenant memberships, custom attributes) is optional at creation and can be layered on afterwards. A single user can hold several login IDs through additional identifiers, which is how one person reaches the same account by more than one route.

## Key concepts

- How Descope models users
- Login IDs
- Verified identifiers
- Custom attributes
- User merging behavior

> [!NOTE]
> A login ID is how a user identifies themselves; it is not automatically the same thing as a verified identifier. Keeping the two distinct in your head will make the authentication modules clearer.

![The Users page. One row per user, keyed by Login ID, with status, display name and a tick against the email once it has actually been verified. The Custom Attributes tab beside it is where fields beyond the built-in ones are defined.](descope-101-users-login-ids-identity-model)

## Summary

- How a Descope user is represented, and that the login ID is the only required field
- The difference between a login ID and a verified identifier
- That merging behavior exists and affects duplicate identities

---
