docs: introduce versioned docs and migrate to fuma (#11166)

## Todos for release

- [x] Configure Env in docs project on vercel
- [x] Configure Root Path in the docs project on vercel
- [ ] Remove old CSP https://github.com/zitadel/website/pull/1592

## What we did

This pull request migrates the project documentation from the old
`docs/` directory to the new `apps/docs/` directory, introduces a new
documentation system built with Next.js and Fumadocs, and updates all
relevant references, configuration files, and documentation to reflect
this change. It also adds new configuration and ignore files for the new
documentation app, updates CI and linting to exclude the new docs from
certain checks, and revises the contributing guidelines accordingly.

**Documentation System Migration and New Docs App**

* Migrated all documentation from `docs/` to `apps/docs/`, and updated
all references in `README.md`, `CONTRIBUTING.md`, and other files to
point to the new location.
[[1]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L585-L640)
[[2]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L660-R607)
[[3]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L740-R687)
[[4]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L2-R3)
[[5]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L30-R30)
* Added a new Next.js/Fumadocs-based documentation app under
`apps/docs/`, including core app files, layouts, routing, search API,
and a comprehensive `README.md` with development and contribution
instructions.
[[1]](diffhunk://#diff-5a1b07344a2c1b4d3f37b23ff1388b62cd9f57dea3c1cd23d8a0412b7602b132R1-R74)
[[2]](diffhunk://#diff-462b9ad1eabbb7d1c29bb9c36e4931eb180fd7190900e6d2babf8f4d66ad1c28R1-R39)
[[3]](diffhunk://#diff-e16ae25660ded787b10ac35dea96d5ecaacf895dae0afc8a9bd4382dc79a8c87R1-R7)
[apps/docs/app/[[...slug]]/layout.tsxR1-R81](diffhunk://#diff-59e08acde4e805b7aeccef1dcf98f1d71dfc550777e6b9402085cee0e9fa4e0aR1-R81),
[apps/docs/app/[[...slug]]/page.tsxR1-R79](diffhunk://#diff-e5df3f80d0fa01e12d63d81f29c57a9d14e846c78fd3beabb2ef768e38fd9580R1-R79),
[[4]](diffhunk://#diff-389b34918e040cacaa87cd7201ffa462cc2b0b716736f537e3d3c660ac69353bR1-R7)
[[5]](diffhunk://#diff-d3b03416d1c457b19f1c27b26f2db741412df841b875c26ccadc36e4522247f4R1-R29)
[[6]](diffhunk://#diff-c8fb8339570a5305809be7c618e14705fd86390dc278e6ce8ba224a7bc8b0c3cR1-R25)

**Configuration and Tooling Updates**

* Updated `.github/workflows/codeql.yml`, `.golangci.yaml`, and
`.github/dependabot.yml` to properly handle the new docs app: excluded
`apps/docs` from certain checks, added npm dependency updates for the
docs app, and excluded generated content.
[[1]](diffhunk://#diff-12783128521e452af0cfac94b99b8d250413c516ec71fe6d97dbea666ff7ba27L8-R14)
[[2]](diffhunk://#diff-9917ddc9f1c3304218f7269265b746d997c5c0615478177b5fceecd33ef47cb5R5-R6)
[[3]](diffhunk://#diff-9917ddc9f1c3304218f7269265b746d997c5c0615478177b5fceecd33ef47cb5R126-R129)
[[4]](diffhunk://#diff-dd4fbda47e51f1e35defb9275a9cd9c212ecde0b870cba89ddaaae65c5f3cd28R89-R106)
* Updated `.devcontainer/devcontainer.json` to use the latest Go 1.25.3
version for consistency.

**Licensing and Miscellaneous**

* Added `apps/docs/` to the list of licensed directories in
`LICENSING.md`.

These changes ensure the documentation is now maintained in a modern,
scalable system and all project tooling is updated to support the new
structure.

---------

Co-authored-by: Federico Coppede <[email protected]>
This commit is contained in:
Florian Forster
2026-01-29 08:38:36 -08:00
committed by GitHub
co-authored by Federico Coppede
parent 7b6395c348
commit d8ea041c56
2826 changed files with 78739 additions and 23571 deletions
@@ -0,0 +1,86 @@
---
title: Authentication and authorization in multi-tenancy B2B scenarios
sidebar_label: B2B
---
import { B2B } from "@/components/b2b";
## Business to Business
B2B describes the situation where an organization interacts with other organizations.
This **multi-tenancy architecture** usually adds some form of complexity to an Identity and Access Management System.
In ZITADEL an [organization](/guides/manage/console/organizations-overview) can represent a business partner or partner who typically has its own branding and has different access settings like an additional federated login for its users.
B2B can be a simple scenario where an organization only shares one of its projects with another organization or have a more complex case where an organization is offering a portal application to all its partners with included (self)administration.
## Sample scenario
Octagon is a fictitious company which is used throughout this guide to explain the details and key concepts of such a B2B scenario.
Octagon tries to solve multiple tasks in the banking field. Its portfolio includes several applications for their employees, customers, and partners. Some of which are web-based, some of which are used by machine users only.
### Portal Application
Octagon has a **Portal application** where its employees can access their account and list all applications they are allowed to use.
Employees work for a department within Octagon or for Octagon itself.
Some of the users have enhanced features because they supervise certain teams. Those can onboard new employees and manage their roles and features.
Target groups of the application can be split into:
- **Employees:** users who are using the application as a starting point for their work.
- **Supervisors:** users who are mainly using the application to manage users and their access of their department.
- **Administrators:** this users are able to grant additional organizations or departments and elect supervisors.
### Planning considerations
In order to define the need of the **Portal Application** some planning considerations about organizations have to be made:
- **Login and Access:** Does a user have a preset organization to login? Does the application show the default login page or does each organization use its own branding?
- **Organizations:** Does a user have access in multiple organizations? Is a user required to use a different federated login for those organizations?
- **Roles** Does the application need users to have specific roles assigned within their organizations? Which roles are needed to enable certain features of the application?
### Login
You can decide whether a organization is preselected for the login or if the user is redirected to the default login screen. Using OpenID Connect, you can send the user to a specific organization by defining the organization in a [reserved scope](/apis/openidoauth/scopes#reserved-scopes) (primary domain).
Settings to the branding or the login options of the organization can be made from the organization section in [Console](/guides/manage/console/console-overview).
The behavior of the login branding can be set in your projects detail page. You can choose the branding of the selected organization, the user's organization, or the project's organization.
### Organizations
Generally a user belongs to and is managed by one organization, however the user can receive authorizations from multiple other organizations (delegated authorizations). Anyways, a user should be able to use the same identity to switch between organizations.
If this feature is not desired, a separate user for each organization should be created.
Adding a user from a different organization to the audience of a project can be as easy as adding a new user authorization (user grant). A user grant combines a user from any organization with a project and 0-N roles.
In our sample scenario, we assume to have the following users:
- **Dimitri:** a team leader who is employed by Pentagon, an Octagon department. Dimitri uses his Microsoft Account in combination with his one time password to access the portal. Pentagon therefore has set up Microsoft as Identity Provider. Pentagon also requires its users to secure their accounts with additional factors.
- **Michael:** a trainee of Pentagon only using the portal to access his workspace apps. Michael uses his Google Account in combination with his laptops fingerprint.
- **Bill:** is employed at Octagon as Administrator of the Portal Application. Bill also uses a Microsoft Account in combination with a Security Key to secure his account.
After having determined the constellation of the organizations and its users, all the necessary data (Portal project with roles and app, users, login requirements, identity providers, branding) should be set up in [Console](https://${CUSTOM_DOMAIN}.zitadel.cloud/ui/console/org).
A B2B [sample application](https://github.com/zitadel/zitadel-nextjs-b2b). for NextJS can be found [here](../../examples/login/nextjs-b2b).
To allow another organization to use a project, a project grant has to be created. Upon creation, roles for a grant can be limited to a subset of the total project roles.
In our scenario, Octagon creates a project grant for Pentagon. Pentagon is limited to use `writer` and `reader` role. The `admin` role is reserved for the Octagon organization itself.
<B2B></B2B>
### Roles
In this scenario, Dimitri and Michael share the same organization Pentagon, where as Bill belongs to Octagon. Octagon is owner of the Portal project with its Web App, having Bill configured as user grant with `admin` role. Dimitri owns the `writer` role, whereas Michael only is `reader`.
> Note: Roles are meant for internal business logic and therefore need to be validated separately, none of the users described are allowed to create user grants, at least if they do not own a ZITADEL administrator role.
If you made a dashboard where some users are able to create user grants, the Management API to do such operations should be triggered with the personal access token of the users, not with a token of a machine user, to create a meaningful audit log.
If you had such a use case, ZITADEL administrator roles must be assigned to those users.
### Noteworthy
Due to the fact that ZITADEL includes unlimited users, projects, and applications and comes with all security features in the FREE tier, ZITADEL can be considered a great alternative to other SaaS IAM systems such as Auth0 or Okta.
In such a case with this high potential of scalability where user counts can grow explosively, ZITADEL does not become the bottleneck and therefore is the valid choice. You can learn more on ZITADELs benefits and the pricing [here](https://zitadel.com/pricing).
### Learn more
- [Creating an organization](../manage/console/organizations)
- [Organization Branding](../manage/customize/branding)
- [Authorization](../integrate/login/oidc/oauth-recommended-flows)
@@ -0,0 +1,108 @@
---
title: ZITADEL for B2C Scenarios
sidebar_label: B2C
---
import Column from "@/components/column";
## Business to Consumer
Users in general come with different needs. You may have end users, employees, or even customers from other parties (B2B).
This groups of users usually don't share the same intentions and use applications differently.
When planning your applications, investing time in researching your apps architecture is vital for later feature upgrades and enhancements as those changes come in with heftier price points if you have to make bigger changes.
This guide introduces you to the grouping and structuring of ZITADEL projects which forms the base for all projects. This can be used as a quick start to the [B2B scenario](./b2b), which is merely focused on planning considerations if you are having projects with multiple organizations.
The journey of this guide starts with creating an Organization, the outermost layer of ZITADEL within your instance, as it is the vessel for projects, roles, applications and users.
Creation can be done from [ZITADEL Management Console](https://${CUSTOM_DOMAIN}.zitadel.cloud/ui/console/orgs/create). You can choose your current account for the organization owner or create a new one.
Depending on your Software Development Life Cycle (SDLC) you can create multiple organizations or projects to keep your applications environments separated.
### Organization Domain
Right after org creation you'll be greeted with the domain section of your organization.
ZITADEL automatically creates an organization domain of the form `[orgname].zitadel.cloud`, but you can create your own. Depending on the settings on the [Domain Policy](../../concepts/structure/policies) it has to be verified by saving a verification file on the specified location.
We recommend that you create your domains early as they create a sense of confidence and trust for your application and changes later on might create additional migration effort.
You can read more about how ZITADEL handles usernames [here](../manage/console/organizations#how-zitadel-handles-usernames).
### Data Provisioning
ZITADEL gives you a basic storage for users and manages phone and email addresses. It also allows you to store your own application data such as preferences or external identifiers to the metadata of a user.
If you are migrating an existing project and you already have an external identity store you can consider bulk importing your user datasets.
Read our [Management API definitions](/reference/api/management) for more info. If the users email is not verified or no password is set, a initialization mail will be send.
<Callout>
Requests to the management API are rate limited. Read our [Rate limit Policy](/legal/policies/rate-limit-policy) for more info.
</Callout>
### User Authentication
User Authentication can be performed in multiple ways. Default method in ZITADEL is username and password with MFA enabled.
ZITADEL allows you to configure Multifactor- and Passkey Authentication in order to enhance security for your users. All authentication methods are available from the FREE Tier.
To setup your organizations login policy, go to your organizations detail in [Console](https://${CUSTOM_DOMAIN}.zitadel.cloud/ui/console/org).
When planning your application consider the following questions about User Authentication:
- What are the methods to authenticate your users?
- Where will your users enter their credentials?
- Do you offer password authentication?
- What do you do to keep your users credentials safe?
- Do you offer Multifactor Authentication?
- Do you offer Login via Identity Provider?
- Which languages do you have to provide?
When looking at these questions, you may have to admit that building an Identity Management System is much more complex and complicated than you thought initially and implementing if yourself may be too much work.
Particularly because you should focus building your applications.
### Federation
ZITADEL supports signup with OIDC Identity providers as well as JWT Identity Providers. On signup, ZITADEL imports user information to the own profile.
### Hosted Login
ZITADEL offers a "secure by default approach" and comes with a Hosted Login which is a fixed endpoint for your users to authenticate.
It's safe and secure and comes with Multifactor, Federated Login and Passkey capabilities.
OIDC (OpenID Connect) opens the doors to Single Sign On (SSO). Especially if you have more than one application, you may want a central and familiar authentication experience.
With SSO, ZITADEL provides a seamless experience across all your apps.
### Branding
<Column>
<div>
Branding and customization is a very important part of your application.
With ZITADEL you can modify colors, logos, icons as well as configure your typography styles, such that you can provide a consistent design throughout your applications.
In addition to visual modifications, you can edit notification texts for your users.
ZITADEL gives you handlebar similar templating for variables. Of course you can define texts for any language.
We'd appreciate if you could contribute to our repo with translations of your language. Read on how to contribute [here](../manage/customize/texts).
> Note that your management console design changes to your design too
</div>
<img src="/docs/img/guides/branding.jpeg" alt="branding in management console"/>
</Column>
### Projects and applications
As our Hosted Login is a separate authentication screen, you have to determine how you are directing your users from your applications.
ZITADEL's Applications live under ZITADEL's Projects. You may add multiple applications for your different client-types (Native, Web, User Agent, or API). When setting up your applications consider reading our guide about [Authentication Flows](../integrate/login/oidc/login-users).
### Access Control
By having authenticated a user you need to ensure users and services have access to your application and APIs. This process is called Access Control and comprises User Authentication, Authorization and Policy Enforcement.
Take the following considerations:
- Does your application call your own APIs?
- Does your application need to call third-party APIs?
- Do **you** offer an API for third-party applications?
The data required to check if a user has access to a certain API is stored within a user grant. This information typically is stored within roles or custom claims and can be accessed with an `access` or OIDC `id` token.
Read more about Authorization in our [Guide](../integrate/login/oidc/oauth-recommended-flows).
## Learn more
- [Creating an organization](../manage/console/organizations#create-a-new-organization)
- [Organization Branding](../manage/customize/branding)
- [Authorization](../integrate/login/oidc/oauth-recommended-flows)
@@ -0,0 +1,154 @@
---
title: Configure ZITADEL for your Scenario
sidebar_label: Common Configurations
---
Each customer does have different needs and use-cases. In ZITADEL you are able to configure your settings depending on your needs.
In this section we show you the different use-cases we have already experienced, that could interest you.
## Automatically redirect users if the organization has only one identity provider
You have different customers (organizations) in your ZITADEL instance and they have different needs on how to authenticate their users. One of your customers does only allow login with an external identity provider like Google, Entra ID, and so on.
If a user of this organization wants to login, you don't want them to enter their username in the ZITADEL Login UI, they should be redirected directly to the identity provider without their interaction.
### Settings
1. Go to the "Identity Providers" Settings of the organization
2. Configure the needed identity provider: Read this [guide](../integrate/identity-providers/introduction) if you don't know how
3. Go to the "Login Behavior and Security" settings of the organization
4. Disable "Username Password Allowed" and enable "External IDP allowed" in the Advanced Section
Now your application can send either the organizations id (`urn:zitadel:iam:org:id:{id}`) or organizations primary domain (`urn:zitadel:iam:org:domain:primary:{domainname}`) scope on your authorization request to identify on which organization the users should be logged in.
More about the [scopes](/apis/openidoauth/scopes#reserved-scopes)
## Custom Application Domain per Organization
If you have an application that runs a dedicated domain for each customer you need to instruct ZITADEL to allow redirection for each domain specifically to safeguard against phishing attacks.
Example:
MyApplication: `customer-a.app.com`
ZITADEL Login: `login.app.com`
In the OIDC Authorization request you always have to send the redirect URI to where you like to be redirected after login.
To handle this scenario it is possible to register multiple URIs on each application in ZITADEL, the only criteria is that the requested URI has to match one of the registered URIs.
Read more about [applications](../manage/console/applications) and the [redirect urls](../manage/console/applications#redirect-ur-is)
### Trigger organization in ZITADEL login
It is possible to trigger the organization directly with the authorization request to ZITADEL.
This will have the following impacts:
- Trigger organization login behavior settings
- Trigger organization branding
- Only allow users from selected organization to login
To request the organization send either the the organization id (`urn:zitadel:iam:org:id:{id}`) or organization primary domain (`urn:zitadel:iam:org:domain:primary:{domainname}`) scope on your authentication request from your application.
More about the [scopes](/apis/openidoauth/scopes#reserved-scopes)
## Use email to login
There are two different possibilities to achieve login with an email.
1. Use an email address as username
2. Use the email field of the user as additional login to the username
![](../../../public/img/guides/scenarios/domain_policy_org_domain_disabled.png)
### Use an email address as username
To be able to use the email as username you have to disable the attribute "User Loginname must contain orgdomain" on your domain settings.
This means that all your users will not be suffixed with the domain of your organization and you can enter the email as username.
All usernames will then be globally unique within your instance.
You can either set this attribute on your whole ZITADEL instance or just on some specific organizations.
### Use the email field of the user as additional login to the username
No matter how the username of your user does look like.
You can additionally allow login with the email attribute of the user.
You can find this in the "Login Behavior and Security" Setting of your instance or organizations.
Go to the "Advanced" section, per default login with email address should be allowed. It is possible to disable it.
![](../../../public/img/guides/scenarios/login_policy_advanced.png)
## Use phone number to login
There are two different possibilities to achieve login with a phone number.
1. Use a phone number as username
2. Use the phone number field of the user as additional login to the username
![](../../../public/img/guides/scenarios/domain_policy_org_domain_disabled.png)
### Use a phone number as username
To be able to use the phone number as username you have to disable the attribute "User Loginname must contain orgdomain" on your domain settings.
This means that your users will not be suffixed with the domain of an organization and you can enter the phone number as username.
All usernames will then be globally unique within your instance.
You can either set this attribute on your whole ZITADEL instance or just on some specific organizations.
### Use the phone number field of the user as additional login to the username
No matter how the username of your user looks like,
you can additionally allow login with the phone number attribute of the user.
You can enable this feature in the "Login Behavior and Security" Setting of your instance or organizations.
Go to the "Advanced" section, per default login with phone number should be allowed. It is possible to disable it.
![](../../../public/img/guides/scenarios/login_policy_advanced_phone.png)
## Embedding ZITADEL in an iFrame
To maximize the security during login and in the Management Console UI, ZITADEL follows security best practices by setting a
Content-Security-Policy (CSP), X-Frame-Options and cookies with SameSite Lax:
```
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: deny
```
These settings block the use of serving it in an iframe to prevents clickjacking attacks.
### Enable iFrame embedding
<Callout type="warn">
This change can make you vulnerable to clickjacking attacks.
</Callout>
If your applications need to load ZITADEL inside an iframe, e.g. for a silent login or silent refresh, you can enable the use on an instance level.
1. Navigate to the Default Settings.
2. Click on the Security Policy tab.
3. Enable the "Allow IFrame" and add the host(s) you load the iframe from.
You can add further hosts later on.
![](../../../public/img/guides/scenarios/security_policy.png)
This will change the CSP to the following:
```
Content-Security-Policy: frame-ancestors https://custom-domain.com
```
remove the X-Frame-Options header and change the SameSite to `None`.
<Callout>
Please note, that SameSite None requires the cookie to be flagged `secure`, which means it must be sent over TLS (HTTPS) or localhost.
This also means that domains other than localhost must use TLS for this option to work.
This is due to browser restrictions: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#none
</Callout>
### Disable Multi-factor (MFA) Prompt
To encourage the users to more security for their accounts, a multi-factor prompt is shown after a certain time, to prompt them to configure an additional factor.
This prompt is shown even if multi-factor is not enforced for the users.
If you do want to disable the prompt for your users, go to the login behavior settings and set the "Multifactor Init Lifetime" to 0.
If the setting is not configured to 0, it means that after that time, the user will be asked again to setup a factor.
![](../../../public/img/guides/scenarios/login-settings-mfa-init-lifetime.png)
@@ -0,0 +1,128 @@
---
title: Domain Discovery in ZITADEL
sidebar_label: Domain Discovery
---
This guide should explain how domain discovery works and how to configure it in ZITADEL.
## Overview
Domain discovery is typically used in [B2B](./b2b) or [SaaS](./saas) scenarios where you have users from different organizations and you want to route them according to their login methods, which could be a user name or, depending on your configuration, also an [email / phone number](./configurations#use-email-to-login).
![](../../../public/img/guides/solution-scenarios/domain-discovery.png)
In the example there is a service provider with a ZITADEL instance running on a [Custom Domain](/guides/manage/cloud/instances#add-custom-domain) on `login.mycompany.com`.
By default all users login on the organization **CIAM** with their preferred social login provider.
Users of the two business customers **Alpha** and **Beta** should login according to their organization login and access policy settings.
In case of Alpha users will login via an external identity provider (eg, [Entra ID](/guides/integrate/identity-providers/azure-ad-oidc)).
Beta users must only login with username/password and MFA instead.
For this scenario you need to route the user `[email protected]` to the **Alpha Organization** and `[email protected]` to the **Beta Organization** respectively.
Follow this guide to configure your ZITADEL instance for this scenario.
## Instance
### Default Login Page
You will use the instance default settings for the login for the organization **CIAM**.
When opening `login.mycompany.com` then the login policy of the instance will be applied.
This means that you have to configure the [Login and Access](/guides/manage/console/default-settings#login-behavior-and-access) Policy and [Identity Providers](/guides/manage/console/default-settings#identity-providers) for the **CIAM** users on the instance itself.
<Callout>
You can also configure these settings on the default organization (see below) and send the scope `urn:zitadel:iam:org:id:{id}` with every [auth request](https://zitadel.com/playgrounds/oidc).
</Callout>
### Default Organization
Set **CIAM** as [default organization](/guides/manage/console/organizations-overview#default-organization).
You will find the overview of all organizations under the "Organizations" tab on the Default Settings.
The default organization will hold all unmatched users, ie. all users that are not specifically in the organizations **Alpha** or **Beta** in the example.
### Enable Domain Discovery
In the [Login Behavior and Security Settings](/guides/manage/console/default-settings#login-behavior-and-access) enable "Domain discovery allowed"
### Configure login with email
Follow this [configuration guide](/guides/solution-scenarios/configurations#use-email-to-login) to allow users to login with their email address.
### Other considerations
You can also have multiple Custom Domains pointing to the same instance as described in this [configuration guide](/guides/solution-scenarios/configurations#custom-application-domain-per-organization). In our example you could also use `alpha.mycompany.com` to show the login page of your instance.
The domain of your email notification can be changed by [setting up your SMTP](/guides/manage/console/default-settings#smtp).
## Organization
### Alpha organization
Users of **Alpha** should only be allowed to authenticate with their company's identity provider.
In the organization settings under Login Behavior and Access make sure the following settings are applied:
- **Username Password allowed**: Disabled
- **Register allowed**: Disabled - we will configure this on the external identity provider
- **External IDP allowed**: Enabled
Now you can configure an [external identity provider](/guides/manage/console/default-settings#identity-providers).
<Callout>
Given you have only one external identity provider configured, when a user tries to login on that organization, then the user will be automatically redirected to the external identity provider.
In case multiple providers are configured, then the user will be prompted to select an identity provider.
</Callout>
### Beta organization
Users of **Beta** must create an account and login with password and 2FA.
In the organization settings under Login Behavior and Access make sure the following settings are applied:
- **Username Password allowed**: Enabled
- **Register allowed**: Disabled - you may want [Managers](/concepts/structure/managers) to setup accounts.
- **External IDP allowed**: Disabled
Make sure to [Force MFA](/guides/manage/console/default-settings#multifactor-mfa) so that users must setup a second factor for authentication.
### Verify domains
Switch to the organization **Alpha** and navigate to the settings and "Verified domains".
Verify the domain alpha.com following the [organization guide](/guides/manage/console/organizations-overview#usernames-and-domains).
Do the same for the **Beta** organization.
<Callout>
You can also disable domain verification with acme challenge in the [default settings](/guides/manage/console/default-settings#domain-settings).
</Callout>
## Conclusion
You should be all setup to try out domain discovery.
The user journeys for the different users would look as follows:
- User (Alice, Bob, Chuck) clicks a login button in your application
- Redirected to `login.mycompany.com` (ZITADEL running under a Custom Domain)
Chuck
1. Select Google button
1. Redirect to Google IDP
1. Chuck logs in with Google credentials
1. Redirected back to your application
Alice
1. Alice enters [email protected] and clicks next
1. Redirect to Entra ID Tenant (or any other IDP)
1. Alice logs in with her company credentials
1. Redirected back to your application
Bob
1. Bob enters [email protected] and clicks next
1. Bob will be redirected to a login with the branding of beta.com
1. Bob enters his password and MFA on the login screen
1. Redirected back to your application
@@ -0,0 +1,64 @@
---
title: Frontend and Back-end API Communication in ZITADEL
sidebar_label: Frontend and API Communication
---
This guide contains a use case and ZITADEL integration.
In a typical web application architecture, the front-end and back-end communicate to exchange data and provide functionality to users. Let's consider a use case where a front-end application needs to communicate with a back-end API using secure authentication and authorization. Let’s explore how ZITADEL can be used to add front-end login and facilitate this communication.
Single-Page Applications (SPAs) are web applications that run entirely in the browser, without a back-end server. In ZITADEL SPAs should use the Authorization Code Grant with PKCE or the Implicit Grant (if PKCE is not feasible) to obtain an access token.
While APIs are vital for communication between applications and services, they don't directly participate in user authentication. Instead, they often authorize client requests based on access tokens issued by an authorization server. APIs in ZITADEL use grant types like JWT Profile or Basic Authentication to access the authorization server's introspection endpoint for token validation.
## A real-world scenario
Suppose there is a news portal web app that allows users to browse through various news articles and personalize their news feed based on their preferences. The back-end API handles fetching and delivering news content from the database.
**Front-End Login**: A user visits the news portal and opts to log in for a personalized news feed. They are redirected to the Identity Provider’s (IdP) login page, where they authenticate with their credentials. Upon successful authentication, the IdP issues access and ID tokens to the front-end app.
**Back-End API Communication**: When the user browses through the news feed, the front-end app makes an API request to the back-end, including the access token in the Authorization header. The back-end API, upon receiving the request, uses the IdP’s introspection endpoint to validate the access token. Once validated, it fetches personalized news data based on the user's preferences from the news database.
While it is true that the back-end API typically needs to authenticate with the IdP, in this specific use case, the back-end API can work with a client credential / JWT since it's not a public client. This means that instead of relying on user-specific authentication, the back-end API can obtain a client credential (such as a client ID and client secret) from the IdP to authenticate itself and validate the access token received from the front-end app. This approach ensures secure communication between the front-end app, the back-end API, and the IdP, while still allowing the back-end API to access user-specific data and provide personalized news feeds.
## A simplified example with a React frontend and a Python Flask API
In this example, the application is a web-based quote generator that employs a secure user authentication system via ZITADEL. The functionality of the app is outlined below:
1. Upon starting, the application provides a login button
2. The user is then redirected to ZITADEL's login page to enter their credentials.
3. Once the login is successful, the application then greets the user by extracting the user's name, thus providing a personalized experience.
4. The application presents an option for the user to generate a quote via a button. Upon pressing this button, the front-end application communicates with the back-end API using the user's access token received from ZITADEL.
5. The back-end API introspects the access token for validity using ZITADEL's introspection endpoint. If the token is valid, the API generates a quote and sends it as a response to the front-end application, which is then displayed to the user in their browser.
## Setting up the applications and ZITADEL
All code and instructions to run the sample application can be found at [https://github.com/zitadel/example-quote-generator-app/](https://github.com/zitadel/example-quote-generator-app/). You can also find the steps for the integration between the front-end, back-end API, and ZITADEL in the README.md.
You can create the front-end application (User Agent) and the API in the same project or in a different project. In this example, we have created both in one. Configure the applications with appropriate settings (as instructed).
<img src="/docs/img/guides/solution-scenarios/frontend-calling-backend-API_1.png" alt="User Agent and API applications in a single project"/>
### Front-end login with ZITADEL
- You must create a User Agent application in your project to add login to your React application using the Authorization Code with PKCE flow. This allows the front-end application to integrate with ZITADEL to enable user authentication and authorization.
- In the React front-end application, configure the ZITADEL OIDC client settings, including the client ID, ZITADEL URLs, redirect URIs, and required scopes.
- Implement the login flow, authentication callbacks, and token handling logic in the front-end application.
- When a user visits the front-end application, they are presented with a login option.
- Upon clicking the login button, the frontend initiates the Authorization Code with PKCE authentication flow and redirects the user to the ZITADEL login page. The user enters their credentials and authenticates with ZITADEL. Authorization Code Flow returns an authorization code to the client application, which can then exchange it for an ID token and an access token directly. This provides the benefit of not exposing any tokens to the user agent and possibly other malicious applications with access to the user agent.
- You must set up the required scopes and claims to ensure the front-end and back-end can exchange data securely. It’s important to note that when specifying the scope when calling the token API, the scope must contain the project ID of the ZITADEL project in which the API resides (to enable token validation by the back-end API):`scope:'openid profile email urn:zitadel:iam:org:project:id:<API_PROJECT_ID>:aud'`
- Also, we want to include user info inside the token to avoid calling the user info endpoint, so go to Token Settings in the front-end app and select User Info inside ID Token.
- After a successful authentication, ZITADEL generates an access token and an ID token.
- The front-end application receives these tokens and stores them securely (e.g., in browser storage).
### Token exchange and user information
- Once the frontend obtains the tokens, it can extract certain information from the ID token itself (e.g., user ID, email, etc.) without making an additional request.
- If more user information is required, the frontend can use the access token to call the ZITADEL User Info endpoint. This endpoint provides additional user details, such as name, profile picture, etc.
### Back-end API communication
- To communicate with the back-end API, the front-end includes the access token in the Authorization header of API requests.
- The back-end API receives the request and needs to validate and authorize the token before processing the request.
- The API performs token introspection using ZITADEL's introspection endpoint to validate the access token. This API uses Basic Authentication to invoke the [introspection endpoint](/apis/openidoauth/endpoints#introspection-endpoint), which means it sends its client ID and client secret along with the access token received.
- If the token is valid and active, the API proceeds to handle the requested action or fetch data from the underlying data sources.
@@ -0,0 +1,9 @@
---
title: Solution Scenarios
---
Learn how to use ZITADEL for different scenarios.
- [B2B](/guides/solution-scenarios/b2b)
- [B2C](/guides/solution-scenarios/b2c)
- [SaaS](/guides/solution-scenarios/saas)
@@ -0,0 +1,19 @@
---
title: "Use Cases"
description: "Customers of an SaaS Identity and access management system usually have all distinct use cases and requirements. This guide attempts to explain real-world implementations and break them down into solution scenarios which aim to help you getting started with ZITADEL."
---
{/* THIS FILE IS AUTO-GENERATED FROM SIDEBAR-DATA.
ANY MANUAL CHANGES WILL BE OVERWRITTEN.
*/}
import { Card, Cards } from 'fumadocs-ui/components/card';
import { FileText, Folder, Link as LinkIcon } from 'lucide-react';
<Cards>
<Card title="B2b" href="/guides/solution-scenarios/b2b" icon={<FileText />} />
<Card title="Configurations" href="/guides/solution-scenarios/configurations" icon={<FileText />} />
<Card title="Saas" href="/guides/solution-scenarios/saas" icon={<FileText />} />
<Card title="B2c" href="/guides/solution-scenarios/b2c" icon={<FileText />} />
<Card title="Frontend Calling Backend API" href="/guides/solution-scenarios/frontend-calling-backend-API" icon={<FileText />} />
</Cards>
@@ -0,0 +1,81 @@
---
title: Prevent users from accessing ZITADEL Management Console
sidebar_label: Limit access to management console
---
ZITADEL includes a management console that allows Managers to configure all resources. All uses, including end-users, by default, view and manage their profile information.
In some use cases you want to prevent users from accessing the management console, this could be:
- User management is integrated into your own app
- Users login via SSO and should not be able to change their data in the Management Console
- Only managers should be able to access Management Console to manage their users
At the moment it is not possible to simply disable the Management Console, but with the configuration described in this guide, you can prevent users from accessing the Console.
## Self-hosted
If you are running ZITADEL self-hosted, we recommend restricting the access to ZITADEL Management Console via WAF/reverse-proxy for Non-Manager users
## ZITADEL Cloud (and self-hosted)
### Default redirect url
One goal is to never send the end user to the ZITADEL management console.
This does make sense if you build your own user profile page within your application.
In that case you probably want to redirect the user to your own application, instead of to the console.
Read more about how to set the default redirect URI: [Settings - Default Redirect URI](/guides/manage/console/default-settings#default-redirect-uri)
### Restricting Management Console in default-project
With this workaround, you will limit users from accessing the [default-project](/guides/manage/console/projects-overview#the-default-project) if they are not explicitly granted to use this project.
When setting the "Check for Project on Authentication" setting on a project, only users of organizations with a grant to that project can access it.
By default, this setting is disabled, so all users can access the project.
![](../../../public/img/guides/solution-scenarios/console-check-project-auth.png)
Start by granting the organization of your managers, that should be able to access the Management Console, the [default project](/guides/manage/console/projects-overview#the-default-project):
1. Click on the default-project > Grants > New +
![](../../../public/img/guides/solution-scenarios/console-zitadel-project-grants.png)
2. On the next screen select the organization to which you want to give the grant
![](../../../public/img/guides/solution-scenarios/console-create-project-grant-org.png)
3. You can skip the screen with the role selection and click save
4. Make sure the grant is in now in the overview and marked as active.
To avoid accidental lock-out, the [default project](/guides/manage/console/projects-overview#the-default-project) hides the checkbox "Check Project on Authentication" in the Management Console:
![Default Project](../../../public/img/guides/solution-scenarios/console-default-project.png)
You need to use the [update project API call](/reference/api/management/zitadel.management.v1.ManagementService.UpdateProject) to set the configuration on the project.
First, you need a user with manager permissions to change the project settings in that organization.
This means either you add the manager to the organization or you use a manager on the instance level with "IAM-OWNER" permissions.
After that create a Personal Access Token (PAT) for the manager.
More detailed information about creating a PAT and administrator roles you can find [here](/guides/integrate/service-users/personal-access-token)
Then you have to send the following request:
```bash
curl -L -X PUT "https://${CUSTOM_DOMAIN}/management/v1/projects/${PROJECT_ID}" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H "Authorization: Bearer ${PAT}" \
--data-raw '{
"name": "ZITADEL",
"projectRoleAssertion": false,
"projectRoleCheck": false,
"hasProjectCheck": true,
"privateLabelingSetting": "PRIVATE_LABELING_SETTING_UNSPECIFIED"
}'
```
Where
- `${CUSTOM_DOMAIN}` is your Custom Domain, f.e. mydemo.zitadel.cloud
- `${PAT}` is your service user's personal access token
- `${PROJECT_ID}` is the default-project's ID that can be found in Management Console see screenshot above
You should now be able to log in with users of the organization that have the grant (in this example users of the organization "Customer-A").
All other users should see the following error message after authentication:
![](../../../public/img/guides/solution-scenarios/console-access-restricted.png)
@@ -0,0 +1,72 @@
---
title: Set up a SaaS Product with Authentication and Authorization using ZITADEL
sidebar_label: Software-as-a-Service
---
This is an example architecture for a typical SaaS product.
To illustrate it, a fictional organization and project is used.
## Example Case
The Timing Company has a product called Time.
They have two environments, the development and the production environment.
In this case Time uses authentication and authorizations from ZITADEL.
This means that the users and also their authorizations will be managed within ZITADEL.
![](../../../public/img/concepts/usecase/saas.png)
## Organization
An organization is the ZITADEL resource which contains users, projects, applications, policies and so on.
In an organization projects and users are managed by the organization.
You need at least one organization for your own company in our case "The Timing Company".
Your next step is to create an organization for each of your customers.
## Project
The idea of projects is to have a vessel for all components who are closely related to each other.
In this use case we would have two different projects, for each environment one. So lets call it "Time Dev" and "Time Prod".
These projects should be created in "The Timing Company" organization, because it is the owner of the project.
In the project you will configure all your roles and applications (clients and APIs).
### Project Settings
You can configure `check roles on authentication` on the project, if you want to restrict access to users that have the correct authorization for the project.
### Project Grant
To give a customer permissions to a project, a project grant to the customers organization is needed (search the granted organization by its domain).
It is also possible to delegate only specific roles of the project to a certain customer.
As soon as a project grant exists, the customer will see the project in the granted projects section of their organization and will be able to authorize their own users to the given project.
## Authorizations
To give a user permission to a project an authorization is needed.
All organizations which own the project or received a grant are able to authorize users.
It is also possible to authorize users outside the own company if the exact login name of the user is known.
## Project Login
There are some different use cases how the login should behave and look like:
1. Restrict Organization
With the primary domain scope the organization will be restricted to the requested domain, this means only users of the requested organization will be able to login.
The private labeling (branding) and the login policy of the requested organization will be set automatically.
<Callout>
More about the [Scopes](/apis/openidoauth/scopes)
</Callout>
2. Show private labeling (branding) of the project organization
You can configure on project-level which branding should be shown to users.
In the default the design of the instance will be shown, but as soon as the user is identified, the policy of the users organization (if specified) will be triggered.
If the setting is set to `Ensure Project Resource Owner Setting`, the private labeling of the project organization will always be triggered.
The last possibility is to show the private labeling of the project organization and as soon as the user is identified the user organization settings will be triggered.
For this the Allow User Resource Owner Setting should be set.
<Callout>
More about [Private Labeling](/guides/manage/customize/branding)
</Callout>