diff --git a/docs/docs/concepts/zitadel/architecture.md b/docs/docs/concepts/architecture.md similarity index 100% rename from docs/docs/concepts/zitadel/architecture.md rename to docs/docs/concepts/architecture.md diff --git a/docs/docs/concepts/general/eventstore.md b/docs/docs/concepts/eventstore.md similarity index 85% rename from docs/docs/concepts/general/eventstore.md rename to docs/docs/concepts/eventstore.md index 7c5b237a48e..00e94625652 100644 --- a/docs/docs/concepts/general/eventstore.md +++ b/docs/docs/concepts/eventstore.md @@ -2,7 +2,7 @@ title: Eventstore --- -ZITADEL is built on the [event sourcing pattern](../zitadel/architecture.md), where changes are stored as events in an eventstore. +ZITADEL is built on the [event sourcing pattern](./architecture), where changes are stored as events in an eventstore. ## What is an eventstore? diff --git a/docs/docs/concepts/introduction.md b/docs/docs/concepts/introduction.md deleted file mode 100644 index 2d2a4304a05..00000000000 --- a/docs/docs/concepts/introduction.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Introduction ---- - -This part of the **ZITADEL** documentation contains ZITADEL specific or general concepts required to understand the system or our guides. - -Please be reminded that ZITADEL is open source — and so is the documentation. Should you happen to stumble over an incorrectness, a spelling mistake, a hard-to-understand text passage, please don’t hesitate to leave a comment or propose a corresponding change. diff --git a/docs/docs/concepts/introduction.mdx b/docs/docs/concepts/introduction.mdx new file mode 100644 index 00000000000..556180e02a5 --- /dev/null +++ b/docs/docs/concepts/introduction.mdx @@ -0,0 +1,39 @@ +--- +title: Introduction +--- + +import {ListElement, ListWrapper, ICONTYPE} from '../../src/components/list'; +import Column from '../../src/components/column'; + +This part of the **ZITADEL** documentation contains ZITADEL specific or general concepts required to understand the system or our guides. + +Please be reminded that ZITADEL is open source — and so is the documentation. Should you happen to stumble over an incorrectness, a spelling mistake, a hard-to-understand text passage, please don’t hesitate to leave a comment or propose a corresponding change. + + + + + + + + + + +
+ + + + +
+
+ + + + +
+
+
+ + + + +
diff --git a/docs/docs/concepts/general/principles.md b/docs/docs/concepts/principles.md similarity index 100% rename from docs/docs/concepts/general/principles.md rename to docs/docs/concepts/principles.md diff --git a/docs/docs/concepts/zitadel/objects/_granted_project_description.mdx b/docs/docs/concepts/structure/_granted_project_description.mdx similarity index 100% rename from docs/docs/concepts/zitadel/objects/_granted_project_description.mdx rename to docs/docs/concepts/structure/_granted_project_description.mdx diff --git a/docs/docs/concepts/zitadel/objects/_org_description.mdx b/docs/docs/concepts/structure/_org_description.mdx similarity index 100% rename from docs/docs/concepts/zitadel/objects/_org_description.mdx rename to docs/docs/concepts/structure/_org_description.mdx diff --git a/docs/docs/concepts/zitadel/objects/_project_description.mdx b/docs/docs/concepts/structure/_project_description.mdx similarity index 100% rename from docs/docs/concepts/zitadel/objects/_project_description.mdx rename to docs/docs/concepts/structure/_project_description.mdx diff --git a/docs/docs/concepts/zitadel/objects/_user_description.mdx b/docs/docs/concepts/structure/_user_description.mdx similarity index 100% rename from docs/docs/concepts/zitadel/objects/_user_description.mdx rename to docs/docs/concepts/structure/_user_description.mdx diff --git a/docs/docs/concepts/zitadel/objects/applications.md b/docs/docs/concepts/structure/applications.md similarity index 84% rename from docs/docs/concepts/zitadel/objects/applications.md rename to docs/docs/concepts/structure/applications.md index 78793be7516..34998de4cb1 100644 --- a/docs/docs/concepts/zitadel/objects/applications.md +++ b/docs/docs/concepts/structure/applications.md @@ -18,4 +18,5 @@ As a fourth option there's the API (OAuth Resource Server), which generally has Depending on the app type registered, there are small differences in the possible settings. -Please read the following guide about the [different-client-profiles](../../../guides/authorization/oauth-recommended-flows#different-client-profiles). +Please read the following guide about the +[different-client-profiles](../../guides/authorization/oauth-recommended-flows#different-client-profiles). diff --git a/docs/docs/concepts/zitadel/objects/granted_projects.md b/docs/docs/concepts/structure/granted_projects.md similarity index 100% rename from docs/docs/concepts/zitadel/objects/granted_projects.md rename to docs/docs/concepts/structure/granted_projects.md diff --git a/docs/docs/concepts/zitadel/objects/managers.md b/docs/docs/concepts/structure/managers.md similarity index 100% rename from docs/docs/concepts/zitadel/objects/managers.md rename to docs/docs/concepts/structure/managers.md diff --git a/docs/docs/concepts/zitadel/objects/organizations.md b/docs/docs/concepts/structure/organizations.md similarity index 100% rename from docs/docs/concepts/zitadel/objects/organizations.md rename to docs/docs/concepts/structure/organizations.md diff --git a/docs/docs/concepts/zitadel/objects/overview.md b/docs/docs/concepts/structure/overview.md similarity index 95% rename from docs/docs/concepts/zitadel/objects/overview.md rename to docs/docs/concepts/structure/overview.md index 77940d4e399..7eaa3985dad 100644 --- a/docs/docs/concepts/zitadel/objects/overview.md +++ b/docs/docs/concepts/structure/overview.md @@ -1,5 +1,5 @@ --- -title: Structure +title: Overview --- This overview shows the general structure of ZITADEL. diff --git a/docs/docs/concepts/zitadel/objects/policies.md b/docs/docs/concepts/structure/policies.md similarity index 98% rename from docs/docs/concepts/zitadel/objects/policies.md rename to docs/docs/concepts/structure/policies.md index 1488ed14c2d..ed9a63ef168 100644 --- a/docs/docs/concepts/zitadel/objects/policies.md +++ b/docs/docs/concepts/structure/policies.md @@ -55,7 +55,7 @@ You can configure all kinds of external identity providers for identity brokerin Create a new identity provider configuration and enable it in the list afterwards. For a detailed guide about how to configure a new identity provider for identity brokering have a look at our guide: -[Identity Brokering](../../../guides/authentication/identity-brokering) +[Identity Brokering](../../guides/authentication/identity-brokering) ## Lockout Policy diff --git a/docs/docs/concepts/zitadel/objects/projects.md b/docs/docs/concepts/structure/projects.md similarity index 94% rename from docs/docs/concepts/zitadel/objects/projects.md rename to docs/docs/concepts/structure/projects.md index ab32032a0c6..8484018e3b4 100644 --- a/docs/docs/concepts/zitadel/objects/projects.md +++ b/docs/docs/concepts/structure/projects.md @@ -11,7 +11,7 @@ import ProjectDescription from './_project_description.mdx'; ## Project Settings On default the login screen will be shown in the private labeling settings of the system (e.g zitadel.ch). -With the [primary domain scope](../../../apis/openidoauth/scopes#reserves-scopes) it is possible to trigger the setting of the given organization. +With the [primary domain scope](../../apis/openidoauth/scopes#reserves-scopes) it is possible to trigger the setting of the given organization. But this will also restrict, the login to user of the given organization. With the private labeling setting it is possible to choose which settings should trigger. diff --git a/docs/docs/concepts/zitadel/objects/users.md b/docs/docs/concepts/structure/users.md similarity index 100% rename from docs/docs/concepts/zitadel/objects/users.md rename to docs/docs/concepts/structure/users.md diff --git a/docs/docs/concepts/usecases/saas.md b/docs/docs/concepts/usecases/saas.md index 0fe1107532c..7ede685a6b4 100644 --- a/docs/docs/concepts/usecases/saas.md +++ b/docs/docs/concepts/usecases/saas.md @@ -1,5 +1,5 @@ --- -title: Saas Product with Authentication and Authorization +title: SaaS Product with Authentication and Authorization --- This is an example architecture for a typical SaaS product. diff --git a/docs/docs/guides/api/access-zitadel-apis.md b/docs/docs/guides/api/access-zitadel-apis.md index 9cd04c1f879..7006b61962d 100644 --- a/docs/docs/guides/api/access-zitadel-apis.md +++ b/docs/docs/guides/api/access-zitadel-apis.md @@ -37,7 +37,7 @@ ZITADEL Managers are Users who have permission to manage ZITADEL itself. There a - **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](../../concepts/zitadel/objects/managers.md) +On each level we have some different Roles. Here you can find more about the different roles: [ZITADEL Manager Roles](../../concepts/structure/managers.md) ## Exercise: Add ORG_OWNER to Service User diff --git a/docs/docs/guides/authentication/authmethods.mdx b/docs/docs/guides/authentication/authmethods.mdx index 9b5d6da847a..7908f0dfdf3 100644 --- a/docs/docs/guides/authentication/authmethods.mdx +++ b/docs/docs/guides/authentication/authmethods.mdx @@ -5,6 +5,7 @@ import PKCE from "./authmethods/pkce.mdx"; import Basic from "./authmethods/basic.mdx"; import Implicit from "./authmethods/implicit.mdx"; import PKCENative from "./authmethods/pkcenative.mdx"; +import JWTPrivateKey from "./authmethods/jwtpk.mdx"; export default function AuthMethods(props) { return props.selected == "web" ? ( @@ -15,7 +16,7 @@ export default function AuthMethods(props) { values={[ { label: "PKCE", value: "pkce" }, { label: "Basic Auth", value: "basic" }, - { label: "JWT with Private Key", value: "jwt" }, + { label: "JWT with Private Key", value: "jwtpk" }, ]} > @@ -24,8 +25,8 @@ export default function AuthMethods(props) { - - + + diff --git a/docs/docs/guides/authentication/authmethods/basic.mdx b/docs/docs/guides/authentication/authmethods/basic.mdx index e69de29bb2d..5e4d29a6bd7 100644 --- a/docs/docs/guides/authentication/authmethods/basic.mdx +++ b/docs/docs/guides/authentication/authmethods/basic.mdx @@ -0,0 +1,78 @@ +#### redirect_uri + +After selecting the authentication method, you can register a redirect_uri and post_logout_redirect_uri. +The redirect_uri will be called after user authentication for code exchange. + +You can even register multiple, but typically one will be enough. If you need to distinguish between different scenarios +or environments we recommend using the `state` parameter for the former and multiple projects for the latter. + +## Auth Request + +To initialize the user authentication, you will have to create an authorization request using HTTP GET in the user agent (browser) +on /authorize with at least the following parameters: + +- `client_id`: this tells the authorization server which application it is, copy from Console +- `redirect_uri`: where the authorization code is sent to after the user authentication, must be one of the registered in the previous step +- `response_type`: if you want to have a code (authorization code flow) or directly a token (implicit flow), so when ever possible use `code` +- `scope`: what scope you want to grant to the access_token / id_token, minimum is `openid`, if you're unsure what you need you might start with `openid profile email` + +We recommend always using two additional parameters `state` and `nonce`. The former enables you to transfer a state through +the authentication process. The latter is used to bind the client session with the id_token and to mitigate replay attacks. + +You don't need any additional parameter for this request. We're identifying the app by the `client_id` parameter. + +So your request might look like this (linebreaks and whitespace for display reasons): + +```curl +curl --request GET \ + --url 'https://accounts.zitadel.ch/oauth/v2/authorize + ?client_id=${client_id} + &redirect_uri=${redirect_uri} + &response_type=code + &scope=openid%20email%20profile' +``` + +### Additional parameters and customization + +There are additional parameters and values you can provide to satisfy your use case and to customize the user's authentication flow. +Please check the [authorization_endpoint reference](/docs/apis/openidoauth/endpoints#authorization_endpoint) in the OAuth / OIDC documentation. + +## Callback + +Regardless of a successful or error response from the authorization_endpoint, the authorization server will call your +callback endpoint you provided by the `redirect_uri`. + +:::note +If the redirect_uri is not provided, was not registered or anything other prevents the auth server form returning the response to the client, +the error will be display directly to the user on the auth server. +::: + +Upon successful authentication you'll be given a `code` and if provided the unmodified `state` parameter. +You will need this `code` in the token request. + +If a parameter was missing, malformed or any other error occurred, your answer will contain an `error` stating the error type, +possibly an `error_description` providing some information about the error and its reason and the `state` parameter. +Check the [error response section](/docs/apis/openidoauth/endpoints#error-response) in the authorization_endpoint reference. + +## Token request + +Next you will have to exchange the given `code` for the tokens. For this HTTP POST request (form-urlencoded) you will need to provide the following: + +- code: the code that was issued from the authorization request +- grant_type: must be `authorization_code` +- redirect_uri: callback uri where the code was sent to. Must match exactly the redirect_uri of the authorization request + +Depending on your authentication method you'll need additional headers and parameters: + +Send your `client_id` and `client_secret` as Basic Auth Header. Note that OAuth2 requires client_id and client_secret to be form url encoded. +So check [Client Secret Basic Auth Method](/docs/apis/openidoauth/authn-methods#client-secret-basic) on how to build it correctly. + +```curl +curl --request POST \ +--url https://api.zitadel.ch/oauth/v2/token \ +--header 'Authorization: Basic ${basic}' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--data grant_type=authorization_code \ +--data code=${code} \ +--data redirect_uri=${redirect_uri} +``` diff --git a/docs/docs/guides/authentication/authmethods/implicit.mdx b/docs/docs/guides/authentication/authmethods/implicit.mdx index b993bd41106..a2893972a9b 100644 --- a/docs/docs/guides/authentication/authmethods/implicit.mdx +++ b/docs/docs/guides/authentication/authmethods/implicit.mdx @@ -7,4 +7,43 @@ We therefore discourage the use of Implicit Flow and do not cover the flow in th ::: If you still need to rely on the implicit flow, simply keep in mind that the response on the authorization_endpoint is -the same you would be given on the token_endpoint and check the [OAuth / OIDC endpoint documentation](../../../apis/openidoauth/endpoints.md) for more information. +the same you would be given on the token_endpoint and check the [OAuth / OIDC endpoint documentation](/docs/apis/openidoauth/endpoints) for more information. + +#### redirect_uri + +After selecting the authentication method, you can register a redirect_uri and post_logout_redirect_uri. +The redirect_uri will be called after user authentication for code exchange. + +You can even register multiple, but typically one will be enough. If you need to distinguish between different scenarios +or environments we recommend using the `state` parameter for the former and multiple projects for the latter. + +## Auth Request + +To initialize the user authentication, you will have to create an authorization request using HTTP GET in the user agent (browser) +on /authorize with at least the following parameters: + +- `client_id`: this tells the authorization server which application it is, copy from Console +- `redirect_uri`: where the authorization code is sent to after the user authentication, must be one of the registered in the previous step +- `response_type`: if you want to have a code (authorization code flow) or directly a token (implicit flow), so when ever possible use `code` +- `scope`: what scope you want to grant to the access_token / id_token, minimum is `openid`, if you're unsure what you need you might start with `openid profile email` + +When using the Implicit Flow you will also have to provide a `nonce` parameter to bind the client session to the id_token and to mitigate replay attacks. Furthermore, we recommend using a `state` parameter, which enables you to transfer a state through the authentication process. + +### Additional parameters and customization + +There are additional parameters and values you can provide to satisfy your use case and to customize the user's authentication flow. +Please check the [authorization_endpoint reference](/docs/apis/openidoauth/endpoints#authorization_endpoint) in the OAuth / OIDC documentation. + +## Callback + +Regardless of a successful or error response from the authorization_endpoint, the authorization server will call your callback endpoint you provided by the `redirect_uri`. + +:::note +If the redirect_uri is not provided, was not registered or anything other prevents the auth server form returning the response to the client, the error will be display directly to the user on the auth server. +::: + +Upon successful authentication you'll be given the `access_token`, `id_token`, `expires_in` and if provided the unmodified `state` parameter, as you would be given from the token_endpoint when using Authorization Code Flow. + +If a parameter was missing, malformed or any other error occurred, your answer will contain an `error` stating the error type, +possibly an `error_description` providing some information about the error and its reason and the `state` parameter. +Check the [error response section](/docs/apis/openidoauth/endpoints#error-response) in the authorization_endpoint reference. diff --git a/docs/docs/guides/authentication/authmethods/jwtpk.mdx b/docs/docs/guides/authentication/authmethods/jwtpk.mdx new file mode 100644 index 00000000000..484c4088546 --- /dev/null +++ b/docs/docs/guides/authentication/authmethods/jwtpk.mdx @@ -0,0 +1,79 @@ +#### redirect_uri + +After selecting the authentication method, you can register a redirect_uri and post_logout_redirect_uri. +The redirect_uri will be called after user authentication for code exchange. + +You can even register multiple, but typically one will be enough. If you need to distinguish between different scenarios +or environments we recommend using the `state` parameter for the former and multiple projects for the latter. + +## Auth Request + +To initialize the user authentication, you will have to create an authorization request using HTTP GET in the user agent (browser) +on /authorize with at least the following parameters: + +- `client_id`: this tells the authorization server which application it is, copy from Console +- `redirect_uri`: where the authorization code is sent to after the user authentication, must be one of the registered in the previous step +- `response_type`: if you want to have a code (authorization code flow) or directly a token (implicit flow), so when ever possible use `code` +- `scope`: what scope you want to grant to the access_token / id_token, minimum is `openid`, if you're unsure what you need you might start with `openid profile email` + +We recommend always using two additional parameters `state` and `nonce`. The former enables you to transfer a state through +the authentication process. The latter is used to bind the client session with the id_token and to mitigate replay attacks. + +You don't need any additional parameter for this request. We're identifying the app by the `client_id` parameter. + +So your request might look like this (linebreaks and whitespace for display reasons): + +```curl +curl --request GET \ + --url 'https://accounts.zitadel.ch/oauth/v2/authorize + ?client_id=${client_id} + &redirect_uri=${redirect_uri} + &response_type=code + &scope=openid%20email%20profile' +``` + +### Additional parameters and customization + +There are additional parameters and values you can provide to satisfy your use case and to customize the user's authentication flow. +Please check the [authorization_endpoint reference](/docs/apis/openidoauth/endpoints#authorization_endpoint) in the OAuth / OIDC documentation. + +## Callback + +Regardless of a successful or error response from the authorization_endpoint, the authorization server will call your +callback endpoint you provided by the `redirect_uri`. + +:::note +If the redirect_uri is not provided, was not registered or anything other prevents the auth server form returning the response to the client, +the error will be display directly to the user on the auth server. +::: + +Upon successful authentication you'll be given a `code` and if provided the unmodified `state` parameter. +You will need this `code` in the token request. + +If a parameter was missing, malformed or any other error occurred, your answer will contain an `error` stating the error type, +possibly an `error_description` providing some information about the error and its reason and the `state` parameter. +Check the [error response section](/docs/apis/openidoauth/endpoints#error-response) in the authorization_endpoint reference. + +## Token request + +Next you will have to exchange the given `code` for the tokens. For this HTTP POST request (form-urlencoded) you will need to provide the following: + +- code: the code that was issued from the authorization request +- grant_type: must be `authorization_code` +- redirect_uri: callback uri where the code was sent to. Must match exactly the redirect_uri of the authorization request + +Depending on your authentication method you'll need additional headers and parameters: + +Send a JWT in the `client_assertion` and set the `client_assertion_type` to `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` +for us to validate the signature against the registered public key: + +```curl +curl --request POST \ +--url https://api.zitadel.ch/oauth/v2/token \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--data grant_type=authorization_code \ +--data code=${code} \ +--data redirect_uri=${redirect_uri} \ +--data client_assertion=${client_assertion} \ +--data client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer +``` diff --git a/docs/docs/guides/authentication/authmethods/pkce.mdx b/docs/docs/guides/authentication/authmethods/pkce.mdx index 5f410017657..b065b920945 100644 --- a/docs/docs/guides/authentication/authmethods/pkce.mdx +++ b/docs/docs/guides/authentication/authmethods/pkce.mdx @@ -5,3 +5,84 @@ The redirect_uri will be called after user authentication for code exchange. You can even register multiple, but typically one will be enough. If you need to distinguish between different scenarios or environments we recommend using the `state` parameter for the former and multiple projects for the latter. + +## Auth Request + +To initialize the user authentication, you will have to create an authorization request using HTTP GET in the user agent (browser) +on /authorize with at least the following parameters: + +- `client_id`: this tells the authorization server which application it is, copy from Console +- `redirect_uri`: where the authorization code is sent to after the user authentication, must be one of the registered in the previous step +- `response_type`: if you want to have a code (authorization code flow) or directly a token (implicit flow), so when ever possible use `code` +- `scope`: what scope you want to grant to the access_token / id_token, minimum is `openid`, if you're unsure what you need you might start with `openid profile email` + +We recommend always using two additional parameters `state` and `nonce`. The former enables you to transfer a state through +the authentication process. The latter is used to bind the client session with the id_token and to mitigate replay attacks. + +PKCE stands for Proof Key for Code Exchange. So other than "normal" code exchange, the does not authenticate using +client_id and client_secret but an additional code. You will have to generate a random string, hash it and send this hash +on the authorization_endpoint. On the token_endpoint you will then send the plain string for the authorization to compute +the hash as well and to verify it's correct. In order to do so you're required to send the following two parameters as well: + +- `code_challenge`: the base64url representation of the (sha256) hash of your random string +- `code_challenge_method`: must always be `S256` standing for sha256, this is the only algorithm we support + +For example for `random-string` the code_challenge would be `9az09PjcfuENS7oDK7jUd2xAWRb-B3N7Sr3kDoWECOY` + +The request would finally look like (linebreaks and whitespace for display reasons): + +```curl +curl --request GET \ + --url 'https://accounts.zitadel.ch/oauth/v2/authorize + ?client_id=${client_id} + &redirect_uri=${redirect_uri} + &response_type=code + &scope=openid%20email%20profile + &code_challenge=${code_challenge} + &code_challenge_method=S256' +``` + +### Additional parameters and customization + +There are additional parameters and values you can provide to satisfy your use case and to customize the user's authentication flow. +Please check the [authorization_endpoint reference](/docs/apis/openidoauth/endpoints#authorization_endpoint) in the OAuth / OIDC documentation. + +## Callback + +Regardless of a successful or error response from the authorization_endpoint, the authorization server will call your +callback endpoint you provided by the `redirect_uri`. + +:::note +If the redirect_uri is not provided, was not registered or anything other prevents the auth server form returning the response to the client, +the error will be display directly to the user on the auth server. +::: + +Upon successful authentication you'll be given a `code` and if provided the unmodified `state` parameter. +You will need this `code` in the token request. + +If a parameter was missing, malformed or any other error occurred, your answer will contain an `error` stating the error type, +possibly an `error_description` providing some information about the error and its reason and the `state` parameter. +Check the [error response section](/docs/apis/openidoauth/endpoints#error-response) in the authorization_endpoint reference. + +## Token request + +Next you will have to exchange the given `code` for the tokens. For this HTTP POST request (form-urlencoded) you will need to provide the following: + +- code: the code that was issued from the authorization request +- grant_type: must be `authorization_code` +- redirect_uri: callback uri where the code was sent to. Must match exactly the redirect_uri of the authorization request + +Depending on your authentication method you'll need additional headers and parameters: + +Send your `client_id` and the previously generated string as `code_verifier` for us to recompute the `code_challenge` of the authorization request: + +```curl +curl --request POST \ +--url https://api.zitadel.ch/oauth/v2/token \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--data grant_type=authorization_code \ +--data code=${code} \ +--data redirect_uri=${redirect_uri} \ +--data client_id=${client_id} \ +--data code_verifier=${code_verifier} +``` diff --git a/docs/docs/guides/authentication/authmethods/pkcenative.mdx b/docs/docs/guides/authentication/authmethods/pkcenative.mdx index 53922d666a0..1f9e0c517b5 100644 --- a/docs/docs/guides/authentication/authmethods/pkcenative.mdx +++ b/docs/docs/guides/authentication/authmethods/pkcenative.mdx @@ -16,3 +16,48 @@ by the user agent. If one is sent we will check if the origin is allowed for you origins of the redirect_uri list are allowed. So if your native app is built with a JavaScript base framework like ReactNative and you only specified redirect_uris with a custom protocol, you will need to add the origin where the app is served from, e.g. `http://localhost:8100`. + +### Additional parameters and customization + +There are additional parameters and values you can provide to satisfy your use case and to customize the user's authentication flow. +Please check the [authorization_endpoint reference](/docs/apis/openidoauth/endpoints#authorization_endpoint) in the OAuth / OIDC documentation. + +## Callback + +Regardless of a successful or error response from the authorization_endpoint, the authorization server will call your +callback endpoint you provided by the `redirect_uri`. + +:::note +If the redirect_uri is not provided, was not registered or anything other prevents the auth server form returning the response to the client, +the error will be display directly to the user on the auth server. +::: + +Upon successful authentication you'll be given a `code` and if provided the unmodified `state` parameter. +You will need this `code` in the token request. + +If a parameter was missing, malformed or any other error occurred, your answer will contain an `error` stating the error type, +possibly an `error_description` providing some information about the error and its reason and the `state` parameter. +Check the [error response section](/docs/apis/openidoauth/endpoints#error-response) in the authorization_endpoint reference. + +## Token request + +Next you will have to exchange the given `code` for the tokens. For this HTTP POST request (form-urlencoded) you will need to provide the following: + +- code: the code that was issued from the authorization request +- grant_type: must be `authorization_code` +- redirect_uri: callback uri where the code was sent to. Must match exactly the redirect_uri of the authorization request + +Depending on your authentication method you'll need additional headers and parameters: + +Send your `client_id` and the previously generated string as `code_verifier` for us to recompute the `code_challenge` of the authorization request: + +```curl +curl --request POST \ +--url https://api.zitadel.ch/oauth/v2/token \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--data grant_type=authorization_code \ +--data code=${code} \ +--data redirect_uri=${redirect_uri} \ +--data client_id=${client_id} \ +--data code_verifier=${code_verifier} +``` diff --git a/docs/docs/guides/authentication/login-users.mdx b/docs/docs/guides/authentication/login-users.mdx index a9f63b6f412..8254dfba045 100644 --- a/docs/docs/guides/authentication/login-users.mdx +++ b/docs/docs/guides/authentication/login-users.mdx @@ -71,7 +71,6 @@ recommend using POST and will not cover it in this guide. Please change the authentication method here as well, if you did so in the wizard, so we can better guide you through the process: - @@ -81,8 +80,8 @@ Please change the authentication method here as well, if you did so in the wizar When selecting Native the authentication method always needs to be PKCE. - + #### Authentication method @@ -93,179 +92,3 @@ are able to successfully authenticate with PKCE. Our Managament UI Console for i - -## Auth Request - -To initialize the user authentication, you will have to create an authorization request using HTTP GET in the user agent (browser) -on /authorize with at least the following parameters: - -- `client_id`: this tells the authorization server which application it is, copy from Console -- `redirect_uri`: where the authorization code is sent to after the user authentication, must be one of the registered in the previous step -- `response_type`: if you want to have a code (authorization code flow) or directly a token (implicit flow), so when ever possible use `code` -- `scope`: what scope you want to grant to the access_token / id_token, minimum is `openid`, if you're unsure what you need you might start with `openid profile email` - -We recommend always using two additional parameters `state` and `nonce`. The former enables you to transfer a state through -the authentication process. The latter is used to bind the client session with the id_token and to mitigate replay attacks. - -Depending on your authentication method you might need to provide additional parameters: - - - - -PKCE stands for Proof Key for Code Exchange. So other than "normal" code exchange, the does not authenticate using -client_id and client_secret but an additional code. You will have to generate a random string, hash it and send this hash -on the authorization_endpoint. On the token_endpoint you will then send the plain string for the authorization to compute -the hash as well and to verify it's correct. In order to do so you're required to send the following two parameters as well: - -- `code_challenge`: the base64url representation of the (sha256) hash of your random string -- `code_challenge_method`: must always be `S256` standing for sha256, this is the only algorithm we support - -For example for `random-string` the code_challenge would be `9az09PjcfuENS7oDK7jUd2xAWRb-B3N7Sr3kDoWECOY` - -The request would finally look like (linebreaks and whitespace for display reasons): - -```curl -curl --request GET \ - --url 'https://accounts.zitadel.ch/oauth/v2/authorize - ?client_id=${client_id} - &redirect_uri=${redirect_uri} - &response_type=code - &scope=openid%20email%20profile - &code_challenge=${code_challenge} - &code_challenge_method=S256' -``` - - - - -You don't need any additional parameter for this request. We're identifying the app by the `client_id` parameter. - -So your request might look like this (linebreaks and whitespace for display reasons): - -```curl -curl --request GET \ - --url 'https://accounts.zitadel.ch/oauth/v2/authorize - ?client_id=${client_id} - &redirect_uri=${redirect_uri} - &response_type=code - &scope=openid%20email%20profile' -``` - - - - -You don't need any additional parameter for this request. We're identifying the app by the `client_id` parameter. - -So your request might look like this (linebreaks and whitespace for display reasons): - -```curl -curl --request GET \ - --url 'https://accounts.zitadel.ch/oauth/v2/authorize - ?client_id=${client_id} - &redirect_uri=${redirect_uri} - &response_type=code - &scope=openid%20email%20profile' -``` - - - - -### Additional parameters and customization - -There are additional parameters and values you can provide to satisfy your use case and to customize the user's authentication flow. -Please check the [authorization_endpoint reference](../../apis/openidoauth/endpoints#authorization_endpoint) in the OAuth / OIDC documentation. - -## Callback - -Regardless of a successful or error response from the authorization_endpoint, the authorization server will call your -callback endpoint you provided by the `redirect_uri`. - -:::note -If the redirect_uri is not provided, was not registered or anything other prevents the auth server form returning the response to the client, -the error will be display directly to the user on the auth server. -::: - -Upon successful authentication you'll be given a `code` and if provided the unmodified `state` parameter. -You will need this `code` in the token request. - -If a parameter was missing, malformed or any other error occurred, your answer will contain an `error` stating the error type, -possibly an `error_description` providing some information about the error and its reason and the `state` parameter. -Check the [error response section](../../apis/openidoauth/endpoints#error-response) in the authorization_endpoint reference. - -## Token request - -Next you will have to exchange the given `code` for the tokens. For this HTTP POST request (form-urlencoded) you will need to provide the following: - -- code: the code that was issued from the authorization request -- grant_type: must be `authorization_code` -- redirect_uri: callback uri where the code was sent to. Must match exactly the redirect_uri of the authorization request - -Depending on your authentication method you'll need additional headers and parameters: - - - - -Send your `client_id` and the previously generated string as `code_verifier` for us to recompute the `code_challenge` of the authorization request: - -```curl -curl --request POST \ ---url https://api.zitadel.ch/oauth/v2/token \ ---header 'Content-Type: application/x-www-form-urlencoded' \ ---data grant_type=authorization_code \ ---data code=${code} \ ---data redirect_uri=${redirect_uri} \ ---data client_id=${client_id} \ ---data code_verifier=${code_verifier} -``` - - - - -Send your `client_id` and `client_secret` as Basic Auth Header. Note that OAuth2 requires client_id and client_secret to be form url encoded. -So check [Client Secret Basic Auth Method](../../apis/openidoauth/authn-methods#client-secret-basic) on how to build it correctly. - -```curl -curl --request POST \ ---url https://api.zitadel.ch/oauth/v2/token \ ---header 'Authorization: Basic ${basic}' \ ---header 'Content-Type: application/x-www-form-urlencoded' \ ---data grant_type=authorization_code \ ---data code=${code} \ ---data redirect_uri=${redirect_uri} -``` - - - - -Send a JWT in the `client_assertion` and set the `client_assertion_type` to `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` -for us to validate the signature against the registered public key: - -```curl -curl --request POST \ ---url https://api.zitadel.ch/oauth/v2/token \ ---header 'Content-Type: application/x-www-form-urlencoded' \ ---data grant_type=authorization_code \ ---data code=${code} \ ---data redirect_uri=${redirect_uri} \ ---data client_assertion=${client_assertion} \ ---data client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer -``` - - - diff --git a/docs/docs/guides/authentication/serviceusers.md b/docs/docs/guides/authentication/serviceusers.md index bac1c44ba29..695e5dbbc0b 100644 --- a/docs/docs/guides/authentication/serviceusers.md +++ b/docs/docs/guides/authentication/serviceusers.md @@ -29,7 +29,7 @@ title: Service Users -import UserDescription from '../../concepts/zitadel/objects/_user_description.mdx'; +import UserDescription from '../../concepts/structure/_user_description.mdx'; diff --git a/docs/docs/guides/basics/get-started.mdx b/docs/docs/guides/basics/get-started.mdx index 6205af01f91..247f1743683 100644 --- a/docs/docs/guides/basics/get-started.mdx +++ b/docs/docs/guides/basics/get-started.mdx @@ -43,3 +43,4 @@ After creating your project you can start integrating your applications. After choosing your [project](https://console.zitadel.ch/projects) add a client application on the top of the page. The wizard should provide some guidance what client is the proper for you. If you are still unsure consult our [Guide Project](projects). +## Learn more diff --git a/docs/docs/guides/basics/organizations.mdx b/docs/docs/guides/basics/organizations.mdx index 65eee89e816..2327cd51f44 100644 --- a/docs/docs/guides/basics/organizations.mdx +++ b/docs/docs/guides/basics/organizations.mdx @@ -11,7 +11,7 @@ title: Organizations ## What is an organization? -import OrgDescription from '../../concepts/zitadel/objects/_org_description.mdx'; +import OrgDescription from '../../concepts/structure/_org_description.mdx'; import Column from '../../../src/components/column'; diff --git a/docs/docs/guides/basics/projects.md b/docs/docs/guides/basics/projects.md index 33f447390eb..51875a77b8d 100644 --- a/docs/docs/guides/basics/projects.md +++ b/docs/docs/guides/basics/projects.md @@ -11,7 +11,7 @@ title: Projects ## What is a project? -import ProjectDescription from '../../concepts/zitadel/objects/_project_description.mdx'; +import ProjectDescription from '../../concepts/structure/_project_description.mdx'; @@ -57,7 +57,7 @@ Now create another project (eg. “My second project”) and verify that there a ## What is a granted project? -import GrantedProjectDescription from '../../concepts/zitadel/objects/_granted_project_description.mdx'; +import GrantedProjectDescription from '../../concepts/structure/_granted_project_description.mdx'; diff --git a/docs/docs/guides/overview.mdx b/docs/docs/guides/overview.mdx index cc5f76d3159..2f9ad914acb 100644 --- a/docs/docs/guides/overview.mdx +++ b/docs/docs/guides/overview.mdx @@ -2,8 +2,8 @@ title: Overview --- -import {ListElement, ListWrapper, ICONTYPE} from '../../src/components/list'; -import Column from '../../src/components/column'; +import { ListElement, ListWrapper, ICONTYPE } from "../../src/components/list"; +import Column from "../../src/components/column"; With our guides you will learn everything you need to know about specific topics. You get step-by-step instructions for certain tasks and have a knowledge check at the end. @@ -13,22 +13,85 @@ When you are familiar with the ZITADEL usage, you can choose to stay on [zitadel - - - + + + - - + + - + - - + + + + + + - + diff --git a/docs/docs/guides/solution-scenarios/b2b.mdx b/docs/docs/guides/solution-scenarios/b2b.mdx new file mode 100644 index 00000000000..01ef70c530a --- /dev/null +++ b/docs/docs/guides/solution-scenarios/b2b.mdx @@ -0,0 +1,85 @@ +--- +title: B2B +--- + +import { B2B } from '../../../src/components/b2b'; + +## Business to Business + +B2B describes the situation where an organization interacts with other organizations. +This **multiple organization architecture** usually adds some form of complexity to an Identity and Access Management System. +In ZITADEL a B2B organization represents a business partner or partner who typically has its own branding and has different access settings like an additional federated login for its users. + +B2B can be a simple scenario where an organization only shares one of its projects with another organization or have a more complex case where an organization is offering a portal application to all its partners with included (self)administration. + + +## Sample scenario + +Octagon is a fictitious company which is used throughout this guide to explain the details and key concepts of such a B2B scenario. +Octagon tries to solve multiple tasks in the banking field. Its portfolio includes several applications for their employees, customers, and partners. Some of which are web-based, some of which are used by machine users only. + +### Portal Application + +Octagon has a **Portal application** where its employees can access their account and list all applications they are allowed to use. +Employees work for a department within Octagon or for Octagon itself. +Some of the users have enhanced features because they supervise certain teams. Those can onboard new employees and manage their roles and features. +Target groups of the application can be split into: +- **Employees:** users who are using the application as a starting point for their work. +- **Supervisors:** users who are mainly using the application to manage users and their access of their department. +- **Administrators:** this users are able to grant additional organizations or departments and elect supervisors. + +### Planning considerations + +In order to define the need of the **Portal Application** some planning considerations about organizations have to be made: + +- **Login and Access:** Does a user have a preset organization to login? Does the application show the default login page or does each organization use its own branding? +- **Organizations:** Does a user have access in multiple organizations? Is a user required to use a different federated login for those organizations? +- **Roles** Does the application need users to have specific roles assigned within their organizations? Which roles are needed to enable certain features of the application? + +### Login + +You can decide whether a organization is preselected for the login or if the user is redirected to the default login screen. You can send the user to a specific organization by defining the organization in a custom scope. (primary domain) +Settings to the branding or the login options of the organization can be made from the organization section in [Console](https://console.zitadel.ch/org). +The behaviour of the login branding can be set in your projects detail page. You can choose the branding of the selected organization, the user resource owner, or the projects resource owner. + +### Organizations + +Generally a user belongs to and is managed by one organization, however the user can receive authorizations from multiple other organizations (delegated authorizations). Anyways, a user should be able to use the same identity to switch between organizations. +If this feature is not desired, a separate user for each organization should be created. + +Adding a user from a different organization to the audience of a project can be as easy as adding a new user authorization (user grant). A user grant combines a user from any organization with a project and 0-N roles. + +In our sample scenario, we assume to have the following users: + +- **Dimitri:** a team leader who is employed by Pentagon, an Octagon department. Dimitri uses his Microsoft Account in combination with his one time password to access the portal. Pentagon therefore has set up Microsoft as Identity Provider. Pentagon also requires its users to secure their accounts with additional factors. +- **Michael:** a trainee of Pentagon only using the portal to access his workspace apps. Michael uses his Google Account in combination with his laptops fingerprint. +- **Bill:** is employed at Octagon as Administrator of the Portal Application. Bill also uses a Microsoft Account in combination with a Security Key to secure his account. + +After having determined the constellation of the organizations and its users, all the necessary data (Portal project with roles and app, users, login requirements, identity providers, branding) should be set up in [Console](https://console.zitadel.ch/org). +A B2B sample application for NextJS can be found in our [Example Repo](https://github.com/caos/zitadel-examples). + +To allow another organization to use a project, a project grant has to be created. Upon creation, roles for a grant can be limited to a subset of the total project roles. + +In our scenario, Octagon creates a project grant for Pentagon. Pentagon is limited to use `writer` and `reader` role. The `admin` role is reserved for the Octagon organization itself. + + + +### Roles + +In this scenario, Dimitri and Michael share the same organization Pentagon, where as Bill belongs to Octagon. Octagon is owner of the Portal project with its Web App, having Bill configured as user grant with `admin` role. Dimitri owns the `writer` role, whereas Michael only is `reader`. + +> Note: Roles are meant for internal business logic and therefore need to be validated separately, none of the users described are allowed to create user grants, at least if they do not own a ZITADEL manager role. + +If you made a dashboard where some users are able to create user grants, the Management API to do such operations should be triggered with the personal access token of the users, not with a token of a machine user, to create a meaningful audit log. +If you had such a use case, ZITADEL manager roles must be assigned to those users. + +### Noteworthy + +Due to the fact that ZITADEL includes unlimited users, projects, and applications and comes with all security features in the FREE tier, ZITADEL can be considered a great alternative to other SaaS IAM systems such as Auth0 or Okta. +In such a case with this high potential of scalability where user counts can grow explosively, ZITADEL does not become the bottleneck and therefore is the valid choice. You can learn more on ZITADELs benefits and the pricing [here](https://zitadel.ch/pricing). + +### Learn more + +- [Creating an organization](../basics/organizations#exercise---create-a-new-organization) +- [Organization Branding](../customization/branding) +- [Authorization](../authorization/oauth-recommended-flows) \ No newline at end of file diff --git a/docs/docs/guides/solution-scenarios/b2c.mdx b/docs/docs/guides/solution-scenarios/b2c.mdx new file mode 100644 index 00000000000..8c7f17768ef --- /dev/null +++ b/docs/docs/guides/solution-scenarios/b2c.mdx @@ -0,0 +1,107 @@ +--- +title: B2C +--- + +import Column from "../../../src/components/column"; + +## Business to Consumer + +Users in general come with different needs. You may have end users, employees, or even customers from other parties (B2B). +This groups of users usually don't share the same intentions and use applications differently. +When planning your applications, investing time in researching your apps architecture is vital for later feature upgrades and enhancements as those changes come in with heftier price points if you have to make bigger changes. + +This guide introduces you to the grouping and structuring of ZITADEL projects which forms the base for all projects. This can be used as a quick start to the [B2B scenario](./b2b), which is merely focused on planning considerations if you are having projects with multiple organizations. + +The journey of this guide starts with creating an Organization, the outermost layer of ZITADEL, as it is the vessel for projects, roles, applications and users. +Creation can be done from [ZITADEL Console](https://console.zitadel.ch/org/create). You can choose your current account for the organization owner or create a new one. + +Depending on your Software Development Life Cycle (SDLC) you can create multiple organizations or projects to keep your applications environments seperated. + +### Custom domain + +Right after org creation you'll be greeted with the domain section of your organization. ZITADEL automatically creates a custom domain of the form `[orgname].zitadel.ch`, but you can set your own by saving a verification file on the specified location. +We recommend that you create your domains early as they create a sense of confidence and trust for your application and changes later on might create additional migration effort. +You can read more about how ZITADEL handles usernames [here](../basics/organizations#how-zitadel-handles-usernames). + +### Data Provisioning + +ZITADEL gives you a basic storage for users and manages phone and email addresses. It also allows you to store your own application data such as preferences or external identifiers to the metadata of a user. + +If you are migrating an existing project and you already have an external identity store you can consider bulk importing your user datasets. +Read our [Management API definitions](../../apis/proto/management#importhumanuser) for more info. If the users email is not verified or no password is set, a initialization mail will be send. + +:::info +Requests to the management API are rate limited. Read our [Rate limit Policy](../../legal/rate-limit-policy) for more info. +::: + +### User Authentication + +User Authentication can be performed in multiple ways. Default method in ZITADEL is username and password with MFA enabled. +ZITADEL allows you to configure Multifactor- and Passwordless Authentication in order to enhance security for your users. All authentication methods are available from the FREE Tier. +To setup your organizations login policy, go to your organizations detail in [Console](https://console.zitadel.ch/org). + +When planning your application consider the following questions about User Authentication: + +- What are the methods to authenticate your users? +- Where will your users enter their credentials? +- Do you offer password authentication? +- What do you do to keep your users credentials safe? +- Do you offer Multifactor Authentication? +- Do you offer Login via Identity Provider? +- Which languages do you have to provide? + +When looking at this questions, you may have to admit that building an Identity Management System is much more complex and complicated than you thought initially and implementing if yourself may be too much work. +Particularly because you should focus building your applications. + +### Federation + +ZITADEL supports signup with OIDC Identity providers as well as JWT Identity Providers. On signup, ZITADEL imports user information to the own profile. +//TODO extend this passage + +### Hosted Login + +ZITADEL offers a "secure by default approach" and comes with a Hosted Login which is a fixed endpoint for your users to authenticate. +It's safe and secure and comes with Multifactor, Federated Login and Passwordless capabilities. +OIDC (OpenID Connect) opens the doors to Single Sign On (SSO). Especially if you have more than one application, you may want a central and familiar authentication experience. +With SSO, ZITADEL provides a seamless experience across all your apps. + +### Branding + + +
+ +Branding and customization is a very important part of your application. +With ZITADEL you can modify colors, logos, icons as well as configure your typography styles, such that you can provide a consistent design throughout your applications. +In addition to visual modifications, you can edit notification texts for your users. +ZITADEL gives you handlebar similar templating for variables. Of course you can define texts for any language. +We'd appreciate if you could contribute to our repo with translations of your language. Read on how to contribute [here](../../guides/customization/texts). + +> Note that your console design changes to your design too + +
+branding in console +
+ +### Projects and applications + +As our Hosted Login is a separate authentication screen, you have to determine how you are directing your users from your applications. +ZITADEL's Applications live under ZITADEL's Projects. You may add multiple applications for your different client-types (Native, Web, User Agent, or API). When setting up your applications consider reading our guide about [Authentication Flows](../authentication/login-users). + +### Access Control + +By having authenticated a user you need to ensure users and services have access to your application and APIs. This process is called Access Control and comprises User Authentication, Authorization and Policy Enforcement. +Take the following considerations: + +- Does your application call your own APIs? +- Does your application need to call third-party APIs? +- Do **you** offer an API for third-party applications? + +The data required to check if a user has access to a certain API is stored within a user grant. This information typically is stored within roles or custom claims and can be accessed with an `access` or OIDC `id` token. + +Read more about Authorization in our [Guide](../authorization/oauth-recommended-flows). + +## Learn more + +- [Creating an organization](../basics/organizations#exercise---create-a-new-organization) +- [Organization Branding](../customization/branding) +- [Authorization](../authorization/oauth-recommended-flows) diff --git a/docs/docs/guides/solution-scenarios/introduction.mdx b/docs/docs/guides/solution-scenarios/introduction.mdx new file mode 100644 index 00000000000..b6d51fbcb06 --- /dev/null +++ b/docs/docs/guides/solution-scenarios/introduction.mdx @@ -0,0 +1,34 @@ +--- +title: Introduction +--- + +import { + ListElement, + ListWrapper, + ICONTYPE, +} from "../../../src/components/list"; +import Column from "../../../src/components/column"; + +## Solution Scenarios + +Customers of an SaaS Identity and Access Management System usually have all distinct use cases and requirements. +This guide attempts to explain real-world implementations and break them down into **Solution Scenarios** which aim to help you getting started with ZITADEL. + + + + + diff --git a/docs/docs/legal/dedicated-instance-annex.md b/docs/docs/legal/dedicated-instance-annex.md index b2715cf5c4b..a653536f369 100644 --- a/docs/docs/legal/dedicated-instance-annex.md +++ b/docs/docs/legal/dedicated-instance-annex.md @@ -74,4 +74,4 @@ Performance SLO | up to [rate limits](https://docs.zitadel.ch/docs/legal/rate-li ### Backup -ZITADEL Cloud creates hourly backups. We do not guarantee recovery time objective. Recovery point objective is in the context of our [event-sourcing pattern](/docs/concepts/general/eventstore) not meaningful. +ZITADEL Cloud creates hourly backups. We do not guarantee recovery time objective. Recovery point objective is in the context of our [event-sourcing pattern](../concepts/eventstore) not meaningful. diff --git a/docs/sidebars.js b/docs/sidebars.js index 0f3dc94b80f..0c6afe7638b 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -1,288 +1,286 @@ module.exports = { - quickstarts: [ - 'quickstarts/introduction', - { - type: 'category', - label: 'Integrate ZITADEL Login in your App', - items: ['quickstarts/login/angular', 'quickstarts/login/react', 'quickstarts/login/flutter', 'quickstarts/login/nextjs'], - collapsed: false, - }, - { - type: 'category', - label: 'Secure your API', - items: ['quickstarts/secure-api/go', 'quickstarts/secure-api/dot-net'], - collapsed: false, - }, - { - type: 'category', - label: 'Call the ZITADEL API', - items: ['quickstarts/call-zitadel-api/go', 'quickstarts/call-zitadel-api/dot-net'], - collapsed: false, - }, - { - type: 'category', - label: 'Identity Aware Proxy', - items: ['quickstarts/identity-proxy/oauth2-proxy'], - collapsed: false, - } - ], - guides: [ - 'guides/overview', - { - type: 'category', - label: 'Get to know ZITADEL', - collapsed: false, - items: [ - 'guides/basics/get-started', - 'guides/basics/organizations', - 'guides/basics/projects', - ], - }, - { - type: 'category', - label: 'Authentication', - collapsed: false, - items: [ - 'guides/authentication/login-users', - 'guides/authentication/identity-brokering', - 'guides/authentication/serviceusers', - ], - }, - { - type: 'category', - label: 'Authorization', - collapsed: false, - items: [ - 'guides/authorization/oauth-recommended-flows', - ], - }, - { - type: 'category', - label: 'API', - collapsed: false, - items: [ - 'guides/api/access-zitadel-apis' - ], - }, - { - type: 'category', - label: 'Customization', - collapsed: false, - items: [ - 'guides/customization/branding', - 'guides/customization/texts', - ], - }, - { - type: 'category', - label: 'Installation', - collapsed: false, - items: [ - { - type: 'category', - label: 'CAOS Managed', - collapsed: true, - items: [ - 'guides/installation/shared-cloud', - 'guides/installation/managed-dedicated-instance' - ], - }, - { - type: 'category', - label: 'CAOS Service Packages', - collapsed: true, - items: [ - 'guides/installation/setup', - 'guides/installation/setup-orbos', - 'guides/installation/checkup' - ], - }, - { - type: 'category', - label: 'Self Managed', - collapsed: true, - items: [ - 'guides/installation/crd', - 'guides/installation/gitops', - 'guides/installation/orbos' - ], - }, - ], - }, - { - type: 'category', - label: 'Trainings', - collapsed: false, - items: [ - 'guides/trainings/introduction', - { - type: 'category', - label: 'Support Service', - collapsed: true, - items: [ - 'guides/trainings/supportservice/operations', - 'guides/trainings/supportservice/application', - 'guides/trainings/supportservice/recurring', - ], - }, - ], - } - ], - apis: [ - 'apis/introduction', - { - type: 'category', - label: 'API Definition', - collapsed: false, - items: [ - { - type: 'category', - label: 'Proto', - collapsed: true, - items: [ - 'apis/proto/auth', - 'apis/proto/management', - 'apis/proto/admin', - 'apis/proto/org', - 'apis/proto/user', - 'apis/proto/app', - 'apis/proto/policy', - 'apis/proto/auth_n_key', - 'apis/proto/change', - 'apis/proto/idp', - 'apis/proto/member', - 'apis/proto/metadata', - 'apis/proto/message', - 'apis/proto/text', - 'apis/proto/object', - 'apis/proto/options' - ], - }, - { - type: 'category', - label: 'Assets API', - collapsed: true, - items: [ - 'apis/assets/assets', - ], - }, - ], - }, - { - type: 'category', - label: 'OpenID Connect & OAuth', - collapsed: false, - items: [ - 'apis/openidoauth/endpoints', - 'apis/openidoauth/scopes', - 'apis/openidoauth/claims', - 'apis/openidoauth/authn-methods', - 'apis/openidoauth/grant-types' - ], - }, + quickstarts: [ + "quickstarts/introduction", + { + type: "category", + label: "Integrate ZITADEL Login in your App", + items: [ + "quickstarts/login/angular", + "quickstarts/login/react", + "quickstarts/login/flutter", + "quickstarts/login/nextjs", + ], + collapsed: false, + }, + { + type: "category", + label: "Secure your API", + items: ["quickstarts/secure-api/go", "quickstarts/secure-api/dot-net"], + collapsed: false, + }, + { + type: "category", + label: "Call the ZITADEL API", + items: [ + "quickstarts/call-zitadel-api/go", + "quickstarts/call-zitadel-api/dot-net", + ], + collapsed: false, + }, + { + type: "category", + label: "Identity Aware Proxy", + items: ["quickstarts/identity-proxy/oauth2-proxy"], + collapsed: false, + }, + ], + guides: [ + "guides/overview", + { + type: "category", + label: "Get to know ZITADEL", + collapsed: false, + items: [ + "guides/basics/get-started", + "guides/basics/organizations", + "guides/basics/projects", + ], + }, + { + type: "category", + label: "Solution Scenarios", + collapsed: false, + items: [ + "guides/solution-scenarios/introduction", + "guides/solution-scenarios/b2c", + "guides/solution-scenarios/b2b", + ], + }, + { + type: "category", + label: "Authentication", + collapsed: false, + items: [ + "guides/authentication/login-users", + "guides/authentication/identity-brokering", + "guides/authentication/serviceusers", + ], + }, + { + type: "category", + label: "Authorization", + collapsed: false, + items: ["guides/authorization/oauth-recommended-flows"], + }, + { + type: "category", + label: "API", + collapsed: false, + items: ["guides/api/access-zitadel-apis"], + }, + { + type: "category", + label: "Customization", + collapsed: false, + items: ["guides/customization/branding", "guides/customization/texts"], + }, + + { + type: "category", + label: "Installation", + collapsed: true, + items: [ { - type: 'category', - label: 'Rate Limits', - collapsed: false, + type: "category", + label: "CAOS Managed", + collapsed: true, items: [ - 'legal/rate-limit-policy', - 'apis/ratelimits/accounts', - 'apis/ratelimits/api', + "guides/installation/shared-cloud", + "guides/installation/managed-dedicated-instance", ], }, - ], - concepts: [ - 'concepts/introduction', - { - type: 'category', - label: 'ZITADEL', - collapsed: false, - items: [ - 'concepts/zitadel/architecture', - { - type: 'category', - label: "Object Overview", - collapsed: false, - items: [ - 'concepts/zitadel/objects/overview', - 'concepts/zitadel/objects/organizations', - 'concepts/zitadel/objects/policies', - 'concepts/zitadel/objects/projects', - 'concepts/zitadel/objects/applications', - 'concepts/zitadel/objects/granted_projects', - 'concepts/zitadel/objects/users', - 'concepts/zitadel/objects/managers', - ], - }, - ], - }, { - type: 'category', - label: 'General', - collapsed: false, - items: [ - 'concepts/general/principles', - 'concepts/general/eventstore', - ], - }, { - type: 'category', - label: 'Use Cases', - collapsed: false, - items: [ - 'concepts/usecases/saas' - ], + type: "category", + label: "CAOS Service Packages", + collapsed: true, + items: [ + "guides/installation/setup", + "guides/installation/setup-orbos", + "guides/installation/checkup", + ], }, - - ], - manuals: [ - 'manuals/introduction', { - type: 'category', - label: 'User', - items: ['manuals/user-register', 'manuals/user-login', 'manuals/user-passwordless', 'manuals/user-password', 'manuals/user-factors', 'manuals/user-email', 'manuals/user-phone', 'manuals/user-social-login',], - collapsed: false, + type: "category", + label: "Self Managed", + collapsed: true, + items: [ + "guides/installation/crd", + "guides/installation/gitops", + "guides/installation/orbos", + ], }, - 'manuals/troubleshooting' - ], - legal: [ - 'legal/introduction', - 'legal/terms-of-service', - 'legal/data-processing-agreement', + ], + }, + { + type: "category", + label: "Trainings", + collapsed: true, + items: [ + "guides/trainings/introduction", { - type: 'category', - label: 'Service Descriptions', - collapsed: false, - items: [ - 'legal/service-level-description', - 'legal/support-services', - ], + type: "category", + label: "Support Service", + collapsed: true, + items: [ + "guides/trainings/supportservice/operations", + "guides/trainings/supportservice/application", + "guides/trainings/supportservice/recurring", + ], }, + ], + }, + ], + apis: [ + "apis/introduction", + { + type: "category", + label: "API Definition", + collapsed: false, + items: [ { - type: 'category', - label: 'Dedicated Instance', - collapsed: false, - items: [ - 'legal/terms-of-service-dedicated', - 'legal/dedicated-instance-annex', - ], + type: "category", + label: "Proto", + collapsed: true, + items: [ + "apis/proto/auth", + "apis/proto/management", + "apis/proto/admin", + "apis/proto/org", + "apis/proto/user", + "apis/proto/app", + "apis/proto/policy", + "apis/proto/auth_n_key", + "apis/proto/change", + "apis/proto/idp", + "apis/proto/member", + "apis/proto/metadata", + "apis/proto/message", + "apis/proto/text", + "apis/proto/object", + "apis/proto/options", + ], }, { - type: 'category', - label: 'Support Program', - collapsed: false, - items: [ - 'legal/terms-support-service' - ], + type: "category", + label: "Assets API", + collapsed: true, + items: ["apis/assets/assets"], }, - { - type: 'category', - label: 'Policies', - collapsed: false, - items: [ - 'legal/privacy-policy', - 'legal/acceptable-use-policy', - 'legal/rate-limit-policy' - ], - } - ], + ], + }, + { + type: "category", + label: "OpenID Connect & OAuth", + collapsed: false, + items: [ + "apis/openidoauth/endpoints", + "apis/openidoauth/scopes", + "apis/openidoauth/claims", + "apis/openidoauth/authn-methods", + "apis/openidoauth/grant-types", + ], + }, + { + type: "category", + label: "Rate Limits", + collapsed: false, + items: [ + "legal/rate-limit-policy", + "apis/ratelimits/accounts", + "apis/ratelimits/api", + ], + }, + ], + concepts: [ + "concepts/introduction", + "concepts/principles", + "concepts/eventstore", + "concepts/architecture", + { + type: "category", + label: "Structure", + collapsed: true, + items: [ + "concepts/structure/overview", + "concepts/structure/organizations", + "concepts/structure/policies", + "concepts/structure/projects", + "concepts/structure/applications", + "concepts/structure/granted_projects", + "concepts/structure/users", + "concepts/structure/managers", + ], + }, + { + type: "category", + label: "Use Cases", + collapsed: false, + items: ["concepts/usecases/saas"], + }, + ], + manuals: [ + "manuals/introduction", + { + type: "category", + label: "User", + items: [ + "manuals/user-register", + "manuals/user-login", + "manuals/user-passwordless", + "manuals/user-password", + "manuals/user-factors", + "manuals/user-email", + "manuals/user-phone", + "manuals/user-social-login", + ], + collapsed: false, + }, + "manuals/troubleshooting", + ], + legal: [ + "legal/introduction", + "legal/terms-of-service", + "legal/data-processing-agreement", + { + type: "category", + label: "Service Descriptions", + collapsed: false, + items: ["legal/service-level-description", "legal/support-services"], + }, + { + type: "category", + label: "Dedicated Instance", + collapsed: false, + items: [ + "legal/terms-of-service-dedicated", + "legal/dedicated-instance-annex", + ], + }, + { + type: "category", + label: "Support Program", + collapsed: false, + items: ["legal/terms-support-service"], + }, + { + type: "category", + label: "Policies", + collapsed: false, + items: [ + "legal/privacy-policy", + "legal/acceptable-use-policy", + "legal/rate-limit-policy", + ], + }, + ], }; diff --git a/docs/src/components/b2b.jsx b/docs/src/components/b2b.jsx new file mode 100644 index 00000000000..9a61c01559f --- /dev/null +++ b/docs/src/components/b2b.jsx @@ -0,0 +1,47 @@ +import React from 'react'; + +export function B2B() { + return ( +
+
+ Octagon (owner) +
+ Portal Project + +
+ WEBAPP +
+ + reader, writer, admin +
+ +
+ Bill (admin) +
+
+ + + +
+ Pentagon +
+ Portal Project (grant) + +
+ WEBAPP +
+ + reader, writer +
+ +
+ Dimitri (writer) +
+ +
+ Michael (reader) +
+
+
+ ); +} diff --git a/docs/src/components/list.jsx b/docs/src/components/list.jsx index ebd98d22b4f..3facf81787f 100644 --- a/docs/src/components/list.jsx +++ b/docs/src/components/list.jsx @@ -6,6 +6,12 @@ export const ICONTYPE = { START:
, + TASKS:
+ +
, + ARCHITECTURE:
+ +
, LOGIN:
, @@ -21,6 +27,15 @@ export const ICONTYPE = { SERVICE:
, + STORAGE:
+ +
, + FOLDER:
+ +
, + FILE:
+ +
, SYSTEM:
, @@ -58,11 +73,13 @@ export const ICONTYPE = { , }; -export function ListElement({ link, iconClasses, type, title, description}) { +export function ListElement({ link, iconClasses,roundClasses, label, type, title, description}) { return ( {type ? type : - iconClasses &&
+ iconClasses &&
+ { label ? {label}: } +
}

{title}

@@ -75,8 +92,19 @@ export function ListElement({ link, iconClasses, type, title, description}) { export function ListWrapper({children, title, columns}) { return (
- {title} + {title && {title}} {children}
) +} + +export function HomeListWrapper({children, image}) { + return ( +
+ {image} +
+ {children} +
+
+ ) } \ No newline at end of file diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 4f1e3975ca4..6bafa4177fa 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -58,6 +58,12 @@ --apimgmtbackground: linear-gradient(40deg, #c6d7f3 30%, #c7c6e3); --apiadminbackground: linear-gradient(40deg, #c192c790, #c192c790); --apiassetbackground: linear-gradient(40deg, #e4eaf1, #eef2f9); + --overlaycolor: #6c90b420; + --ifm-hero-text-color: #ffffff; +} + +.get-started { + border-radius: 50vw; } .apicard-right { @@ -211,6 +217,12 @@ h2 { --apimgmtbackground: linear-gradient(40deg, #595d8090 30%, #595d8090); --apiadminbackground: linear-gradient(40deg, #6a506e90, #6a506e90); --apiassetbackground: linear-gradient(40deg, #3c4257, #3c4257); + --overlaycolor: #ffffff15; + --ifm-hero-text-color: #023c2a; +} + +.get-started:hover { + color: #ffffff !important; } .menu li li a { @@ -234,6 +246,8 @@ main .container img { padding: .5rem; margin-right: 1rem; border-radius: 50%; + width: 40px; + height: 40px; } .rounded svg { @@ -262,12 +276,18 @@ main .container img { .rounded-privatelabel, .rounded-phone, .rounded-email, +.rounded-storage, .rounded-service { background: linear-gradient(40deg, #3b82f6 30%, #4f46e5); } +.rounded-split { + background: linear-gradient(40deg, #3b82f6, #4f46e5); +} + .rounded-texts, -.rounded-help { +.rounded-help, +.rounded-architecture { background: linear-gradient(40deg, #dc2626 30%, #db2777); } @@ -284,6 +304,10 @@ main .container img { padding: 0 var(--ifm-pre-padding); } +.hero__title { + color: white; +} + .get-started { border: 2px solid var(--get-started); background-color: var(--get-started); @@ -295,6 +319,10 @@ main .container img { color: var(--ifm-hero-text-color); } +.docs-link { + margin-bottom: 2rem; +} + .docs-link a { text-decoration: none; color: inherit; @@ -306,4 +334,51 @@ main .container img { .docs-link img { margin: 40px; +} + +.b2borg, +.b2bproject, +.b2bapp, +.b2buser { + border-radius: 1rem; + background: var(--overlaycolor); + padding: 1rem; +} + +.b2buser { + margin-top: 1rem; +} + +.b2borg span, +.b2bproject span, +.b2bapp span, +.b2buser span { + margin-left: 1rem; + margin-bottom: 1rem; + display: block; +} + +.flexrowbetween { + display: flex; + justify-content: space-around; + margin: 2rem 0; +} + +.arrowright { + height: 2rem; + width: auto; + align-self: center; + min-width: 2rem; +} + +.b2bprojectrole { + margin: 1rem 0 0 1rem !important; +} + +.footer__link-item { + font-size: 14px; +} + +.footer__link-item svg { + margin-left: .5rem; } \ No newline at end of file diff --git a/docs/src/css/list.module.css b/docs/src/css/list.module.css index d6117ffaa43..459286fe7a2 100644 --- a/docs/src/css/list.module.css +++ b/docs/src/css/list.module.css @@ -31,11 +31,15 @@ padding: .5rem 1rem .5rem .5rem; } +.listlabel { + color: white; +} + .listWrapper { display: flex; flex-direction: column; background: var(--list-background); - border-radius: .5rem; + border-radius: 1rem; padding: 1rem; } @@ -44,4 +48,18 @@ font-size: 16px; margin-bottom: .5rem; display: block; +} + +.homerow { + display: flex; + flex-direction: row; + align-items: flex-start; +} + +.homecontent { + flex: 1; + display: flex; + flex-direction: column; + align-items: stretch; + padding: 1rem 0; } \ No newline at end of file diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js index 29b109dd701..da555daadef 100644 --- a/docs/src/pages/index.js +++ b/docs/src/pages/index.js @@ -6,98 +6,274 @@ import ThemedImage from '@theme/ThemedImage'; import clsx from 'clsx'; import React from 'react'; +import Column from '../components/column'; +import { HomeListWrapper, ICONTYPE, ListElement, ListWrapper } from '../components/list'; import styles from './styles.module.css'; const features = [ { - title: 'Guides', - darkImageUrl: 'img/index/Guides-dark.svg', - lightImageUrl: 'img/index/Guides-light.svg', - link: 'docs/guides/overview', + title: "Guides", + darkImageUrl: "img/index/Guides-dark.svg", + lightImageUrl: "img/index/Guides-light.svg", + link: "docs/guides/overview", description: ( <> - Read our guides on how to manage your data and role associations in ZITADEL and on what we recommend. + Read our guides on how to manage your data and role associations in + ZITADEL and on what we recommend. ), + content: ( + + +
+ + + + +
+
+ + + + +
+
+
+ ), }, { - title: 'Quickstarts', - darkImageUrl: 'img/index/Quickstarts-dark.svg', - lightImageUrl: 'img/index/Quickstarts-light.svg', - link: 'docs/quickstarts/introduction', + title: "Quickstarts", + darkImageUrl: "img/index/Quickstarts-dark.svg", + lightImageUrl: "img/index/Quickstarts-light.svg", + link: "docs/quickstarts/introduction", description: ( - <> - Learn how to integrate your applications and build secure workflows and APIs with ZITADEL - + <> + Learn how to integrate your applications and build secure workflows and + APIs with ZITADEL + + ), + content: ( +
+ + + + +
), }, { - title: 'APIs', - darkImageUrl: 'img/index/APIs-dark.svg', - lightImageUrl: 'img/index/APIs-light.svg', - link: '/docs/apis/introduction', + title: "APIs", + darkImageUrl: "img/index/APIs-dark.svg", + lightImageUrl: "img/index/APIs-light.svg", + link: "/docs/apis/introduction", description: ( - <> - Learn more about our APIs and how to integrate them in your apps. - + <>Learn more about our APIs and how to integrate them in your apps. + ), + content: ( +
+ + + + +
), }, { - title: 'Concepts', - darkImageUrl: 'img/index/Concepts-dark.svg', - lightImageUrl: 'img/index/Concepts-light.svg', - link: 'docs/concepts/introduction', + title: "Concepts", + darkImageUrl: "img/index/Concepts-dark.svg", + lightImageUrl: "img/index/Concepts-light.svg", + link: "docs/concepts/introduction", description: ( <> - Learn more about engineering and design principles, ZITADELs architecture and used technologies. + Learn more about engineering and design principles, ZITADELs + architecture and used technologies. ), + content: ( + + + + + + + ), }, ]; -function Feature({darkImageUrl, lightImageUrl, title, description, link}) { +function QuickstartLink({ link, title, imageSource, lightImageSource }) { + return ( + + {/* {`${title}`}/ */} + +

{title}

+ + ); +} + +function Feature({ + darkImageUrl, + lightImageUrl, + title, + description, + link, + content, +}) { const darkImgUrl = useBaseUrl(darkImageUrl); const lightImgUrl = useBaseUrl(lightImageUrl); + + const themedImage = ( + + ); return ( -
- - {darkImgUrl && lightImgUrl && ( -
- -
- )} -

{title}

-

{description}

- +
+ {darkImgUrl && lightImgUrl && ( +
+ + +

+ {title} + +

+ +

{description}

+ + {content} +
+ )} +
); } export default function Home() { const context = useDocusaurusContext(); - const {siteConfig = {}} = context; + const { siteConfig = {} } = context; return ( -
+ description="This site bundles ZITADELs Documentations" + > +

{siteConfig.title}

{siteConfig.tagline}

+ to={useBaseUrl("docs/guides/basics/get-started")} + > Get Started
diff --git a/docs/src/pages/styles.module.css b/docs/src/pages/styles.module.css index c1aa85121c9..01d9ca39012 100644 --- a/docs/src/pages/styles.module.css +++ b/docs/src/pages/styles.module.css @@ -32,6 +32,72 @@ } .featureImage { - height: 200px; - width: 200px; + height: 70px; + width: 70px; + margin: 1rem 1rem 1rem 0 !important; } + +.homelink:hover, +.homelink:hover i { + color: var(--ifm-link-color); +} + +.homelinkicon { + font-size: 1.2rem; +} + +.quickstartcontainer { + padding: 0; + border-radius: 1rem; + display: flex; + flex-wrap: wrap; + flex-direction: row; + margin: -0.5rem; +} + +.quickstart { + flex: 1; + padding: 1rem; + margin: 0.5rem; + min-width: 200px; + display: flex; + align-items: center; + background: var(--list-background); + border-radius: 1rem; +} + +.quickstart p { + margin: 0; + font-size: 1.5rem; +} + +.quickstartlinkimg { + height: 80px; + width: 80px; + margin: 1rem 1rem 1rem 0 !important; + border-radius: 1rem; + background-size: cover; + object-fit: contain; + background-position: center; +} + + +@media screen and (max-width: 600px) { + .quickstartcontainer { + flex-direction: column; + } + + .quickstartlinkimg { + height: 60px; + width: 60px; + } + + .featureImage { + height: 50px; + width: 50px; + } +} + +.apilinks h2 { + font-size: 1rem; +} \ No newline at end of file diff --git a/docs/static/img/guides/branding.jpeg b/docs/static/img/guides/branding.jpeg new file mode 100644 index 00000000000..dd87c5e87a5 Binary files /dev/null and b/docs/static/img/guides/branding.jpeg differ diff --git a/docs/static/img/tech/nextjslight.svg b/docs/static/img/tech/nextjslight.svg new file mode 100644 index 00000000000..803afe1d4b3 --- /dev/null +++ b/docs/static/img/tech/nextjslight.svg @@ -0,0 +1,18 @@ + + + + next-black + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file