mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-01 03:52:14 +00:00
## 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]>
228 lines
8.5 KiB
Plaintext
228 lines
8.5 KiB
Plaintext
---
|
|
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).
|