From 376c3a3fff6e654d84ab31e4e45ccfff195ff861 Mon Sep 17 00:00:00 2001 From: mffap Date: Mon, 25 Mar 2024 11:30:43 +0200 Subject: [PATCH] docs(integrate): improve service user authentication (#7492) * service users * wip * wip * wip * lower case titles * wip * wip * private key jwt * wip * wip * token introspection * zitadel apis * expiration * replace mermaid with svg * Apply suggestions from code review Co-authored-by: Fabi * Apply suggestions from code review * boulevard of broken links * my hrefs will go on * docs: add token type to client credential * Update docs/docs/apis/introduction.mdx Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/service-users/authenticate-service-users.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/service-users/authenticate-service-users.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/service-users/authenticate-service-users.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/service-users/private-key-jwt.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/service-users/private-key-jwt.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/service-users/authenticate-service-users.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/service-users/client-credentials.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/service-users/client-credentials.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/_accessing_zitadel_api.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * Update docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md Co-authored-by: Florian Forster * docs: add token type to client credential --------- Co-authored-by: Fabi Co-authored-by: Fabienne Co-authored-by: Florian Forster Co-authored-by: Livio Spring --- docs/docs/apis/introduction.mdx | 17 +- docs/docs/concepts/features/audit-trail.md | 4 +- docs/docs/concepts/features/selfservice.md | 2 +- .../docs/examples/secure-api/python-flask.mdx | 4 +- .../guides/integrate/access-zitadel-apis.md | 81 ------ .../guides/integrate/client-credentials.md | 88 ------- .../guides/integrate/external-audit-log.md | 2 +- docs/docs/guides/integrate/pat.md | 46 ---- docs/docs/guides/integrate/private-key-jwt.md | 157 ------------ .../guides/integrate/retrieve-user-roles.md | 2 +- .../authenticate-service-users.md | 137 ++++++++++ .../service-users/client-credentials.md | 104 ++++++++ .../service-users/personal-access-token.md | 70 ++++++ .../service-users/private-key-jwt.md | 213 ++++++++++++++++ .../integrate/token-introspection/index.md | 39 +++ .../token-introspection/private-key-jwt.mdx | 2 +- .../zitadel-apis/_accessing_zitadel_api.md | 75 ++++++ .../zitadel-apis/access-zitadel-apis.md | 237 ++++++++++++++++++ .../access-zitadel-system-api.md | 1 + .../integrate/{ => zitadel-apis}/event-api.md | 4 +- .../example-zitadel-api-with-dot-net.md} | 10 +- .../example-zitadel-api-with-go.md} | 10 +- docs/docs/guides/manage/terraform/basics.md | 2 +- docs/docs/guides/migrate/sources/keycloak.md | 6 +- docs/docs/guides/migrate/sources/zitadel.md | 4 +- .../solution-scenarios/restrict-console.mdx | 2 +- docs/docs/imports/_code-flow-chart.md | 2 +- .../docs/self-hosting/manage/usage_control.md | 2 +- docs/docs/support/advisory/a10007.md | 2 +- docs/sidebars.js | 61 ++--- .../img/console_service_user_tokentype.png | Bin 0 -> 173063 bytes .../sequence-private-key-jwt.svg | 1 + docs/vercel.json | 11 +- 33 files changed, 952 insertions(+), 446 deletions(-) delete mode 100644 docs/docs/guides/integrate/access-zitadel-apis.md delete mode 100644 docs/docs/guides/integrate/client-credentials.md delete mode 100644 docs/docs/guides/integrate/pat.md delete mode 100644 docs/docs/guides/integrate/private-key-jwt.md create mode 100644 docs/docs/guides/integrate/service-users/authenticate-service-users.md create mode 100644 docs/docs/guides/integrate/service-users/client-credentials.md create mode 100644 docs/docs/guides/integrate/service-users/personal-access-token.md create mode 100644 docs/docs/guides/integrate/service-users/private-key-jwt.md create mode 100644 docs/docs/guides/integrate/token-introspection/index.md create mode 100644 docs/docs/guides/integrate/zitadel-apis/_accessing_zitadel_api.md create mode 100644 docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md rename docs/docs/guides/integrate/{ => zitadel-apis}/access-zitadel-system-api.md (99%) rename docs/docs/guides/integrate/{ => zitadel-apis}/event-api.md (98%) rename docs/docs/{examples/call-zitadel-api/dot-net.md => guides/integrate/zitadel-apis/example-zitadel-api-with-dot-net.md} (94%) rename docs/docs/{examples/call-zitadel-api/go.md => guides/integrate/zitadel-apis/example-zitadel-api-with-go.md} (89%) create mode 100644 docs/static/img/console_service_user_tokentype.png create mode 100644 docs/static/img/guides/integrate/service-users/sequence-private-key-jwt.svg diff --git a/docs/docs/apis/introduction.mdx b/docs/docs/apis/introduction.mdx index 7502b20be6..a4220abba5 100644 --- a/docs/docs/apis/introduction.mdx +++ b/docs/docs/apis/introduction.mdx @@ -14,8 +14,21 @@ The [OpenID Connect & OAuth endpoints](/docs/apis/openidoauth/endpoints) and [SA ## Authentication & authorization +### Authentication for human users (interactive) + ZITADEL implements industry standards such as OpenID Connect, OAuth 2.0, or SAML for authentication. -Please refer to our guides how to [authenticate users](/docs/guides/integrate/login/login-users) through an interactive authentication process and how to [authenticate service users](/docs/guides/integrate/serviceusers) with a programmatic authentication. +Please refer to our guides how to [authenticate users](/docs/guides/integrate/login/login-users) through an interactive authentication process. + +For user authentication on devices with limited accessibility (eg, SmartTV, Smart Watch etc.) use the [device authorization grant](/docs/guides/integrate/login/oidc/device-authorization). + +Additionally, you can use the [session API](../apis/resources/session_service/) to authenticate users, for example by building a [custom login UI](/docs/guides/integrate/login-ui/). + +### Authenticate service users and machines + +Service users allow for machine-to-machine (M2M) communication. +Follow the guides to learn how to [authenticate service users](/docs/guides/integrate/service-users/authenticate-service-users). + +Accessing the ZITADEL APIs through a service user might require additional steps, please follow the guide on how to [access ZITADEL APIs](../guides/integrate/zitadel-apis/access-zitadel-apis) to include the correct audience scope in your requests. ### OpenID Connect & OAuth @@ -163,7 +176,7 @@ API Reference: This API is intended to manage the different ZITADEL instances within the system. -Checkout the guide how to [access the ZITADEL System API](/guides/integrate/access-zitadel-system-api). +Checkout the guide how to [access the ZITADEL System API](/docs/guides/integrate/zitadel-apis/access-zitadel-system-api).
diff --git a/docs/docs/concepts/features/audit-trail.md b/docs/docs/concepts/features/audit-trail.md index bad91b01d0..a4c79e003e 100644 --- a/docs/docs/concepts/features/audit-trail.md +++ b/docs/docs/concepts/features/audit-trail.md @@ -35,10 +35,10 @@ Go to your instance settings and then click on the Tab **Events** to open the Ev Since everything that is available in Console can also be called with our APIs, you can access all events and audit data trough our APIs: -- [Event API Guide](/docs/guides/integrate/event-api) +- [Event API Guide](/docs/guides/integrate/zitadel-apis/event-api) - [API Documentation](/docs/category/apis/resources/admin/events) -Access to the API is possible with a [Service User](/docs/guides/integrate/serviceusers) account, allowing you to integrate the events with your own business logic. +Access to the API is possible with a [Service User](/docs/guides/integrate/service-users/authenticate-service-users) account, allowing you to integrate the events with your own business logic. ## Using logs in external systems diff --git a/docs/docs/concepts/features/selfservice.md b/docs/docs/concepts/features/selfservice.md index bfd64890d4..4493687570 100644 --- a/docs/docs/concepts/features/selfservice.md +++ b/docs/docs/concepts/features/selfservice.md @@ -68,7 +68,7 @@ Given an external identity provider is configured on the instance or on the orga ### Machines Machine accounts can't use an interactive login but require other means of authentication, such as privately-signed JWT or personal access tokens. -Read more about [Service Users](/guides/integrate/serviceusers) and recommended [OpenID Connect Flows](/guides/integrate/login/oidc/oauth-recommended-flows#different-client-profiles). +Read more about [Service Users](/guides/integrate/service-users/authenticate-service-users) and recommended [OpenID Connect Flows](/guides/integrate/login/oidc/oauth-recommended-flows#different-client-profiles). ## Logout diff --git a/docs/docs/examples/secure-api/python-flask.mdx b/docs/docs/examples/secure-api/python-flask.mdx index 6b83049a16..1263c945e9 100644 --- a/docs/docs/examples/secure-api/python-flask.mdx +++ b/docs/docs/examples/secure-api/python-flask.mdx @@ -16,7 +16,7 @@ The API will validate the access token on the [introspect endpoint](https://zita The API application uses [Client Secret Basic](https://zitadel.com/docs/apis/openidoauth/authn-methods#client-secret-basic) to authenticate against ZITADEL and access the introspection endpoint. You can use any valid access_token from a user or service account to send requests to the example API. -In this example we will use a service account with a [personal access token](https://zitadel.com/docs/guides/integrate/pat) which can be used directly to access the example API. +In this example we will use a service account with a [personal access token](https://zitadel.com/docs/guides/integrate/service-users/personal-access-token) which can be used directly to access the example API. ## Running the example @@ -191,7 +191,7 @@ CLIENT_SECRET = "NVAp70IqiGmJldbS...." ![Create a service user](/img/python-flask/3.png) -1. Create a service user and a Personal Access Token (PAT) for that user by following [this guide](https://zitadel.com/docs/guides/integrate/pat#create-a-service-user-with-a-pat). +1. Create a service user and a Personal Access Token (PAT) for that user by following [this guide](https://zitadel.com/docs/guides/integrate/service-users/personal-access-token#create-a-service-user-with-a-pat). 2. To enable authorization, follow [this guide](https://zitadel.com/docs/guides/manage/console/roles) to create a role `read:messages` on your project. 3. Next, create an authorization for the service user you created by adding the role `read:messages` to the user. Follow this [guide](https://zitadel.com/docs/guides/manage/console/roles#authorizations) for more information on creating an authorization. diff --git a/docs/docs/guides/integrate/access-zitadel-apis.md b/docs/docs/guides/integrate/access-zitadel-apis.md deleted file mode 100644 index 545e9d75a1..0000000000 --- a/docs/docs/guides/integrate/access-zitadel-apis.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Access ZITADEL APIs ---- - -:::note -This guide focuses on the Admin, Auth and Management APIs. To access the ZITADEL System API, please checkout [this guide](./access-zitadel-system-api). -::: - -## ZITADEL Managers - -ZITADEL Managers are Users who have permission to manage ZITADEL itself. There are some different levels for managers. - -- **IAM Managers**: This is the highest level. Users with IAM Manager roles are able to manage the whole instance. -- **Org Managers**: Managers in the Organization Level are able to manage everything within the granted Organization. -- **Project Mangers**: In this level the user is able to manage a project. -- **Project Grant Manager**: The project grant manager is for projects, which are granted of another organization. - -On each level we have some different Roles. Here you can find more about the different roles: [ZITADEL Manager Roles](/guides/manage/console/managers#roles) - -## Add ORG_OWNER to Service User - -Make sure you have a Service User with a Key. (For more detailed informations about creating a service user go to [Service User](serviceusers)) - -1. Navigate to Organization Detail -2. Click the **+** button in the right part of console, in the managers part of details -3. Search the user and select it -4. Choose the role ORG_OWNER - -![Add Org Manager](/img/console_org_manager_add.gif) - -## Authenticating a service user - -In ZITADEL we use the `urn:ietf:params:oauth:grant-type:jwt-bearer` (**“JWT bearer token with private key”**, [RFC7523](https://tools.ietf.org/html/rfc7523)) authorization grant for this non-interactive authentication. -This is already described in the [Service User](./serviceusers), so make sure you follow this guide. - -### Request an OAuth token, with audience for ZITADEL - -With the encoded JWT from the prior step, you will need to craft a POST request to ZITADEL's token endpoint: - -To access the ZITADEL APIs you need the ZITADEL Project ID in the audience of your token. -This is possible by sending a custom scope for the audience. More about [Custom Scopes](/apis/openidoauth/scopes) - -Use the scope `urn:zitadel:iam:org:project:id:zitadel:aud` to include the ZITADEL project id in your audience - -```bash -curl --request POST \ - --url $CUSTOM-DOMAIN/oauth/v2/token \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --data grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \ - --data scope='openid profile email urn:zitadel:iam:org:project:id:zitadel:aud' \ - --data assertion=eyJ0eXAiOiJKV1QiL... -``` - -- `grant_type` must be set to `urn:ietf:params:oauth:grant-type:jwt-bearer` -- `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid`. For this example, please include `profile` and `email` -- `assertion` is the encoded value of the JWT that was signed with your private key from the prior step - -You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. - -```bash -HTTP/1.1 200 OK -Content-Type: application/json - -{ - "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", - "token_type": "Bearer", - "expires_in": 43199 -} -``` - -With this token you are allowed to access the [ZITADEL APIs](/apis/introduction) . - -## Summary - -- Grant a user for ZITADEL -- Because there is no interactive logon, you need to use a JWT signed with your private key to authorize the user -- With a custom scope (`urn:zitadel:iam:org:project:id:zitadel:aud`) you can access ZITADEL APIs - -Where to go from here: - -- [ZITADEL API Documentation](/apis/introduction) diff --git a/docs/docs/guides/integrate/client-credentials.md b/docs/docs/guides/integrate/client-credentials.md deleted file mode 100644 index bd0ccf85f3..0000000000 --- a/docs/docs/guides/integrate/client-credentials.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: Client Credentials with Service Users ---- - -This is a guide on how to use Client Credentials with service users in ZITADEL. You can read more about users [here](/concepts/structure/users.md). - -In ZITADEL, the Client Credentials grant can be used for this non-interactive authentication as alternative to the [JWT profile authentication](serviceusers). - -## Create a Service User with a Secret - -1. Navigate to Service Users -2. Click on **New** -3. Enter a username and a display name -4. Click on **Create** -5. Open **Actions** in the top right corner and click on **Generate Client Secret** -6. Copy the **ClientID** and **ClientSecret** from the dialog - -:::note -Be sure to copy in particular the ClientSecret. You won't be able to retrieve it again. -If you lose it, you will have to generate a new one. -::: - -![Create new service user](/img/console_serviceusers_secret.gif) - -## Grant role for ZITADEL - -To be able to access the ZITADEL APIs your service user needs permissions to ZITADEL. - -1. Go to the detail page of your organization -2. Click in the top right corner the "+" button -3. Search for your service user -4. Give the user the role you need, for the example we choose Org Owner (More about [ZITADEL Permissions](/guides/manage/console/managers)) - -![Add org owner to service user](/img/guides/console-service-user-org-owner.gif) - -## Authenticating a service user - -In this step we will authenticate a service user and receive an access_token to use against the ZITADEL API. - -You will need to craft a POST request to ZITADEL's token endpoint: - -```bash -curl --request POST \ - --url https://$CUSTOM-DOMAIN/oauth/v2/token \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --header 'Authorization: Basic ${BASIC_AUTH}' \ - --data grant_type=client_credentials \ - --data scope='openid profile email urn:zitadel:iam:org:project:id:zitadel:aud' -``` - -* `grant_type` should be set to `client_credentials` -* `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid`. For this example, please include `profile`, `email` - and `urn:zitadel:iam:org:project:id:zitadel:aud`. The latter provides access to the ZITADEL API. - -You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. - -```bash -HTTP/1.1 200 OK -Content-Type: application/json - -{ - "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", - "token_type": "Bearer", - "expires_in": 43199 -} -``` - -## Call ZITADEL API with Token - -Because the received Token includes the `urn:zitadel:iam:org:project:id:zitadel:aud` scope, we can send it in your requests to the ZITADEL API as Authorization Header. -In this example we read the organization of the service user. - -```bash -curl --request GET \ - --url $CUSTOM-DOMAIN/management/v1/orgs/me \ - --header 'Authorization: Bearer ${TOKEN}' -``` - -## Summary - -* With service users you can secure machine-to-machine communication -* Client Credentials provide an alternative way to JWT Profile for service user authentication -* After successful authorization you can use an access token like for human users - -Where to go from here: - -* Management API -* Securing backend API diff --git a/docs/docs/guides/integrate/external-audit-log.md b/docs/docs/guides/integrate/external-audit-log.md index 9d2db89d80..93262d26f7 100644 --- a/docs/docs/guides/integrate/external-audit-log.md +++ b/docs/docs/guides/integrate/external-audit-log.md @@ -32,7 +32,7 @@ This API offers granular control through various filters, enabling you to: - **Target Aggregates**: Narrow down the data scope by filtering for events related to particular organizations, projects, or users. - **Define Time Frames**: Retrieve audit logs for precise time periods, allowing you to schedule data retrieval at desired intervals (e.g., hourly) and analyze activity within specific windows. -You can find a comprehensive guide on how to use the events API for different use cases here: [Get Events from ZITADEL](/docs/guides/integrate/event-api) +You can find a comprehensive guide on how to use the events API for different use cases here: [Get Events from ZITADEL](/docs/guides/integrate/zitadel-apis/event-api) ### Cockroach Change Data Capture diff --git a/docs/docs/guides/integrate/pat.md b/docs/docs/guides/integrate/pat.md deleted file mode 100644 index e3be879c26..0000000000 --- a/docs/docs/guides/integrate/pat.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: ZITADEL's Personal Access Tokens(PATs) -sidebar_label: Personal Access Tokens(PATs) ---- - - -A Personal Access Token (PAT) is a ready to use token which can be used as _Authorization_ header. -At the moment ZITADEL only allows PATs for machine accounts (service users). - -It is an alternative to the JWT profile authentication where the service user has a key to authenticate. Read more about that [here](serviceusers) - -## Create a Service User with a PAT - - -1. Navigate to Service Users -2. Click on **New** -3. Enter a user name and a display name -4. Click on the Personal Access Token menu point in the detail of your user -5. Click on **New** -6. You can either set an expiration date or leave it empty if you don't want it to expire -7. Copy the token from the dialog (You will not see this again) - -![Create new service user](/img/guides/console-service-user-pat.gif) - -## Grant role for ZITADEL - -To be able to access the ZITADEL APIs your service user needs permissions to ZITADEL. - -1. Go to the detail page of your organization -2. Click in the top right corner the "+" button -3. Search for your service user -4. Give the user the role you need, for the example we choose Org Owner (More about [ZITADEL Permissions](../manage/console/managers)) - -![Add org owner to service user](/img/guides/console-service-user-org-owner.gif) - - -## Call ZITADEL API with PAT - -Because the PAT is a ready to use Token, you can add it as Authorization Header and send it in your requests to the ZITADEL API. -In this example we read the organization of the service user. - -```bash -curl --request GET \ - --url $CUSTOM-DOMAIN/management/v1/orgs/me \ - --header 'Authorization: Bearer {PAT}' -``` \ No newline at end of file diff --git a/docs/docs/guides/integrate/private-key-jwt.md b/docs/docs/guides/integrate/private-key-jwt.md deleted file mode 100644 index 620293bddf..0000000000 --- a/docs/docs/guides/integrate/private-key-jwt.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: Service Users in ZITADEL -sidebar_label: Service Users ---- - -This is a guide on how to create service users in ZITADEL. You can read more about users [here](/concepts/structure/users.md). - -## Create a Service User - -1. Navigate to Service Users -2. Click on **New** -3. Enter a user name and a display name - -![Create new service user](/img/console_serviceusers_create.gif) - -## Authenticating a service user - -In ZITADEL we use the `urn:ietf:params:oauth:grant-type:jwt-bearer` (**“JWT bearer token with private key”**, [RFC7523](https://tools.ietf.org/html/rfc7523)) authorization grant for this non-interactive authentication. - -You need to follow these steps to authenticate a service user and receive an access token: - -1. Generate a private-public key pair in ZITADEL -2. Create a JSON Web Token (JWT) and sign with private key -3. With this JWT, request an OAuth token from ZITADEL - -With this token you can make subsequent requests, just like a human user. - -## Get an access token - -In this step we will authenticate a service user and receive an access_token to use against the API. - -> **Information:** Are you stuck? Don't hesitate to reach out to us on [Github Discussions](https://github.com/zitadel/zitadel/discussions) or [contact us](https://zitadel.com/contact/) privately. - -### 1. Generate a private-public key pair in ZITADEL - -Select your service user and in the section KEYS click **New**. Enter an optional expiration date and click **Add**. Make sure to download the json by clicking **Download**. - -:::note -If you specify an expiration date, note that the key will expire at midnight that day -::: - -![Create private key](/img/console_serviceusers_new_key.gif) - -The downloaded json should look something like outlined below. The value of `key` contains the _private_ key for your service account. Please make sure to keep this key securely stored and handle with care. The public key is automatically stored in ZITADEL. - -```json -{ - "type": "serviceaccount", - "keyId": "100509901696068329", - "key": "-----BEGIN RSA PRIVATE KEY----- [...] -----END RSA PRIVATE KEY-----\n", - "userId": "100507859606888466" -} -``` - -### 2. Create a JWT and sign with private key - -You need to create a JWT with the following header and payload and sign it with the RS256 algorithm. - -Header - -```json -{ - "alg": "RS256", - "kid": "100509901696068329" -} -``` - -Make sure to include `kid` in the header with the value of `keyId` from the downloaded JSON. - -Payload - -```json -{ - "iss": "100507859606888466", - "sub": "100507859606888466", - "aud": "https://$CUSTOM-DOMAIN", - "iat": [Current UTC timestamp, e.g. 1605179982, max. 1 hour ago], - "exp": [UTC timestamp, e.g. 1605183582] -} -``` - -- `iss` represents the requesting party, i.e. the owner of the private key. In this case the value of `userId` from the downloaded JSON. -- `sub` represents the application. Set the value also to the value of `userId` -- `aud` must be ZITADEL's issuing domain -- `iat` is a unix timestamp of the creation signing time of the JWT, e.g. now and must not be older than 1 hour ago -- `exp` is the unix timestamp of expiry of this assertion - -Please refer to [JWT_with_Private_Key](/apis/openidoauth/authn-methods#jwt-with-private-key) in the documentation for further information. - -If you use Go, you might want to use the [provided tool](https://github.com/zitadel/zitadel-tools) to generate a JWT from the downloaded json. There are many [libraries](https://jwt.io/#libraries-io) to generate and sign JWT. - -### 3. With this JWT, request an OAuth token from ZITADEL - -With the encoded JWT from the prior step, you will need to craft a POST request to ZITADEL's token endpoint: - -```bash -curl --request POST \ - --url https:/$CUSTOM-DOMAIN/oauth/v2/token \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --data grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \ - --data scope='openid profile email' \ - --data assertion=eyJ0eXAiOiJKV1QiL... -``` - -If you want to access the ZITADEL API with this access token, you have to add `urn:zitadel:iam:org:project:id:zitadel:aud` to the list of scopes. - -- `grant_type` should be set to `urn:ietf:params:oauth:grant-type:jwt-bearer` -- `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid`. For this example, please include `profile` and `email` -- `assertion` is the encoded value of the JWT that was signed with your private key from the prior step - -You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. - -```bash -HTTP/1.1 200 OK -Content-Type: application/json - -{ - "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", - "token_type": "Bearer", - "expires_in": 43199 -} -``` - -### 4. Verify that you have a valid access token - -For this example let's call the userinfo endpoint to verify that our access token works. - -```bash -curl --request POST \ - --url $CUSTOM-DOMAIN/oidc/v1/userinfo \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --header 'Authorization: Bearer MtjHodGy4zxKylDOhg6kW90WeEQs2q...' -``` - -You should receive a response with your service user's information. - -```bash -HTTP/1.1 200 OK -Content-Type: application/json - -{ - "name": "MyServiceUser", - "preferred_username": "service_user@$CUSTOM-DOMAIN", - "updated_at": 1616417938 -} -``` - -## Summary - -- With service users you can secure machine-to-machine communication -- Because there is no interactive logon, you need to use a JWT signed with your private key to authorize the user -- After successful authorization you can use an access token like for human users - -Where to go from here: - -- Management API -- Securing backend API diff --git a/docs/docs/guides/integrate/retrieve-user-roles.md b/docs/docs/guides/integrate/retrieve-user-roles.md index 64793a07e6..1e97ef647a 100644 --- a/docs/docs/guides/integrate/retrieve-user-roles.md +++ b/docs/docs/guides/integrate/retrieve-user-roles.md @@ -32,7 +32,7 @@ You must first of all generate a token for the user. For human users, the typica How to generate a token: - [Generate tokens for human users](/docs/guides/integrate/login/oidc/login-users) -- [Generate tokens for service users](/docs/guides/integrate/serviceusers) +- [Generate tokens for service users](/docs/guides/integrate/service-users/authenticate-service-users) In order to access role information via the token you must include the right audience and the necessary role claims in the scope and/or select the required role settings in the ZITADEL console before requesting the token. diff --git a/docs/docs/guides/integrate/service-users/authenticate-service-users.md b/docs/docs/guides/integrate/service-users/authenticate-service-users.md new file mode 100644 index 0000000000..7ca961ae21 --- /dev/null +++ b/docs/docs/guides/integrate/service-users/authenticate-service-users.md @@ -0,0 +1,137 @@ +--- +title: Authenticate service users and client applications +sidebar_label: Authenticate service users +sidebar_position: 1 +--- + +This guide explains ZITADEL service users and their role in facilitating secure machine-to-machine communication within your applications. + +## What are Service Users? + +Service users in ZITADEL represent **non-human entities** within your system. +They are ideal for scenarios involving secure communication between applications, particularly when interacting with backend services or APIs. +Service users in combination with [Manager](/concepts/structure/managers) permissions are used to access ZITADEL's APIs, for example, to manage user resources. +Unlike regular human users, service users don't rely on traditional login methods (e.g., username/password) and require alternative authentication mechanisms. + +## Benefits of using Service Users + +### Enhanced security + +* **Principle of Least Privilege:** Grant service users only the minimum permissions they need, minimizing potential damage in case of compromise. +* **Distinct Credentials:** Avoid embedding sensitive credentials like API keys directly in code. Service user credentials can be rotated independently. + +### Segregated authorization + +Manage authorization for service users separately from human users, providing an extra layer of control. + +### API and backend access + +Service users offer a secure way to authenticate and access various API endpoints and protected backend services. + +You can [use service users to access ZITADEL APIs](../zitadel-apis/access-zitadel-apis), follow the guides to learn how to access the different ZITADEL APIs. +While you can define the scopes and required information in your requests for your applications API endpoints, when using the ZITADEL APIs, you must include the scope `urn:zitadel:iam:org:project:id:zitadel:aud` to gain access. + +### Improved auditability + +Actions performed by service users are clearly identifiable in logs, facilitating easier auditing and tracing. + +Using the [Event API](../zitadel-apis/event-api) you can use these logs for further analysis or to integrate the logs with [external SOC / SIEM](../external-audit-log) systems. + +## Authentication methods + +ZITADEL supports two primary authentication methods for service users: + +### Private key JWT authentication + +#### How private key JWT authentication works + +* Generate a private/public key pair associated with the service user. +* Sign JWTs with the private key. +* ZITADEL validates the signature using the service user's public key. +* JWTs can include expiration dates and scopes to control access. + +Follow our guide on using [private key JWT client authentication](./private-key-jwt) to get started authenticating service users and clients. + +#### Benefits of private key JWT authentication + +* **Decentralized Verification:** No need for constant server calls, improving performance and scalability. +* **Flexibility and Control:** Define scopes and expiration within the JWT itself for granular access control. +* **Stateless:** The server doesn't need to maintain a session state, simplifying server implementation. + +#### Drawbacks of private key JWT authentication + +* **Complexity:** Slightly more complex to implement compared to other methods, requiring knowledge of JWT and digital signing. +* **Revocation:** Invalidating a JWT before its expiry can be challenging; blacklisting mechanisms might be required. + +#### Security considerations when using private key JWT authentication + +* **Secure Key Storage:** The private key used for signing must be stored with the highest level of security. Compromise could allow attackers to forge tokens. +* **Short Expirations:** Implementing short expiration durations for JWTs helps limit the impact of stolen tokens. + +### Client credentials grant + +* Presents a client ID and client secret associated with the service user. +* Simpler than the JWT profile in specific scenarios. + +Follow our guide on using [client credentials grant](./client-credentials) to get started authenticating service users and clients. + +This method is still available in ZITADEL but is generally considered less secure than JWT due to: + +* **Centralized Validation:** Relies on the server to verify credentials for every request, potentially impacting performance and requiring more server resources. +* **Credentials Exposure:** Leaked client ID and secret could be used by attackers to impersonate the service user until rotation occurs. + +### Personal Access Tokens (PATs) + +* **Ready-to-use tokens:** Generated for specific service users and can be directly included in the authorization header of API requests. +* **Currently available only for machine users** (service users) and not regular human users. + +Follow our guide on using [personal access tokens](./personal-access-token) to get started authenticating service users and clients. + +PAT offer some benefits, such as: + +* **Ease of Use:** Ready-to-use tokens, eliminating the need for complex signing logic. + +However, PATs also come with limitations: + +* **Centralized Validation:** Similar to Client Credentials, relying on the server for verification could impact performance under high load. +* **Revocation:** Requires deleting the PAT directly, potentially causing downtime if not managed carefully. +* **Leakage:** PATs are long-lived tokens that can be readily used in API calls, if leaked the attacker can access all resources until the PAT is expired or deleted. Private key JWT and client credentials create a short-lived access token instead. + +## Using Service Users + +1. **Creation:** Access the ZITADEL management console and create a new service user. Assign a descriptive name that reflects its purpose. Follow our detailed guide on [how to create service users](../../manage/console/users). +2. **Credentials:** Choose your preferred authentication method (JWT or Client Credentials) and securely store the generated credentials (private key, client secret). +3. **Making API Calls:** When your service needs to make an API call: + * **For JWT:** Generate and sign a JWT. Include it in the "Authorization" header of your API request. + * **For Client Credentials:** Include the client ID and client secret in your API request. + * **For PATs:** Include the PAT directly in the "Authorization" header of your API request. +4. ZITADEL Verifies the credentials and authorizes the service user to perform the requested action based on its granted permissions. + +We have guides for the different authentication methods: + +- [Private key JWT authentication](private-key-jwt) +- [Client credential authentication](client-credentials) +- [Personal access token authentication](personal-access-token) + +## Important considerations + +* **Secure Credentials:** Treat service user credentials (private keys, client secrets) with utmost care. Store them securely, similar to any other sensitive information like API keys or passwords. +* **Expiry Management:** Set appropriate expiration dates for JWTs and regularly rotate all credentials to maintain strong security practices. +* **Permission Granting:** Adhere to the principle of least privilege by granting only the specific permissions required for a service user's function. + +## Choosing the right authentication method + +For most service user scenarios in ZITADEL, [private key JWT authentication](./private-key-jwt.md) is the recommended choice due to its benefits in security, performance, and control. +However, [client credentials authentication](./client-credentials.md) might be considered in specific situations where simplicity and trust between servers are priorities. + +## Further resources + +* Read about the [different methods to authenticate service users](./authenticate-service-users) +* [Service User API reference](/docs/category/apis/resources/mgmt/user-machine) +* [OIDC JWT with private key](/docs/apis/openidoauth/authn-methods#jwt-with-private-key) authentication method reference +* [Access ZITADEL APIs](../zitadel-apis/access-zitadel-apis) +* Validate access tokens with [token introspection with private key jwt](../token-introspection/private-key-jwt.mdx) + +import DocCardList from '@theme/DocCardList'; + + diff --git a/docs/docs/guides/integrate/service-users/client-credentials.md b/docs/docs/guides/integrate/service-users/client-credentials.md new file mode 100644 index 0000000000..8d2caf6e83 --- /dev/null +++ b/docs/docs/guides/integrate/service-users/client-credentials.md @@ -0,0 +1,104 @@ +--- +title: Configure client credential authentication for service users +sidebar_label: Client credential authentication +sidebar_position: 3 +--- + +This guide demonstrates how developers can leverage Client Credential authentication to secure communication between [service users](/concepts/structure/users) and client applications within ZITADEL. + +In ZITADEL, the Client Credentials Flow can be used for this [non-interactive authentication](authenticate-service-users) as alternative to the [JWT profile authentication](../service-users/authenticate-service-users). + +## Steps to authenticate a Service User with client credentials + +### 1. Create a Service User with a client secret + +1. Navigate to Service Users +2. Click on **New** +3. Enter a username and a display name +4. Click on **Create** +5. Open **Actions** in the top right corner and click on **Generate Client Secret** +6. Copy the **ClientID** and **ClientSecret** from the dialog + +:::note +Make sure to copy in particular the ClientSecret. You won't be able to retrieve it again. +If you lose it, you will have to generate a new one. +::: + +![Create new service user](/img/console_serviceusers_secret.gif) + +## 2. Authenticating a service user and request a token + +In this step, we will authenticate a service user and receive an access_token to use against the ZITADEL API. + +You will need to craft a POST request to ZITADEL's token endpoint: + +```bash +curl --request POST \ + --url https://$CUSTOM-DOMAIN/oauth/v2/token \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --header 'Authorization: Basic ${BASIC_AUTH}' \ + --data grant_type=client_credentials \ + --data scope='openid profile' +``` + +* `grant_type` should be set to `client_credentials` +* `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid`. For this example, please include `profile` + +If you want to access ZITADEL APIs, make sure to include the required scopes `urn:zitadel:iam:org:project:id:zitadel:aud`. +Read our guide [how to access ZITADEL APIs](../zitadel-apis/access-zitadel-apis) to learn more. + +You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. + +```bash +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", + "token_type": "Bearer", + "expires_in": 43199 +} +``` + +Per default a service user will get an opaque access token. +If you want to get a Jason Web Token (JWT) as an access token for your user, you can change the token type in the general settings of your service account. +To learn more about opaque and JWT tokens read our [Opaque Tokens in ZITADEL: Enhancing Application Security](/docs/concepts/knowledge/opaque-tokens) Guide + +![Service User Token Type](/img/console_service_user_tokentype.png) + +### 3. Include the access token in the authorization header + +When making API requests on behalf of the service user, include the generated token in the "Authorization" header with the "Bearer" prefix. + +```bash +curl --request POST \ + --url $YOUR_API_ENDOINT \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --header 'Authorization: Bearer MtjHodGy4zxKylDOhg6kW90WeEQs2q...' +``` + +## Accessing ZITADEL APIs + +You might want to access ZITADEL APIs to manage resources, such as users, or to validate tokens sent to your backend service. +Follow our guides on [how to access ZITADEL API](../zitadel-apis/access-zitadel-apis) to use the ZITADEL APIs with your service user using client credentials. + +### Token introspection + +Your API endpoint might receive tokens from users and need to validate the token with ZITADEL. +In this case, your API needs to authenticate with ZITADEL and then do a token introspection. +Follow our [guide on token introspection with client credentials](../token-introspection/basic-auth) to learn more. + +## Security considerations + +* **Store private keys securely:** **Never share or embed the private key in your code or application.** Consider using secure key management solutions. +* **Set appropriate expiration times:** Limit the validity period of tokens to minimize the impact of potential compromise. + +By following these steps and adhering to security best practices, you can effectively secure service user and client application communication within ZITADEL using client credential authentication. + +## Notes + +* Read about the [different methods to authenticate service users](./authenticate-service-users) +* [Service User API reference](/docs/category/apis/resources/mgmt/user-machine) +* [OIDC client secret basic](/docs/apis/openidoauth/authn-methods#client-secret-basic) authentication method reference +* [Access ZITADEL APIs](../zitadel-apis/access-zitadel-apis) +* Validate access tokens with [token introspection with basic auth](../token-introspection/basic-auth) diff --git a/docs/docs/guides/integrate/service-users/personal-access-token.md b/docs/docs/guides/integrate/service-users/personal-access-token.md new file mode 100644 index 0000000000..2b42c89d0e --- /dev/null +++ b/docs/docs/guides/integrate/service-users/personal-access-token.md @@ -0,0 +1,70 @@ +--- +title: Configure personal access token authentication for service users +sidebar_label: Personal access token authentication +sidebar_position: 3 +--- + +A Personal Access Token (PAT) is a ready to use token which can be used as _Authorization_ header. +At the moment ZITADEL only allows PATs for machine accounts (service users). + +It is an alternative to the [private key JWT profile authentication](private-key-jwt) and [client credentials authentication](client-credentials). Read more about that the different [authentication methods for service users](authenticate-service-users). + +## Create a Service User with a PAT + +1. Navigate to Service Users +2. Click on **New** +3. Enter a user name and a display name +4. Click on the Personal Access Token menu point in the detail of your user +5. Click on **New** +6. You can either set an expiration date or leave it empty if you don't want it to expire +7. Copy the token from the dialog (You will not see this again) + +![Create new service user](/img/guides/console-service-user-pat.gif) + +## Grant role for ZITADEL + +To be able to access the ZITADEL APIs your service user needs permissions to ZITADEL. + +1. Go to the detail page of your organization +2. Click in the top right corner the "+" button +3. Search for your service user +4. Give the user the role you need, for the example we choose Org Owner (More about [ZITADEL Permissions](/docs/guides/manage/console/managers)) + +![Add org owner to service user](/img/guides/console-service-user-org-owner.gif) + +## Accessing ZITADEL APIs + +You might want to access ZITADEL APIs to manage resources, such as users, or to validate tokens sent to your backend service. +Follow our guides on [how to access ZITADEL API](../zitadel-apis/access-zitadel-apis) to use the ZITADEL APIs with your service user. + +### Token introspection + +Your API endpoint might receive tokens from users and need to validate the token with ZITADEL. +In this case your API needs to authenticate with ZITADEL and then do a token introspection. +Follow our [guide on token introspection with private key JWT](../token-introspection/private-key-jwt) to learn more. + +## Call ZITADEL API with PAT + +Because the PAT is a ready to use token, you can add it as Authorization Header and send it in your requests to the ZITADEL API. +In this example we read the organization of the service user. + +```bash +curl --request GET \ + --url $CUSTOM-DOMAIN/management/v1/orgs/me \ + --header 'Authorization: Bearer {PAT}' +``` + + +## Client application authentication + +The above steps demonstrate service user authentication. +If your application also needs to authenticate itself, you can utilize [Client Credentials Grant](./client-credentials). +Refer to ZITADEL documentation for details on this alternative method. + +## Security considerations + +* **Store private keys securely:** **Never share or embed the private key in your code or application.** Consider using secure key management solutions. +* **Set appropriate JWT expiration times:** Limit the validity period of tokens to minimize the impact of potential compromise. +* **Implement proper error handling:** Handle situations where JWT verification fails or tokens are expired. + +By following these steps and adhering to security best practices, you can effectively secure service user and client application communication within ZITADEL using private key JWT authentication. \ No newline at end of file diff --git a/docs/docs/guides/integrate/service-users/private-key-jwt.md b/docs/docs/guides/integrate/service-users/private-key-jwt.md new file mode 100644 index 0000000000..65bd3d0f1e --- /dev/null +++ b/docs/docs/guides/integrate/service-users/private-key-jwt.md @@ -0,0 +1,213 @@ +--- +title: Configure private key JWT authentication for service users +sidebar_label: Private key JWT authentication +sidebar_position: 2 +--- + +This guide demonstrates how developers can leverage private key JWT authentication to secure communication between service users and client applications within ZITADEL. + +In ZITADEL we use the `urn:ietf:params:oauth:grant-type:jwt-bearer` (**“JWT bearer token with private key”**, [RFC7523](https://tools.ietf.org/html/rfc7523)) authorization grant for this non-interactive authentication. + +Read more about the [different authentication methods for service users](authenticate-service-users) and their benefits, drawbacks, and security considerations. + +#### How private key JWT authentication works + +1. Generate a private/public key pair associated with the service user. +2. The authorization server stores the public key; and +3. returns the private key as a json file +4. The developer configures the client in such a way, that +5. JWT assertion is created with the subject of the service user, and the JWT is signed by the private key +6. Resource owner requests a token by sending the client_assertion +7. Authorization server validates the signature using the service user's public key +8. Authorization server returns an OAuth access_token +9. Resource Owner calls a Resource Server by including the access_token in the Header +10. Resource Server validates the JWT with [token introspection](../token-introspection/) + +![private key jwt authentication sequence diagram](/img/guides/integrate/service-users/sequence-private-key-jwt.svg) + + +## Prerequisites + +A code library/framework supporting JWT generation and verification (e.g., `pyjwt` for Python, `jsonwebtoken` for Node.js). + +## Steps to authenticate a Service User with private JWT + +You need to follow these steps to authenticate a service user and receive an access token that can be used in subsequent requests. + +### 1. Create a Service User + +1. Navigate to Service Users +2. Click on **New** +3. Enter a username and a display name +4. Click on **Create** + +### 2. Generate a private key file + +1. Access the ZITADEL web console and navigate to the service user details. +2. Click on the **Keys** menu point in the detail of your new service user +3. Click on **New** +4. You can either set an expiration date or leave it empty if you don't want it to expire +5. Click on **Download** and save the key file + +:::note +Make sure to save the key file. You won't be able to retrieve it again. +If you lose it, you will have to generate a new one. +::: + +:::note Expiration +If you specify an expiration date, note that the key will expire at midnight that day +::: + +![Create private key](/img/console_serviceusers_new_key.gif) + +The downloaded JSON should look something like outlined below. The value of `key` contains the _private_ key for your service account. Please make sure to keep this key securely stored and handled with care. The public key is automatically stored in ZITADEL. + +```json +{ + "type":"serviceaccount", + "keyId":"100509901696068329", + "key":"-----BEGIN RSA PRIVATE KEY----- [...] -----END RSA PRIVATE KEY-----\n", + "userId":"100507859606888466" +} +``` + +### 3. Create a JWT and sign with private key + +You need to create a JWT with the following header and payload and sign it with the RS256 algorithm. + +Header + +```json +{ + "alg": "RS256", + "kid":"100509901696068329" +} +``` + +Make sure to include `kid` in the header with the value of `keyId` from the downloaded JSON. + +Payload + +```json +{ + "iss": "100507859606888466", + "sub": "100507859606888466", + "aud": "https://$CUSTOM-DOMAIN", + "iat": [Current UTC timestamp, e.g. 1605179982, max. 1 hour ago], + "exp": [UTC timestamp, e.g. 1605183582] +} +``` + +* `iss` represents the requesting party, i.e. the owner of the private key. In this case the value of `userId` from the downloaded JSON. +* `sub` represents the application. Set the value also to the value of `userId` +* `aud` must be your [Custom Domain](../../../concepts/features/custom-domain) +* `iat` is a unix timestamp of the creation signing time of the JWT, e.g. now and must not be older than 1 hour ago +* `exp` is the unix timestamp of expiry of this assertion + +Please refer to [JWT with private key](/apis/openidoauth/authn-methods#jwt-with-private-key) API reference for further information. + +If you use Go, you might want to use the [provided tool](https://github.com/zitadel/zitadel-tools) to generate a JWT from the downloaded JSON. +There are many [libraries](https://jwt.io/#libraries-io) to generate and sign JWT. + +**Code Example (Python using `pyjwt`):** + +```python +import jwt +import datetime + +# Replace with your service user ID and private key +service_user_id = "your_service_user_id" +private_key = "-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY\n-----END PRIVATE KEY-----" + +# ZITADEL API URL (replace if needed) +api_url = "your_custom_domain" + +# Generate JWT claims +payload = { + "iss": "your_zitadel_instance_id", + "sub": service_user_id, + "aud": api_url, + "exp": datetime.utcnow() + datetime.timedelta(minutes=5), + "iat": datetime.utcnow() +} + +# Sign the JWT using RS256 algorithm +encoded_jwt = jwt.encode(payload, private_key, algorithm="RS256") + +print(f"Generated JWT: {encoded_jwt}") +``` + +### 4. Request an OAuth token with the generated JWT + +With the encoded JWT from the prior step, you will need to craft a POST request to ZITADEL's token endpoint: + +```bash +curl --request POST \ + --url https:/$CUSTOM-DOMAIN/oauth/v2/token \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --data grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \ + --data scope='openid' \ + --data assertion=eyJ0eXAiOiJKV1QiL... +``` + +* `grant_type` should be set to `urn:ietf:params:oauth:grant-type:jwt-bearer` +* `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid`. +* `assertion` is the encoded value of the JWT that was signed with your private key from the prior step + +If you want to access ZITADEL APIs, make sure to include the required scopes `urn:zitadel:iam:org:project:id:zitadel:aud`. +Read our guide [how to access ZITADEL APIs](../zitadel-apis/access-zitadel-apis) to learn more. + +You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. + +```bash +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", + "token_type": "Bearer", + "expires_in": 43199 +} +``` + +### 5. Include the access token in the authorization header + +When making API requests on behalf of the service user, include the generated token in the "Authorization" header with the "Bearer" prefix. + +```bash +curl --request POST \ + --url $YOUR_API_ENDOINT \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --header 'Authorization: Bearer MtjHodGy4zxKylDOhg6kW90WeEQs2q...' +``` + +## Accessing ZITADEL APIs + +You might want to access ZITADEL APIs to manage resources, such as users, or to validate tokens sent to your backend service. +Follow our guides on [how to access ZITADEL API](../zitadel-apis/access-zitadel-apis) to use the ZITADEL APIs with your service user. + +### Token introspection + +Your API endpoint might receive tokens from users and need to validate the token with ZITADEL. +In this case your API needs to authenticate with ZITADEL and then do a token introspection. +Follow our [guide on token introspection with private key JWT](../token-introspection/private-key-jwt) to learn more. + +## Client application authentication + +The above steps demonstrate service user authentication. +If your application also needs to authenticate itself, you can utilize [Client Credentials Grant](./client-credentials). +Refer to ZITADEL documentation for details on this alternative method. + +## Security considerations + +* **Store private keys securely:** **Never share or embed the private key in your code or application.** Consider using secure key management solutions. +* **Set appropriate JWT expiration times:** Limit the validity period of tokens to minimize the impact of potential compromise. +* **Implement proper error handling:** Handle situations where JWT verification fails or tokens are expired. + +By following these steps and adhering to security best practices, you can effectively secure service user and client application communication within ZITADEL using private key JWT authentication. + +## Notes + +* [JWT with private key](/apis/openidoauth/authn-methods#jwt-with-private-key) API reference +* [Accessing ZITADEL API](../zitadel-apis/access-zitadel-apis) +* [Token introspection with private key JWT](../token-introspection/private-key-jwt) diff --git a/docs/docs/guides/integrate/token-introspection/index.md b/docs/docs/guides/integrate/token-introspection/index.md new file mode 100644 index 0000000000..b7782d952a --- /dev/null +++ b/docs/docs/guides/integrate/token-introspection/index.md @@ -0,0 +1,39 @@ +--- +title: Token introspection +sidebar_label: Token introspection +sidebar_position: 1 +--- + +Token introspection is the process of checking whether an access token is valid and can be used to access protected resources. + +You have an API that acts as an OAuth resource server and can be accessed by user-facing applications. +To validate an access token by calling the ZITADEL introspection API, you can use the JSON Web Token (JWT) Profile (recommended) or Basic Authentication for token introspection. +It's crucial to understand that the API is entirely separate from the front end. +The API shouldn’t concern itself with the token type received. +Instead, it's about how the API chooses to call the introspection endpoint, either through JWT Profile or Basic Authentication. +Many APIs assume they might receive a JWT and attempt to verify it based on signature or expiration. +However, with ZITADEL, you can send either a JWT or an opaque Bearer token from the client end to the API. +This flexibility is one of ZITADEL's standout features. + +## API application + +If you have an API that behaves as an OAuth resource server that can be accessed by user-facing applications and need to validate an access token by calling the ZITADEL introspection API, you can use the following methods to register these APIs in ZITADEL: + +- [JSON Web Token (JWT) Profile (Recommended)](private-key-jwt.mdx) +- [Basic Authentication](./basic-auth.mdx) + +## Service users + +If there are client APIs or systems that need to access other protected APIs, these APIs or systems must be declared as [service users](/docs/concepts/structure/users). +A service user is not considered an application type in ZITADEL. +Read the introduction on how to [authenticate service users](../service-users/authenticate-service-users.md). + +## Further references + +- [Introspection API reference](/docs/apis/openidoauth/endpoints#token_endpoint) +- [JWT vs. opaque tokens](/docs/concepts/knowledge/opaque-tokens.md) +- [Python examples for securing an API and invoking it as a service user](https://github.com/zitadel/examples-api-access-and-token-introspection) + +import DocCardList from '@theme/DocCardList'; + + diff --git a/docs/docs/guides/integrate/token-introspection/private-key-jwt.mdx b/docs/docs/guides/integrate/token-introspection/private-key-jwt.mdx index beaa58f3fb..57fa4abd31 100644 --- a/docs/docs/guides/integrate/token-introspection/private-key-jwt.mdx +++ b/docs/docs/guides/integrate/token-introspection/private-key-jwt.mdx @@ -5,7 +5,7 @@ sidebar_label: JSON Web Token(JWT) Profile import IntrospectionResponse from './_introspection-response.mdx'; -This is a guide on how to secure your API using [JSON Web Token (JWT) profile (recommended)](https://zitadel.com/docs/apis/openidoauth/authn-methods#client-secret-basic). +This is a guide on how to secure your API using [JSON Web Token (JWT) profile (recommended)](/docs/apis/openidoauth/authn-methods#client-secret-basic). ## Register the API in ZITADEL and generate private and public keys diff --git a/docs/docs/guides/integrate/zitadel-apis/_accessing_zitadel_api.md b/docs/docs/guides/integrate/zitadel-apis/_accessing_zitadel_api.md new file mode 100644 index 0000000000..cf74299adb --- /dev/null +++ b/docs/docs/guides/integrate/zitadel-apis/_accessing_zitadel_api.md @@ -0,0 +1,75 @@ + +## Accessing ZITADEL APIs + +In this step, we will authenticate a service user and receive an access_token to use against the ZITADEL API. + +You will need to craft a POST request to ZITADEL's token endpoint: + +```bash +curl --request POST \ + --url https://$CUSTOM-DOMAIN/oauth/v2/token \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --header 'Authorization: Basic ${BASIC_AUTH}' \ + --data grant_type=client_credentials \ + --data scope='openid urn:zitadel:iam:org:project:id:zitadel:aud' +``` + +If you want to access the ZITADEL API with this access token, you have to add `urn:zitadel:iam:org:project:id:zitadel:aud` to the list of scopes. + +* `grant_type` should be set to `urn:ietf:params:oauth:grant-type:jwt-bearer` +* `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid` and `urn:zitadel:iam:org:project:id:zitadel:aud` +* `assertion` is the encoded value of the JWT that was signed with your private key from the prior step + +You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. + +```bash +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", + "token_type": "Bearer", + "expires_in": 43199 +} +``` + + +In this step we will authenticate a service user and receive an access_token to use against the ZITADEL API. + +You will need to craft a POST request to ZITADEL's token endpoint: + +```bash +curl --request POST \ + --url https://$CUSTOM-DOMAIN/oauth/v2/token \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --header 'Authorization: Basic ${BASIC_AUTH}' \ + --data grant_type=client_credentials \ + --data scope='openid profile email urn:zitadel:iam:org:project:id:zitadel:aud' +``` + +* `grant_type` should be set to `client_credentials` +* `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid`. For this example, please include `profile`, `email` + and `urn:zitadel:iam:org:project:id:zitadel:aud`. The latter provides access to the ZITADEL API. + +You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. + +```bash +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", + "token_type": "Bearer", + "expires_in": 43199 +} +``` + +### Access ZITADEL's API with the token + +```bash +curl --request GET \ + --url $CUSTOM-DOMAIN/management/v1/orgs/me \ + --header "Authorization: Bearer $TOKEN" +``` + +Where `$TOKEN` corresponds to the access token from the earlier response. \ No newline at end of file diff --git a/docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md b/docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md new file mode 100644 index 0000000000..697832461a --- /dev/null +++ b/docs/docs/guides/integrate/zitadel-apis/access-zitadel-apis.md @@ -0,0 +1,237 @@ +--- +title: Access ZITADEL APIs +--- + +This guide explains what ZITADEL APIs are and how to access ZITADEL APIs using a service user to manage all types of resources and settings. + +## What are the ZITADEL APIs + +ZITADEL exposes a variety of APIs that allow you to interact with its functionalities programmatically. +These APIs are offered through different protocols including gRPC and REST. +Additionally, ZITADEL provides [SDKs for popular languages](/docs/sdk-examples/introduction) and frameworks to simplify integration. + +Here's a breakdown of some key points about ZITADEL APIs: + +* **Auth API:** Used by authenticated users for tasks related to their accounts. +* **Management API:** Used by organization managers for administrative tasks. +* **Admin API:** Used for administrative functions on the ZITADEL instance itself (may require separate user setup). +* **System API:** For ZITADEL self-hosted deployments only, providing superordinate control (requires specific configuration). + +:::note Resource-based APIs +ZITADEL is transitioning from a use-case based API structure to a resource-based one, aiming to simplify API usage. +::: + +For further details and in-depth exploration, you can refer to the [ZITADEL API documentation](/docs/apis/introduction). + +## How to access ZITADEL APIs + +Accessing ZITADEL APIs, except for the Auth API and the System API, requires these basic steps: + +1. **Create a service user**: A service user is a special type of account used to grant programmatic access to ZITADEL's functionalities. Unlike regular users who log in with a username and password, [service users rely on a more secure mechanism involving digital keys and tokens](../service-users/authenticate-service-users). +2. **Give permission to access ZITADEL APIs**: Assign a Manager role to the service user, giving it permission to make changes to certain resources in ZITADEL. +3. **Authenticate the service user**: Like human users, service users must authenticate and request an OAuth token with the scope `urn:zitadel:iam:org:project:id:zitadel:aud` to access ZITADEL APIs. [Service users can be authenticated](../service-users/authenticate-service-users) using private key JWT, client credentials, or personal access tokens. +4. **Access ZITADEL APIs with the token**: The OAuth token must be included in the Authorization Header of calls to ZITADEL APIs. + +### Accessing Auth API + +The Auth API can be used for all operations on the requesting user, meaning the user id in the sub claim of the used token. +Using this API doesn't require a service user to be authenticated. +Instead, you call the Auth API with the token of the user. + +[Reference documentation for authentication API](/docs/apis/introduction#authentication) + +### Accessing System API + +With the System API developers can manage different ZITADEL instances. +The System API can't be accessed by service users and requires a special configuration and authentication that can be found in our [guide to access ZITADEL's System API](./access-zitadel-system-api). + +[Reference documentation for system API](/docs/apis/introduction#system) + +## 1. Create a service user + +First, you need to create a new service user through the console or ZITADEL APIs. + +Via Console: + +1. In an organization, navigate to Users > Service Users +2. Click on **New** +3. Enter a username and a display name +4. Click on **Create** + +Via APIs: + +* [Create User (Machine)](/docs/apis/resources/mgmt/management-service-add-machine-user) + +## 2. Grant a Manager role to the service user + +ZITADEL Managers are Users who have permission to manage ZITADEL itself. +There are some different levels for managers. + +- **IAM Managers**: This is the highest level. Users with IAM Manager roles are able to manage the whole instance. +- **Org Managers**: Managers in the Organization Level are able to manage everything within the granted Organization. +- **Project Managers**: At this level, the user is able to manage a project. +- **Project Grant Manager**: The project grant manager is for projects, which are granted of another organization. + +On each level, we have some different Roles. Here you can find more about the different roles: [ZITADEL Manager Roles](/guides/manage/console/managers#roles) + +To be able to access the ZITADEL APIs your service user needs permissions to ZITADEL. + +1. Go to the detail page of your organization +2. Click in the top right corner the "+" button +3. Search for your service user +4. Give the user the role you need, for the example we choose Org Owner (More about [ZITADEL Permissions](/guides/manage/console/managers)) + +![Add Org Manager](/img/console_org_manager_add.gif) + +## 3. Authenticate service user and request token + +Service users can be authenticated using private key JWT, client credentials, or personal access tokens. +The [service user authentication](../service-users/authenticate-service-users) can be used to make machine-to-machine requests to any Resource Server (eg, a backend service / API) by requesting a token from the Authorization Server (ZITADEL) and sending the short-lived token (access token) in the Header of requests. + +This guide covers a specific case of service user authentication when requesting access to the [ZITADEL APIs](/docs/apis/introduction). +While PAT can be used directly to access the ZITADEL APIS, the more secure authentication methods private key JWT and client credentials must include the [reserved scope](/docs/apis/openidoauth/scopes) `urn:zitadel:iam:org:project:id:zitadel:aud` when requesting an access from the token endpoint. +This scope will add the ZITADEL APIs to the audience of the access token. +ZITADEL APIs will check if they are in the audience of the access token, and reject the token in case they are not in the audience. + +The following sections will explain the more specific authentication to access the ZITADEL APIs. + +### Authenticate with private key JWT + +Follow the steps in this guide to [generate an key file](../service-users/private-key-jwt#2-generate-a-private-key-file) and [create a JWT and sign with private key](../service-users/private-key-jwt#3-create-a-jwt-and-sign-with-private-key). + +With the encoded JWT (assertion) from the prior step, you will need to craft a POST request to ZITADEL's token endpoint. + +**To access the ZITADEL APIs you need the ZITADEL Project ID in the audience of your token.** +This is possible by sending a [reserved scope](/apis/openidoauth/scopes) for the audience. +Use the scope `urn:zitadel:iam:org:project:id:zitadel:aud` to include the ZITADEL project id in your audience + +A sample request will look like this + +```bash {5} +curl --request POST \ + --url $CUSTOM-DOMAIN/oauth/v2/token \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --data grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \ + --data scope='openid profile urn:zitadel:iam:org:project:id:zitadel:aud' \ + --data assertion=eyJ0eXAiOiJKV1QiL... +``` + +where + +- `grant_type` must be set to `urn:ietf:params:oauth:grant-type:jwt-bearer` +- `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid` and `urn:zitadel:iam:org:project:id:zitadel:aud` to acces the ZITADEL APIs. For this example include `profile`. +- `assertion` is the encoded value of the JWT that was signed with your private key from the prior step + +You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. + +```bash +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", + "token_type": "Bearer", + "expires_in": 43199 +} +``` + +Use the access_token in the Authorization header to make requests to the ZITADEL APIs. +In the following example, we read the organization of the service user. + +```bash +curl --request GET \ + --url $CUSTOM-DOMAIN/management/v1/orgs/me \ + --header 'Authorization: Bearer ${TOKEN}' +``` + +### Client credentials + +Get the client id and client secret by + +1. navigating to the service user, then +2. Open **Actions** in the top right corner and click on **Generate Client Secret** +3. Copy the **ClientID** and **ClientSecret** from the dialog + +![Create new service user](/img/console_serviceusers_secret.gif) + +With the ClientId and ClientSecret from the prior step, you will need to craft a POST request to ZITADEL's token endpoint. + +#### Audience scope + +**To access the ZITADEL APIs you need the ZITADEL Project ID in the audience of your token.** +This is possible by sending a [reserved scope](/apis/openidoauth/scopes) for the audience. +Use the scope `urn:zitadel:iam:org:project:id:zitadel:aud` to include the ZITADEL project id in your audience + +In this step we will authenticate a service user and receive an access_token to use against the ZITADEL API. + +#### Basic authentication + +When using `client_secret_basic` on the token or introspection endpoints, provide an `Authorization` header with a Basic auth value in the following form: + +```markdown +Authorization: "Basic " + base64( formUrlEncode(client_id) + ":" + formUrlEncode(client_secret) ) +``` + +For an example see the [client secret basic authentication method reference](/docs/apis/openidoauth/authn-methods#client-secret-basic). +We recommend using an OpenID / OAuth library that handles the encoding for you. + +#### Post request + +You will need to craft a POST request to ZITADEL's token endpoint: + +```bash {6} +curl --request POST \ + --url https://$CUSTOM-DOMAIN/oauth/v2/token \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --header 'Authorization: Basic ${BASIC_AUTH}' \ + --data grant_type=client_credentials \ + --data scope='openid profile urn:zitadel:iam:org:project:id:zitadel:aud' +``` + +where + +* `grant_type` should be set to `client_credentials` +* `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid`. For this example, please include `profile` + and `urn:zitadel:iam:org:project:id:zitadel:aud`. The latter provides access to the ZITADEL API. + +You should receive a successful response with `access_token`, `token_type` and time to expiry in seconds as `expires_in`. + +```bash +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "access_token": "MtjHodGy4zxKylDOhg6kW90WeEQs2q...", + "token_type": "Bearer", + "expires_in": 43199 +} +``` + +Because the received token includes the `urn:zitadel:iam:org:project:id:zitadel:aud` scope, we can send it in your requests to the ZITADEL API as the Authorization Header. +In this example we read the organization of the service user. + +```bash +curl --request GET \ + --url $CUSTOM-DOMAIN/management/v1/orgs/me \ + --header 'Authorization: Bearer ${TOKEN}' +``` + +### Personal access token (PAT) + +A Personal Access Token (PAT) is a ready-to-use token which can be used as _Authorization_ header. + +Because the PAT is a ready-to-use token, you can add it as Authorization Header and send it in your requests to the ZITADEL API. +In this example, we read the organization of the service user. + +```bash +curl --request GET \ + --url $CUSTOM-DOMAIN/management/v1/orgs/me \ + --header 'Authorization: Bearer {PAT}' +``` + +## Notes + +- [Example application in Go](./example-zitadel-api-with-go) to access ZITADEL APIs +- [Example application in .NET](./example-zitadel-api-with-dot-net) to access ZITADEL APIs +- Learn how to use the [Event API](./event-api) to retrieve your audit trail +- Read about the [different methods to authenticate service users](../service-users/authenticate-service-users) diff --git a/docs/docs/guides/integrate/access-zitadel-system-api.md b/docs/docs/guides/integrate/zitadel-apis/access-zitadel-system-api.md similarity index 99% rename from docs/docs/guides/integrate/access-zitadel-system-api.md rename to docs/docs/guides/integrate/zitadel-apis/access-zitadel-system-api.md index 821dbc0d3c..4e2b0b9973 100644 --- a/docs/docs/guides/integrate/access-zitadel-system-api.md +++ b/docs/docs/guides/integrate/zitadel-apis/access-zitadel-system-api.md @@ -1,5 +1,6 @@ --- title: Access ZITADEL System API +sidebar_label: System API --- :::note This guide focuses on the ZITADEL System API. To access the other APIs (Admin, Auth, Management), please checkout [this guide](./access-zitadel-apis). diff --git a/docs/docs/guides/integrate/event-api.md b/docs/docs/guides/integrate/zitadel-apis/event-api.md similarity index 98% rename from docs/docs/guides/integrate/event-api.md rename to docs/docs/guides/integrate/zitadel-apis/event-api.md index 44f9aaef11..e4899421f1 100644 --- a/docs/docs/guides/integrate/event-api.md +++ b/docs/docs/guides/integrate/zitadel-apis/event-api.md @@ -1,6 +1,6 @@ --- title: Get Events from ZITADEL -sidebar_label: Events +sidebar_label: Event API --- ZITADEL leverages the power of eventsourcing, meaning every action and change within the system generates a corresponding event that is stored in the database. @@ -9,7 +9,7 @@ This API allows you to easily retrieve and utilize the events generated within t You need to give a user the [manager role](https://zitadel.com/docs/guides/manage/console/managers) IAM_OWNER_VIEWER or IAM_OWNER to access the Event API. -If you like to know more about eventsourcing/eventstore and how this works in ZITADEL, head over to our [concepts](../../concepts/eventstore/overview). +If you like to know more about eventsourcing/eventstore and how this works in ZITADEL, head over to our [concepts](/docs/concepts/eventstore/overview). ## Request Events Call the [ListEvents](/apis/resources/admin) enpoint in the Administration API to get all the events you need. diff --git a/docs/docs/examples/call-zitadel-api/dot-net.md b/docs/docs/guides/integrate/zitadel-apis/example-zitadel-api-with-dot-net.md similarity index 94% rename from docs/docs/examples/call-zitadel-api/dot-net.md rename to docs/docs/guides/integrate/zitadel-apis/example-zitadel-api-with-dot-net.md index 46d742d98a..fe1b5a2f2c 100644 --- a/docs/docs/examples/call-zitadel-api/dot-net.md +++ b/docs/docs/guides/integrate/zitadel-apis/example-zitadel-api-with-dot-net.md @@ -1,6 +1,6 @@ --- -title: Integrate ZITADEL into a .NET Application -sidebar_label: .NET +title: Integrate ZITADEL APIs into a .NET Application +sidebar_label: Example .NET --- This integration guide shows you how to integrate **ZITADEL** into your .NET application. @@ -15,10 +15,10 @@ If you need any other information about the .NET SDK go to the [documentation](h The client [SDK](https://github.com/zitadel/zitadel-net) will handle all necessary OAuth 2.0 requests and send the required headers to the ZITADEL API. All that is required, is a service account with an Org Owner (or another role, depending on the needed api requests) role assigned and its key JSON. -However, we recommend you read the guide on [how to access ZITADEL API](../../guides/integrate/access-zitadel-apis) and the associated guides for a basic knowledge of : +However, we recommend you read the guide on [how to access ZITADEL API](/docs/guides/integrate/zitadel-apis/access-zitadel-apis) and the associated guides for a basic knowledge of : - - [Recommended Authorization Flows](../../guides/integrate/login/oidc/oauth-recommended-flows.md) - - [Service Users](../../guides/integrate/serviceusers) + - [Recommended Authorization Flows](/docs/guides/integrate/login/oidc/oauth-recommended-flows) + - [Service Users](/docs/guides/integrate/service-users/authenticate-service-users) > Be sure to have a valid key JSON and that its service account is either ORG_OWNER or at least ORG_OWNER_VIEWER before you continue with this guide. diff --git a/docs/docs/examples/call-zitadel-api/go.md b/docs/docs/guides/integrate/zitadel-apis/example-zitadel-api-with-go.md similarity index 89% rename from docs/docs/examples/call-zitadel-api/go.md rename to docs/docs/guides/integrate/zitadel-apis/example-zitadel-api-with-go.md index 4092d9d1f9..3fdc3e8490 100644 --- a/docs/docs/examples/call-zitadel-api/go.md +++ b/docs/docs/guides/integrate/zitadel-apis/example-zitadel-api-with-go.md @@ -1,6 +1,6 @@ --- -title: Integrate ZITADEL into a Go Application -sidebar_label: Go +title: Integrate ZITADEL APIs into a Go Application +sidebar_label: Example Go --- This integration guide shows you how to integrate **ZITADEL** into your Go application. @@ -15,9 +15,9 @@ At the end of the guide you should have an application able to read the details The client [SDK](https://github.com/zitadel/zitadel-go) will handle all necessary OAuth 2.0 requests and send the required headers to the ZITADEL API using our [OIDC client library](https://github.com/zitadel/oidc). All that is required, is a service account with an Org Owner (or another role, depending on the needed api requests) role assigned and its key JSON. -However, we recommend you read the guide on [how to access ZITADEL API](../../guides/integrate/access-zitadel-apis) and the associated guides for a basic knowledge of : - - [Recommended Authorization Flows](../../guides/integrate/login/oidc/oauth-recommended-flows.md) - - [Service Users](../../guides/integrate/serviceusers) +However, we recommend you read the guide on [how to access ZITADEL API](/docs/guides/integrate/zitadel-apis/access-zitadel-apis)) and the associated guides for a basic knowledge of : + - [Recommended Authorization Flows](/docs/guides/integrate/login/oidc/oauth-recommended-flows) + - [Service Users](/docs/guides/integrate/service-users/authenticate-service-users) > Be sure to have a valid key JSON and that its service account is either ORG_OWNER or at least ORG_OWNER_VIEWER before you continue with this guide. diff --git a/docs/docs/guides/manage/terraform/basics.md b/docs/docs/guides/manage/terraform/basics.md index 197527b9bf..d4678efe79 100644 --- a/docs/docs/guides/manage/terraform/basics.md +++ b/docs/docs/guides/manage/terraform/basics.md @@ -10,7 +10,7 @@ It covers how to: Prerequisites: - A ZITADEL Instance, if not present follow [this guide](../../start/quickstart) -- A user with enough authorization to manage the desired resources, if not present follow [this guide](../../integrate/serviceusers) +- A user with enough authorization to manage the desired resources, if not present follow [this guide](/docs/guides/integrate/service-users/authenticate-service-users) - Installed Terraform, if not present follow [this guide](https://learn.hashicorp.com/tutorials/terraform/install-cli) ## Manage ZITADEL resources through terraform diff --git a/docs/docs/guides/migrate/sources/keycloak.md b/docs/docs/guides/migrate/sources/keycloak.md index 666c96adfc..5604714a2b 100644 --- a/docs/docs/guides/migrate/sources/keycloak.md +++ b/docs/docs/guides/migrate/sources/keycloak.md @@ -97,7 +97,7 @@ As explained in this [ZITADEL user migration guide](https://zitadel.com/docs/gui ### Create a service user to consume ZITADEL API -But first of all, in order to use this ZITADEL API, you need to create a [service user](https://zitadel.com/docs/guides/integrate/serviceusers#exercise-create-a-service-user). +But first of all, in order to use this ZITADEL API, you need to create a [service user](https://zitadel.com/docs/guides/integrate/service-users/authenticate-service-users#exercise-create-a-service-user). Go to the **Users** menu and select the **Service Users** tab. And click the **+ New** button. @@ -113,7 +113,7 @@ Your service user is now created and listed. ### Provide 'Org Owner' permissions to the service user -This service user needs to have elevated permissions in order to import users. For this example, you should make the service user an organization owner as explained in [this guide](https://zitadel.com/docs/guides/integrate/access-zitadel-apis#add-org_owner-to-service-user). +This service user needs to have elevated permissions in order to import users. For this example, you should make the service user an organization owner as explained in [this guide](/docs/guides/integrate/zitadel-apis/access-zitadel-apis#add-org_owner-to-service-user). Let's change the permissions as follows: @@ -127,7 +127,7 @@ Next, select your service user that you created and select the **Org Owner** che ### Generate an access token for the service user -In order for the service user to access the API, they must be able to authenticate themselves. To authenticate the user, you can use either [JWT with Private Key](/docs/guides/integrate/serviceusers#authenticating-a-service-user) flow (recommended for production) or [Personal Access Tokens](/docs/guides/integrate/pat)(PAT). In this guide, we will choose the latter. +In order for the service user to access the API, they must be able to authenticate themselves. To authenticate the user, you can use either [JWT with Private Key](/docs/guides/integrate/service-users/authenticate-service-users#authenticating-a-service-user) flow (recommended for production) or [Personal Access Tokens](/docs/guides/integrate/service-users/personal-access-token)(PAT). In this guide, we will choose the latter. Go to **Users** -> **Service Users** again and click on the service user, then select **Personal Access Tokens** on the left and click the **+ New** button. Copy the generated personal access token to use it later. Click **Close** after copying the PAT. diff --git a/docs/docs/guides/migrate/sources/zitadel.md b/docs/docs/guides/migrate/sources/zitadel.md index 2d19eb3e32..06d04f2ad3 100644 --- a/docs/docs/guides/migrate/sources/zitadel.md +++ b/docs/docs/guides/migrate/sources/zitadel.md @@ -36,7 +36,7 @@ You need a PAT from a service user with IAM Owner permissions in both the source 1. Go to your default organization 2. Create a service user "import_user" with Access Token Type "Bearer" -3. Create a [personal access token](/docs/guides/integrate/pat) +3. Create a [personal access token](/docs/guides/integrate/service-users/personal-access-token) 4. Go to the global instance settings 5. Add the import_user as [manager](/docs/guides/manage/console/managers) with the role "IAM Owner" @@ -46,7 +46,7 @@ Save the PAT to the environment variabel `PAT_EXPORT_TOKEN` and the source domai 1. Go to your default organization 2. Create a service user "export_user" with Access Token Type "Bearer" -3. Create a [personal access token](/docs/guides/integrate/pat) +3. Create a [personal access token](/docs/guides/integrate/service-users/personal-access-token) 4. Go to the global instance settings 5. Add the export_user as [manager](/docs/guides/manage/console/managers) with the role "IAM Owner" diff --git a/docs/docs/guides/solution-scenarios/restrict-console.mdx b/docs/docs/guides/solution-scenarios/restrict-console.mdx index 8dce6f9ec7..7d21afda1a 100644 --- a/docs/docs/guides/solution-scenarios/restrict-console.mdx +++ b/docs/docs/guides/solution-scenarios/restrict-console.mdx @@ -53,7 +53,7 @@ First you need a user with manager permissions to change the project settings in 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 manager roles you can find [here](/docs/guides/integrate/pat) +More detailed information about creating a PAT and manager roles you can find [here](/docs/guides/integrate/service-users/personal-access-token) Then you have to send the following request: ```bash diff --git a/docs/docs/imports/_code-flow-chart.md b/docs/docs/imports/_code-flow-chart.md index fbff4b783b..36929bedc2 100644 --- a/docs/docs/imports/_code-flow-chart.md +++ b/docs/docs/imports/_code-flow-chart.md @@ -5,7 +5,7 @@ sequenceDiagram participant App participant AS as Authorization Server (ZITADEL) RO-->>App: Open App - App->>AS: Authorization Rrequest to /authorize + App->>AS: Authorization Request to /authorize AS->>RO: redirect to login RO->>AS: user authentication AS->>App: authorization code response diff --git a/docs/docs/self-hosting/manage/usage_control.md b/docs/docs/self-hosting/manage/usage_control.md index cd438b36d9..4a3963b895 100644 --- a/docs/docs/self-hosting/manage/usage_control.md +++ b/docs/docs/self-hosting/manage/usage_control.md @@ -31,7 +31,7 @@ DefaultInstance: You can restrict the maximum age of events returned by the following APIs: -- [Events Search](/apis/resources/admin/admin-service-list-events), See also the [Event API guide](/guides/integrate/event-api) +- [Events Search](/apis/resources/admin/admin-service-list-events), See also the [Event API guide](/guides/integrate/zitadel-apis/event-api) - [My User History](/apis/resources/auth/auth-service-list-my-user-changes) - [A Users History](/apis/resources/mgmt/management-service-list-user-changes) - [An Applications History](/apis/resources/mgmt/management-service-list-app-changes) diff --git a/docs/docs/support/advisory/a10007.md b/docs/docs/support/advisory/a10007.md index 66a9d8eb5a..455bccebad 100644 --- a/docs/docs/support/advisory/a10007.md +++ b/docs/docs/support/advisory/a10007.md @@ -14,7 +14,7 @@ This advisory applies to self-hosted ZITADEL installations with custom roles to ## Description -In upcoming ZITADEL versions, RBAC also applies to [system users defined in the ZITADEL runtime configuration](/guides/integrate/access-zitadel-system-api#runtime-configuration). +In upcoming ZITADEL versions, RBAC also applies to [system users defined in the ZITADEL runtime configuration](/docs/guides/integrate/zitadel-apis/access-zitadel-system-api#runtime-configuration). This enables fine grained access control to the system API as well as other APIs for system users. ZITADEL defines the new default roles *SYSTEM_OWNER* and *SYSTEM_OWNER_VIEWER*. System users without any memberships defined in the configuration will be assigned the *SYSTEM_OWNER* role. diff --git a/docs/sidebars.js b/docs/sidebars.js index 5304d867b4..c2491abead 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -205,10 +205,10 @@ module.exports = { label: "Login Users", link: { type: "generated-index", - title: "Integrate", + title: "Login users with ZITADEL", slug: "guides/integrate/login", description: - "Integrate your users and application with ZITADEL. In this section you will find resource on how to authenticate your users, configure external identity providers, access the ZITADEL APIs to manage resources, and integrate with third party services and tools.", + "Sign-in users and application with ZITADEL. In this section you will find resources on how to authenticate your users by using the hosted login via OpenID Connect and SAML. Follow our dedicated guides to build your custom login user interface, if you want to customize the login behavior further.", }, items: [ "guides/integrate/login/login-users", @@ -270,34 +270,27 @@ module.exports = { { type: "category", label: "Token Introspection", - link: { - type: "generated-index", - title: "Token Introspection", - slug: "/guides/integrate/token-introspection", - description: - "Token introspection is the process of checking whether an access token is valid and can be used to access protected resources. You have an API that acts as an OAuth resource server and can be accessed by user-facing applications. To validate an access token by calling the ZITADEL introspection API, you can use the JSON Web Token (JWT) Profile (recommended) or Basic Authentication for token introspection. It's crucial to understand that the API is entirely separate from the front end. The API shouldn’t concern itself with the token type received. Instead, it's about how the API chooses to call the introspection endpoint, either through JWT Profile or Basic Authentication. Many APIs assume they might receive a JWT and attempt to verify it based on signature or expiration. However, with ZITADEL, you can send either a JWT or an opaque Bearer token from the client end to the API. This flexibility is one of ZITADEL's standout features.", - }, collapsed: true, items: [ - "guides/integrate/token-introspection/private-key-jwt", - "guides/integrate/token-introspection/basic-auth", + { + type: "autogenerated", + dirName: "guides/integrate/token-introspection", + }, ], }, { type: "category", - label: "Authenticate Service Users", + label: "Service Users", link: { - type: "generated-index", - title: "Authenticate ZITADEL Service Users", - slug: "/guides/integrate/serviceusers", - description: - "How to authenticate service users for machine-to-machine (M2M) communication between services. You also need to authenticate service users to access ZITADEL's APIs.", + type: "doc", + id: "guides/integrate/service-users/authenticate-service-users" }, collapsed: true, items: [ - "guides/integrate/private-key-jwt", - "guides/integrate/client-credentials", - "guides/integrate/pat", + { + type: "autogenerated", + dirName: "guides/integrate/service-users", + }, ], }, { @@ -362,25 +355,16 @@ module.exports = { }, { type: "category", - label: "Access ZITADEL APIs", + label: "ZITADEL APIs", + link: { + type: "doc", + id: "guides/integrate/zitadel-apis/access-zitadel-apis" + }, collapsed: true, items: [ { - type: "link", - label: "Authenticate Service Users", - href: "/guides/integrate/serviceusers", - }, - "guides/integrate/access-zitadel-apis", - "guides/integrate/access-zitadel-system-api", - "guides/integrate/event-api", - { - type: "category", - label: "Example Code", - items: [ - "examples/call-zitadel-api/go", - "examples/call-zitadel-api/dot-net", - ], - collapsed: true, + type: "autogenerated", + dirName: "guides/integrate/zitadel-apis", }, ], }, @@ -540,11 +524,6 @@ module.exports = { items: [ "support/software-release-cycles-support", "support/troubleshooting", - { - type: "link", - label: "Support Service Descriptions", - href: "/legal/service-description/support-services", - }, { type: "category", label: "Technical Advisory", diff --git a/docs/static/img/console_service_user_tokentype.png b/docs/static/img/console_service_user_tokentype.png new file mode 100644 index 0000000000000000000000000000000000000000..dd4a68d8eba4922f726b8cf2e68a265e158913c0 GIT binary patch literal 173063 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 literal 0 HcmV?d00001 diff --git a/docs/static/img/guides/integrate/service-users/sequence-private-key-jwt.svg b/docs/static/img/guides/integrate/service-users/sequence-private-key-jwt.svg new file mode 100644 index 0000000000..c707a32194 --- /dev/null +++ b/docs/static/img/guides/integrate/service-users/sequence-private-key-jwt.svg @@ -0,0 +1 @@ +Resource Server(API)Authorization Server(ZITADEL)Resource Owner(Client on-behalfof service user)Admin(Manager User)Resource Server(API)Authorization Server(ZITADEL)Resource Owner(Client on-behalfof service user)Admin(Manager User)POST /token HTTP/1.1 ...client_assertion_type=urn:ietf:...:grant-type:jwt-bearerclient_assertion=eyJ....(JWT token)Generate private/public key (API or Console)1Store public key2private key3Configure with private key4Generate JWT assertion with private key: payload (sub: serviceUser ID) x private key5Token request with the JWT as Client assertion6validate signature using service user's public key7Provide OAuth access_token8Call API with access_token As Authorization Header9Token introspection10 \ No newline at end of file diff --git a/docs/vercel.json b/docs/vercel.json index 37fdd52363..8adaa184c6 100644 --- a/docs/vercel.json +++ b/docs/vercel.json @@ -29,6 +29,15 @@ { "source": "/docs/guides/solution-scenarios/onboarding/b2b", "destination": "/docs/guides/integrate/onboarding/b2b", "permanent": true }, { "source": "/docs/guides/solution-scenarios/onboarding/end-users", "destination": "/docs/guides/integrate/onboarding/end-users", "permanent": true }, { "source": "/docs/concepts/structure/jwt_idp", "destination": "/docs/guides/integrate/identity-providers/jwt-idp", "permanent": true }, - { "source": "/docs/concepts/structure/jwt-idp", "destination": "/docs/guides/integrate/identity-providers/jwt-idp", "permanent": true } + { "source": "/docs/guides/solution-scenarios/onboarding/end-users", "destination": "/docs/guides/integrate/onboarding/end-users", "permanent": true }, + { "source": "/docs/guides/integrate/serviceusers", "destination": "/docs/guides/integrate/service-users/authenticate-service-users", "permanent": true }, + { "source": "/docs/guides/integrate/private-key-jwt", "destination": "/docs/guides/integrate/service-users/private-key-jwt", "permanent": true }, + { "source": "/docs/guides/integrate/client-credentials", "destination": "/docs/guides/integrate/service-users/client-credentials", "permanent": true }, + { "source": "/docs/guides/integrate/pat", "destination": "/docs/guides/integrate/service-users/private-access-token", "permanent": true }, + { "source": "/docs/guides/integrate/access-zitadel-apis", "destination": "/docs/guides/integrate/zitadel-apis/access-zitadel-apis", "permanent": true }, + { "source": "/docs/guides/integrate/access-zitadel-system-api", "destination": "/docs/guides/integrate/zitadel-apis/access-zitadel-system-api", "permanent": true }, + { "source": "/docs/guides/integrate/event-api", "destination": "/docs/guides/integrate/zitadel-apis/event-api", "permanent": true }, + { "source": "/docs/examples/call-zitadel-api/go", "destination": "/docs/guides/integrate/zitadel-apis/example-zitadel-api-with-go", "permanent": true }, + { "source": "/docs/examples/call-zitadel-api/dot-net", "destination": "/docs/guides/integrate/zitadel-apis/example-zitadel-api-with-dot-net", "permanent": true } ] }