mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-10 16:15:12 +00:00
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:
co-authored by
Federico Coppede
parent
7b6395c348
commit
d8ea041c56
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: Behavior Customization
|
||||
---
|
||||
|
||||
In this guide, you will create a [ZITADEL action](../../../concepts/features/actions).
|
||||
After users register using an external identity provider, the action assigns them a role.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you start, make sure you have everything set up correctly.
|
||||
|
||||
- You need to be at least a ZITADEL _ORG_OWNER_
|
||||
- Your ZITADEL organization needs to have the actions feature enabled. - [Your ZITADEL organization needs to have at least one external identity provider enabled](../../integrate/identity-providers/introduction)
|
||||
- [You need to have at least one role configured for a project](../console/projects)
|
||||
|
||||
## Copy some information for the action
|
||||
|
||||
1. Select the **Projects** navigation item.
|
||||
1. Select a project that has a role configured.
|
||||
1. Copy the projects **Resource Id** on the screens top right.
|
||||
1. Scroll to the **ROLES** section and note some roles key.
|
||||
|
||||
## Create the action
|
||||
|
||||
1. Select the **Actions** navigation item.
|
||||
1. In the **Actions <i className="las la-code"></i>** section, select the **+ New** button.
|
||||
1. Give the new action the name `addGrant`.
|
||||
1. Paste this snippet into the multiline textfield.
|
||||
1. Replace the snippets placeholders and select **Save**.
|
||||
|
||||
```js reference
|
||||
https://github.com/zitadel/actions/blob/main/examples/add_user_grant.js
|
||||
```
|
||||
|
||||
## Run the action when a user registers
|
||||
|
||||
Now, make the action hook into the [external authentication flow](/apis/actions/external-authentication).
|
||||
|
||||
1. In the **Flows <i className="las la-exchange-alt"></i>** section, select the **+ New** button.
|
||||
1. Select the **Flow Type** _External Authentication_.
|
||||
1. Select the **Trigger Type** _Post Creation_.
|
||||
1. In the **Actions** dropdown, check _addGrant_.
|
||||
1. Select the **Save** button.
|
||||
|
||||
New users automatically are assigned a role now if they register by authenticating with an external identity provider.
|
||||
|
||||
## What's next?
|
||||
|
||||
- [Read more about the concepts around actions](/concepts/features/actions)
|
||||
- [Read more about all the options you have with actions](/guides/manage/console/actions-overview)
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: Brand Customization
|
||||
---
|
||||
|
||||
ZITADEL offers various customization options for your projects brand design. The branding can be configured on two different levels.
|
||||
The configuration on the instance level will set the default settings, which are triggered for all users if not overwritten on an organization specifically.
|
||||
The second possibility is to configure it on each organization. This guide will describe the second possibility.
|
||||
For this head over to the Branding Setting on your Organization Page.
|
||||
|
||||
## How it works
|
||||
|
||||
You are able to customize the light and a dark mode separately.
|
||||
All your changes will be shown in the preview window on the right side.
|
||||
As soon as you are happy with your configuration click the "Apply configuration" button.
|
||||
After this your settings will trigger in your system. The login and the emails will be sent with your branding.
|
||||
|
||||
## Settings
|
||||
|
||||

|
||||
|
||||
### Logo
|
||||
|
||||
Upload your logo for the chosen theme, as soon as it is uploaded the preview on the right side of the screen should show it.
|
||||
|
||||
### Colors
|
||||
|
||||
In the next part you can configure your colors.
|
||||
Background color is self-explanatory, the primary color will be used for buttons, links and some highlights.
|
||||
The warn color is used for all the error messages and warnings and the font color for texts.
|
||||
|
||||
### Font
|
||||
|
||||
Last step to apply to your branding is the font upload.
|
||||
The best way is to upload a ttf file after a successful upload you will see it in the font part, but not in the preview.
|
||||
|
||||
### Advanced Settings
|
||||
|
||||
In the advanced behavior you can choose if the loginname suffix (domain e.g [email protected]) should be shown in the loginname screen or not and if the “ZITADEL watermark” should be hidden.
|
||||
|
||||
## Trigger the private labeling for the login
|
||||
|
||||
If you like to trigger your settings for your applications you have different possibilities.
|
||||
|
||||
### 1. Primary Domain Scope
|
||||
|
||||
Send a [reserved scope](/apis/openidoauth/scopes) with your [authorization request](../../integrate/login/oidc/login-users) to trigger your organization.
|
||||
The primary domain scope will restrict the login to your organization, so only users of your own organization will be able to login.
|
||||
|
||||
You can use our [OpenID Authentication Request Playground](https://zitadel.com/playgrounds/oidc) to learn more about how to trigger an [organization's policies and branding](https://zitadel.com/playgrounds/oidc#organization-policies-and-branding).
|
||||
|
||||
### 2. Setting on your Project
|
||||
|
||||
Set the private labeling setting on your project to define which branding should trigger.
|
||||
|
||||
## Reset to default
|
||||
|
||||
If you don't like your customization anymore click the "reset policy" button.
|
||||
All your settings will be removed and the default settings of the system will trigger.
|
||||
@@ -0,0 +1,167 @@
|
||||
---
|
||||
title: SMS, SMTP and HTTP Provider for Notifications
|
||||
sidebar_label: Notification Providers
|
||||
---
|
||||
|
||||
ZITADEL can send messages to users via different notification providers, such as SMS, SMTP, or Webhook (HTTP Provider).
|
||||
While you can add multiple providers to different channels, messages will only be delivered via the active provider.
|
||||
Message and notification texts can be [customized](./texts) for an instance or for each organization.
|
||||
|
||||
## SMS providers
|
||||
|
||||
ZITADEL integrates with Twilio as SMS provider.
|
||||
|
||||
## SMTP providers
|
||||
|
||||
For easy configuration, there are some integration templates available such as:
|
||||
|
||||
- Amazon SES
|
||||
- Mailgun
|
||||
- Mailjet
|
||||
- SendGrid
|
||||
- ...
|
||||
|
||||
Aside from those, it is also possible to configure a generic SMTP provider. With a generic SMTP provider you specify what
|
||||
the SMTP server, username and what kind of auth method you want to use. Currently, the Console only supports plain auth.
|
||||
However, with [the API's](https://zitadel.com/docs/apis/resources/admin/admin-service-add-email-provider-smtp) you can
|
||||
configure XOAUTH2 as well.
|
||||
|
||||
<Callout title="Default Provider ZITADEL Cloud">
|
||||
A default SMTP provider is configured for ZITADEL Cloud customers.
|
||||
This provider meant for development and testing purposes and you must replace this provider with your custom SMTP provider for production use cases to guarantee security and reliability of your service.
|
||||
</Callout>
|
||||
|
||||
## Webhook / HTTP provider
|
||||
|
||||
Webhook (HTTP Provider) allows you to fully customize the messages and use integrate with any provider or custom solution to deliver the messages to users.
|
||||
A provider with HTTP type will send the messages and the data to a pre-defined webhook as JSON.
|
||||
|
||||
### Configuring a HTTP provider
|
||||
|
||||
<Tabs>
|
||||
<Tab value="sms" label="SMS" default>
|
||||
|
||||
First [add a new SMS Provider of type HTTP](/reference/api/admin/zitadel.admin.v1.AdminService.AddSMSProviderHTTP) to create a new HTTP provider that can be used to send SMS messages:
|
||||
|
||||
```bash
|
||||
curl -L 'https://${CUSTOM_DOMAIN}/admin/v1/sms/http' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Authorization: Bearer ${TOKEN}' \
|
||||
-d '{
|
||||
"endpoint": "http://relay.example.com/provider",
|
||||
"description": "provider description"
|
||||
}'
|
||||
```
|
||||
|
||||
Where `endpoint` defines the Webhook endpoint to which the data should be sent to.
|
||||
The result will contain an ID of the provider that we need in the next step.
|
||||
|
||||
You can configure multiple SMS providers at the same time.
|
||||
To use the HTTP provider you need to [activate the SMS provider](/reference/api/admin/zitadel.admin.v1.AdminService.ActivateSMSProvider):
|
||||
|
||||
```bash
|
||||
curl -L 'https://${CUSTOM_DOMAIN}/admin/v1/sms/:id/_activate' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Authorization: Bearer ${TOKEN}' \
|
||||
-d '{}'
|
||||
```
|
||||
|
||||
The `id` is the provider's ID from the previous step.
|
||||
|
||||
See full API reference for [SMS Providers](/reference/api/admin) for more details.
|
||||
|
||||
</Tab>
|
||||
<Tab value="email" label="Email">
|
||||
|
||||
First [add a new Email Provider of type HTTP](/reference/api/admin/zitadel.admin.v1.AdminService.AddEmailProviderHTTP) to create a new HTTP provider that can be used to send Email messages:
|
||||
|
||||
```bash
|
||||
curl -L 'https://${CUSTOM_DOMAIN}/admin/v1/email/http' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Authorization: Bearer ${TOKEN}' \
|
||||
-d '{
|
||||
"endpoint": "http://relay.example.com/provider",
|
||||
"description": "provider description"
|
||||
}'
|
||||
```
|
||||
|
||||
Where `endpoint` defines the Webhook endpoint to which the data should be sent to.
|
||||
The result will contain an ID of the provider that we need in the next step.
|
||||
|
||||
You can configure multiple Email providers at the same time.
|
||||
To use the HTTP provider you need to [activate the Email provider](/reference/api/admin/zitadel.admin.v1.AdminService.ActivateEmailProvider):
|
||||
|
||||
```bash
|
||||
curl -L 'https://${CUSTOM_DOMAIN}/admin/v1/email/:id/_activate' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Authorization: Bearer ${TOKEN}' \
|
||||
-d '{}'
|
||||
```
|
||||
|
||||
The `id` is the provider's ID from the previous step.
|
||||
|
||||
See full API reference for [Email Providers](/reference/api/admin/zitadel.admin.v1.AdminService.ListEmailProviders) for more details.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### HTTP provider payload
|
||||
|
||||
In case of the Twilio and Email providers, the messages will be sent as before, in case of the HTTP providers the content of the messages is the same but as a HTTP call.
|
||||
|
||||
Here an example of the body of an payload sent via Email HTTP provider:
|
||||
|
||||
```json
|
||||
{
|
||||
"contextInfo": {
|
||||
"eventType": "user.human.initialization.code.added",
|
||||
"provider": {
|
||||
"id": "285181292935381355",
|
||||
"description": "test"
|
||||
},
|
||||
"recipientEmailAddress": "[email protected]"
|
||||
},
|
||||
"templateData": {
|
||||
"title": "Zitadel - Initialize User",
|
||||
"preHeader": "Initialize User",
|
||||
"subject": "Initialize User",
|
||||
"greeting": "Hello GivenName FamilyName,",
|
||||
"text": "This user was created in Zitadel. Use the username Username to login. Please click the button below to finish the initialization process. (Code 0M53RF) If you didn't ask for this mail, please ignore it.",
|
||||
"url": "http://example.zitadel.com/ui/login/user/init?authRequestID=\u0026code=0M53RF\u0026loginname=Username\u0026orgID=275353657317327214\u0026passwordset=false\u0026userID=285181014567813483",
|
||||
"buttonText": "Finish initialization",
|
||||
"primaryColor": "#5469d4",
|
||||
"backgroundColor": "#fafafa",
|
||||
"fontColor": "#000000",
|
||||
"fontFamily": "-apple-system, BlinkMacSystemFont, Segoe UI, Lato, Arial, Helvetica, sans-serif",
|
||||
"footerText": "InitCode.Footer"
|
||||
},
|
||||
"args": {
|
||||
"changeDate": "2024-09-16T10:58:50.73237+02:00",
|
||||
"code": "0M53RF",
|
||||
"creationDate": "2024-09-16T10:58:50.73237+02:00",
|
||||
"displayName": "GivenName FamilyName",
|
||||
"firstName": "GivenName",
|
||||
"lastEmail": "[email protected]",
|
||||
"lastName": "FamilyName",
|
||||
"lastPhone": "+41791234567",
|
||||
"loginNames": [
|
||||
"Username"
|
||||
],
|
||||
"nickName": "",
|
||||
"preferredLoginName": "Username",
|
||||
"userName": "Username",
|
||||
"verifiedEmail": "[email protected]",
|
||||
"verifiedPhone": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There are 3 elements to this message:
|
||||
|
||||
- `contextInfo`, with information on why this message is sent like the Event, which Email or SMS provider is used and which recipient should receive this message
|
||||
- `templateData`, with all texts and format information which can be used with a template to produce the desired message
|
||||
- `args`, with the information provided to the user which can be used in the message to customize
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Feature Restrictions
|
||||
---
|
||||
|
||||
New self-hosted and [ZITADEL Cloud instances](https://zitadel.com/signin) are unrestricted by default.
|
||||
Self-hosters can change this default using the DefaultInstance.Restrictions configuration section.
|
||||
Users with the role IAM_OWNER can change the restrictions of their instance using the [Feature Restrictions Admin API](/reference/api/admin).
|
||||
Currently, the following restrictions are available:
|
||||
|
||||
- *Disallow public organization registrations* - If restricted, only users with the role IAM_OWNERS can create new organizations. The endpoint */ui/login/register/org* returns HTTP status 404 on GET requests, and 409 on POST requests.
|
||||
- *AllowedLanguages* - The following rules apply if languages are restricted:
|
||||
- Only allowed languages are listed in the OIDC discovery endpoint */.well-known/openid-configuration*.
|
||||
- Login UI texts are only rendered in allowed languages.
|
||||
- Notification message texts are only rendered in allowed languages.
|
||||
- Custom Texts can be created for disallowed languages as long as ZITADEL supports that language. Therefore, all texts can be customized before allowing a language.
|
||||
|
||||
Feature restrictions for an instance are intended to be configured by a user that is managed within that instance.
|
||||
However, if you are self-hosting and need to control your virtual instances usage, [read about the APIs for limits and quotas](/self-hosting/manage/usage_control) that are intended to be used by system users.
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Customized Texts
|
||||
---
|
||||
|
||||
You are able to customize the texts used from ZITADEL. This is possibly on the instance or organization level.
|
||||
|
||||
## Message Texts
|
||||
|
||||
Sometimes the users will get an email or phone message from ZITADEL (e.g Password Reset Request).
|
||||
ZITADEL already has some good standard texts, but maybe you would like to customize it for your organization.
|
||||
|
||||
Go to the message text policy on your organization and you will find the different kinds of messages that are sent from ZITADEL.
|
||||
Choose the template and the language you like to edit.
|
||||
You can now change all the texts from a message.
|
||||
As soon as you click into a input field you will see some attribute chips below the field.
|
||||
These are the parameters you can include on this specific message.
|
||||
|
||||

|
||||
|
||||
## Login Texts
|
||||
|
||||
Like the message texts you are also able to change the texts on the login interface.
|
||||
First choose the screen and the language you like to edit.
|
||||
You will see the default texts in the input field and you can overwrite them by typing into the box.
|
||||
|
||||

|
||||
|
||||
## Reset to default
|
||||
|
||||
If you don't like your customization anymore click the "reset policy" button.
|
||||
All your settings will be removed and the default settings of the system will trigger.
|
||||
|
||||
## Internationalization / i18n
|
||||
|
||||
ZITADEL is available in the following languages
|
||||
|
||||
- German (de)
|
||||
- English (en)
|
||||
- Spanish (es)
|
||||
- French (fr)
|
||||
- Indonesian (id)
|
||||
- Italian (it)
|
||||
- 日本語 (ja)
|
||||
- Polish(pl)
|
||||
- 简体中文(zh)
|
||||
- Bulgarian (bg)
|
||||
- Portuguese (pt)
|
||||
- Macedonian (mk)
|
||||
- Czech (cs)
|
||||
- Russian (ru)
|
||||
- Dutch (nl)
|
||||
- Swedish (sv)
|
||||
- Hungarian (hu)
|
||||
- 한국어 (ko)
|
||||
- Romanian (ro)
|
||||
- Turkish (tr)
|
||||
- Ukrainian (uk)
|
||||
- Arabic (ar)
|
||||
|
||||
A language is displayed based on your agent's language header.
|
||||
If a users language header doesn't match any of the supported or [restricted](#restrict-languages) languages, the instances default language will be used.
|
||||
|
||||
If you need support for a specific language we highly encourage you to [contribute translation files](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md) for the missing language.
|
||||
|
||||
## Restrict Languages
|
||||
|
||||
If you only want to enable a subset of the supported languages, you can configure the languages you'd like to allow using the [restrictions API](./restrictions).
|
||||
The login UI and notification messages are only rendered in one of the allowed languages and fallback to the instances default language.
|
||||
Also, the instances OIDC discovery endpoint will only list the allowed languages in the *ui_locales_supported* field.
|
||||
|
||||
All language settings are also configurable in the management consoles *Languages* default settings.
|
||||
|
||||

|
||||
@@ -0,0 +1,227 @@
|
||||
---
|
||||
title: User Metadata
|
||||
---
|
||||
|
||||
This guide shows you how to request metadata from a user.
|
||||
ZITADEL offers multiple methods to retrieve metadata.
|
||||
Pick the one that works best for your solution.
|
||||
|
||||
## Use cases for metadata
|
||||
|
||||
Typical use cases for user metadata include:
|
||||
|
||||
- Link the user to an internal identifier (eg, userId, contract number, etc.)
|
||||
- Save custom user data when registering a user
|
||||
- Route upstream traffic based on user attributes
|
||||
|
||||
## Before you start
|
||||
|
||||
Before you start you need to add some metadata to an existing user.
|
||||
You can do so by using [Console](../console/users) or [setting user metadata](/reference/api/management/zitadel.management.v1.ManagementService.SetUserMetadata) through the management API.
|
||||
|
||||
Most of the methods below require you to login with the correct user while setting some scopes.
|
||||
Make sure you pick the right user when logging into the test application.
|
||||
Use the [OIDC authentication request playground](https://zitadel.com/playgrounds/oidc) or the configuration of an [example client](/sdk-examples/introduction) to set the required scopes and receive a valid access token.
|
||||
|
||||
<Callout title="Getting a token">
|
||||
In case you want to test out different settings configure an application with code flow (PKCE).
|
||||
Grab the code from the url parameter after a successful login and exchange the code for tokens by calling the [token endpoint](/apis/openidoauth/endpoints#token-endpoint).
|
||||
You will find more information in our guides on how to [authenticate users](/guides/integrate/login/oidc/login-users).
|
||||
</Callout>
|
||||
|
||||
## Use tokens to get user metadata
|
||||
|
||||
Use one of these methods to get the metadata for the currently logged in user.
|
||||
|
||||
In case you want to manage metadata for other users than the currently logged in user, then you must use the [management service](#manage-user-metadata-through-the-management-api).
|
||||
|
||||
### Request metadata from userinfo endpoint
|
||||
|
||||
With the access token we can make a request to the [userinfo endpoint](/apis/openidoauth/endpoints#introspection-endpoint) to get the user's metadata.
|
||||
This method is the preferred method to retrieve a user's information in combination with opaque tokens, to insure that the token is valid.
|
||||
|
||||
You must pass the [reserved scope](/apis/openidoauth/scopes#reserved-scopes) `urn:zitadel:iam:user:metadata` in your authentication request.
|
||||
If you don't include this scope the response will contain user data, but not the metadata object.
|
||||
|
||||
Request the user information by calling the [userinfo endpoint](/apis/openidoauth/endpoints#introspection-endpoint):
|
||||
|
||||
```bash
|
||||
curl --request GET \
|
||||
--url "https://${CUSTOM_DOMAIN}/oidc/v1/userinfo" \
|
||||
--header "Authorization: Bearer $ACCESS_TOKEN"
|
||||
```
|
||||
|
||||
Replace `$ACCESS_TOKEN` with your user's access token.
|
||||
|
||||
The response will look something like this
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "[email protected]",
|
||||
"email_verified": true,
|
||||
"family_name": "Runner",
|
||||
"given_name": "Road",
|
||||
"locale": "en",
|
||||
"name": "Road Runner",
|
||||
"preferred_username": "[email protected]",
|
||||
"sub": "166.....729",
|
||||
"updated_at": 1655467738,
|
||||
//highlight-start
|
||||
"urn:zitadel:iam:user:metadata": {
|
||||
"ContractNumber": "MTIzNA"
|
||||
}
|
||||
//highlight-end
|
||||
}
|
||||
```
|
||||
|
||||
You can grab the metadata from the reserved claim `"urn:zitadel:iam:user:metadata"` as key-value pairs.
|
||||
Note that the values are base64 encoded.
|
||||
So the value `MTIzNA` decodes to `1234`.
|
||||
|
||||
### Send metadata inside the ID token
|
||||
|
||||
You might want to include metadata directly into the ID Token.
|
||||
For that you need to enable "User Info inside ID Token" in your application's settings.
|
||||
|
||||

|
||||
|
||||
Now request a new token from ZITADEL by logging in with the user that has metadata attached.
|
||||
Make sure you log into the correct client/application where you enabled the settings.
|
||||
|
||||
The result will give you something like:
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token": "jZuRixKQTVecEjKqw...kc3G4",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 43199,
|
||||
"id_token": "ey...Ww"
|
||||
}
|
||||
```
|
||||
|
||||
When you decode the value of `id_token`, then the response will include the metadata claim:
|
||||
|
||||
```json
|
||||
{
|
||||
"amr": ["password", "pwd", "mfa", "otp"],
|
||||
"at_hash": "lGIblkTr8faHz2zd0oTddA",
|
||||
"aud": [
|
||||
"170086824411201793@portal",
|
||||
"209806276543185153@portal",
|
||||
"170086774599581953"
|
||||
],
|
||||
"auth_time": 1687418556,
|
||||
"azp": "170086824411201793@portal",
|
||||
"c_hash": "dA3wre4ytCJCn11f7cIm0A",
|
||||
"client_id": "1700...1793@portal",
|
||||
"email": "[email protected]",
|
||||
"email_verified": true,
|
||||
"exp": 1687422272,
|
||||
"family_name": "Runner",
|
||||
"given_name": "Road",
|
||||
"iat": 1687418672,
|
||||
"iss": "https://...-abcd.zitadel.cloud",
|
||||
"locale": null,
|
||||
"name": "Road Runner",
|
||||
"preferred_username": "[email protected]",
|
||||
"sub": "170848145649959169",
|
||||
"updated_at": 1658329554,
|
||||
//highlight-start
|
||||
"urn:zitadel:iam:user:metadata": {
|
||||
"ContractNumber": "MTIzNA"
|
||||
}
|
||||
//highlight-end
|
||||
}
|
||||
```
|
||||
|
||||
Note that the values are base64 encoded.
|
||||
So the value `MTIzNA` decodes to `1234`.
|
||||
|
||||
<Callout title="decoding the jwt token">
|
||||
Use a website like [jwt.io](https://jwt.io/) to decode the token.
|
||||
With jq installed you can also use `jq -R 'split(".") | .[1] | @base64d | fromjson' <<< $ID_TOKEN`
|
||||
</Callout>
|
||||
|
||||
### Request metadata from authentication API
|
||||
|
||||
You can use the authentication service to request and search for the user's metadata.
|
||||
|
||||
The introspection endpoint and the token endpoint in the examples above do not require a special scope to access.
|
||||
Yet when accessing the authentication service, you need to pass the [reserved scope](/apis/openidoauth/scopes#reserved-scopes) `urn:zitadel:iam:org:project:id:zitadel:aud` along with the authentication request.
|
||||
This scope allows the user to access ZITADEL's APIs, specifically the authentication API that we need for this method.
|
||||
Use the [OIDC authentication request playground](https://zitadel.com/playgrounds/oidc) or the configuration of an [example client](/sdk-examples/introduction) to set the required scopes and receive a valid access token.
|
||||
|
||||
<Callout title="Invalid audience">
|
||||
If you get the error "invalid audience (APP-Zxfako)", then you need to add the reserved scope `urn:zitadel:iam:org:project:id:zitadel:aud` to your authentication request.
|
||||
</Callout>
|
||||
|
||||
You can request the user's metadata with the [List My Metadata](/reference/api/auth/zitadel.auth.v1.AuthService.ListMyMetadata) method:
|
||||
|
||||
```bash
|
||||
curl -L -X POST "https://${CUSTOM_DOMAIN}/auth/v1/users/me/metadata/_search" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
--data-raw '{
|
||||
"query": {
|
||||
"offset": "0",
|
||||
"limit": 100,
|
||||
"asc": true
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"keyQuery": {
|
||||
"key": "${METADATA_KEY}",
|
||||
"method": "TEXT_QUERY_METHOD_EQUALS"
|
||||
}
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
Replace `${ACCESS_TOKEN}` with your user's access token.
|
||||
Replace `${CUSTOM_DOMAIN}` with your ZITADEL instance's url.
|
||||
Replace `${METADATA_KEY}` with they key you want to search for (f.e. "ContractNumber")
|
||||
|
||||
<Callout title="Get all metadata">
|
||||
You can omit the queries array to retrieve all metadata key-value pairs.
|
||||
</Callout>
|
||||
|
||||
An example response for your search looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"details": {
|
||||
"totalResult": "1",
|
||||
"processedSequence": "2935",
|
||||
"viewTimestamp": "2023-06-21T16:01:52.829838Z"
|
||||
},
|
||||
"result": [
|
||||
{
|
||||
"details": {
|
||||
"sequence": "409",
|
||||
"creationDate": "2022-08-04T09:09:06.259324Z",
|
||||
"changeDate": "2022-08-04T09:09:06.259324Z",
|
||||
"resourceOwner": "170086363054473473"
|
||||
},
|
||||
"key": "ContractNumber",
|
||||
"value": "MTIzNA"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Register user with custom metadata
|
||||
|
||||
When you build your own registration UI you have the possibility to have custom fields and add them to the metadata of your user.
|
||||
Learn everything about how to build your own registration UI [here](/guides/integrate/onboarding/end-users#build-your-own-registration-form).
|
||||
|
||||
## Manage user metadata through the management API
|
||||
|
||||
The previous methods allowed you to retrieve metadata only for the `sub` in the access token.
|
||||
In case you want to get the metadata for another user, you need to use the management service.
|
||||
The user that calls the management service must have [manager permissions](/guides/manage/console/managers).
|
||||
A user can be either a human user or a service user.
|
||||
|
||||
You can get [metadata of a user filtered by your query](/apis/resources/mgmt/management-service-list-user-metadata) or [get a metadata object from a user by a specific key](/apis/resources/mgmt/management-service-get-user-metadata).
|
||||
The management service allows you to set and delete metadata, see the [API documentation for users](/reference/api/user).
|
||||
Reference in New Issue
Block a user