docs: rework documentation site (#1589)

* initial commit

* inital changes

* commit WIP Information Architecture

* commit a working state

* add static assets and project

* add org and fix img names

* add plausible

* remove img

* change sidebar to easier mgmt

* add openid oauth and domains

* lint md

* quickstarts

* add auth flow

* identity brokering

* remove site

* fix broken links

* extend footer

* extend readme

* fix: styling

* fix: zitadel logo on index

* styling

* border

* fix: nav

* fix: nav

* fix: index

* fix: rename architecture to concepts

* fix: introductions

* fix: introductions

* fix: introductions

* fix: get started

* fix: user manual

* fix: zitadel architecture

* fix: dead links

* add favicon

Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Florian Forster 2021-04-15 13:22:37 +02:00 committed by GitHub
parent c7e7ef8e74
commit dfc9488bb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
248 changed files with 41653 additions and 17764 deletions

View File

@ -1,57 +0,0 @@
name: Docs
on:
push:
branches:
- '**'
tags-ignore:
- '**'
paths:
- 'site/**'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
builddocs:
name: Build Doc Frontend
runs-on: ubuntu-18.04
defaults:
run:
working-directory: ./site
steps:
- name: Checkout Repo
uses: actions/checkout@v2
- uses: docker/build-push-action@v2
with:
context: .
file: ./site/dockerfile
platforms: linux/amd64
tags: zitadel:docs
push: false
outputs: type=local,dest=output
- name: Archive Production Artifact
uses: actions/upload-artifact@master
with:
name: export
path: output
deploydocs:
name: Deploy
needs: builddocs
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout Repo
uses: actions/checkout@master
- name: Download Artifact
uses: actions/download-artifact@master
with:
name: export
path: site/__sapper__/export
- name: Add CNAME file
run: echo "docs.zitadel.ch" > site/__sapper__/export/CNAME
- name: Deploy
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
BRANCH: gh-pages
FOLDER: site/__sapper__/export
CLEAN: true

View File

@ -1,20 +0,0 @@
server:
log_level: debug
http_listen_port: 12345
tempo:
receivers:
otlp:
protocols:
grpc:
endpoint: ":9096"
attributes:
actions:
- action: upsert
key: env
value: prod
push_config:
endpoint: tempo-us-central1.grafana.net:443
basic_auth:
username: $(gopass show caos-secrets/technical/boom/grafana-cloud/tempo-user)
password: $(gopass show caos-secrets/technical/boom/grafana-cloud/tempo-password)

20
docs/.gitignore vendored Normal file
View File

@ -0,0 +1,20 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

34
docs/README.md Normal file
View File

@ -0,0 +1,34 @@
# Website
This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator.
## Add new Sites to existing Topics
To add a new site to the already existing structure simply save the `md` file into the corresponding folder and append the sites id int the file `sidebars.js`.
## Installation
```console
yarn install
```
## Local Development
```console
yarn start
```
This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server.
## Build
```console
yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
## Deployment
Each PR will be automaticly built with a preview link from cloudflare pages.
Visit the checks / comments on the PR for the link.

3
docs/babel.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

3
docs/docs/apis/admin.md Normal file
View File

@ -0,0 +1,3 @@
---
title: Administration
---

3
docs/docs/apis/authn.md Normal file
View File

@ -0,0 +1,3 @@
---
title: Authentication
---

10
docs/docs/apis/domains.md Normal file
View File

@ -0,0 +1,10 @@
---
title: Domains
---
| Domain Name | Example | Description |
| :---------- | :-------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| issuer | `issuer.zitadel.ch` | Provides the [OpenID Connect 1.0 Discovery Endpoint](openidoauth/endpoints#openid-connect-10-discovery) |
| api | `api.zitadel.ch` | All ZITADEL API's are located under this domain. |
| login | `accounts.zitadel.ch` | The accounts.* page provides server renderer pages like login and register and as well the authorization_endpoint for OpenID Connect |
| console | `console.zitadel.ch` | With the console.* domain we serve the assets for the management gui |

View File

@ -1,10 +1,7 @@
---
title: Overview
description: …
title: Introduction
---
<i class="las la-code" style="font-size: 100px; height: 100px; color:#6c8eef" ></i>
> All documentations are under active work and subject to change soon!
### APIs

3
docs/docs/apis/mgmt.md Normal file
View File

@ -0,0 +1,3 @@
---
title: Management
---

View File

@ -0,0 +1,71 @@
---
title: Authentication Methods
---
## Client Secret Basic
When using `client_secret_basic` on 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) )
```
Given the client_id `78366401571920522@amce` and client_secret `veryweaksecret!`, this would result in the following `Authorization` header:
`Basic NzgzNjY0MDE1NzE5MjA1MjIlNDBhbWNlOnZlcnl3ZWFrc2VjcmV0JTIx`
## JWT with Private Key
When using `private_key_jwt` for token or introspection endpoints, provide a JWT as assertion generated with the following structure and signed with a downloaded key:
---
Key JSON
| Key | Example | Description |
|:---------|:--------------------------------------------------------------------|:-------------------------------------------------------------------------------|
| type | `"application"` | The type of account, right now only application is valid |
| keyId | `"81693565968962154"` | This is unique ID of the key |
| key | `"-----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----"` | The private key generated by ZITADEL, this can not be regenerated! |
| clientId | `78366401571920522@acme` | The client_id of the application, this is the same as the subject from tokens |
| appId | `78366403256846242` | The id of the application (just for completeness, not used for JWT) |
```JSON
{
"type": "application",
"keyId": "81693565968962154",
"key": "-----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----",
"clientId": "78366401571920522@acme",
"appId": "78366403256846242"
}
```
---
JWT
| Claim | Example | Description |
|:------|:------------------------------|:----------------------------------------------------------------------------------------------------------------|
| aud | `"https://issuer.zitadel.ch"` | String or Array of intended audiences MUST include ZITADEL's issuing domain |
| exp | `1605183582` | Unix timestamp of the expiry, MUST NOT be longer than 1h |
| iat | `1605179982` | Unix timestamp of the creation singing time of the JWT |
| iss | `"78366401571920522@acme"` | String which represents the requesting party (owner of the key), normally the `clientID` from the json key file |
| sub | `"78366401571920522@acme"` | The subject ID of the application, normally the `clientID` from the json key file |
```JSON
{
"iss": "78366401571920522@acme",
"sub": "78366401571920522@acme",
"aud": "https://issuer.zitadel.ch",
"exp": 1605183582,
"iat": 1605179982
}
```
> To identify your key, it is necessary that you provide a JWT with a `kid` header claim representing your keyId from the Key JSON:
>
> ```json
> {
> "alg": "RS256",
> "kid": "81693565968962154"
> }
> ```

View File

@ -0,0 +1,71 @@
---
title: Claims
---
ZITADEL asserts claims on different places according to the corresponding specifications or project and clients settings.
Please check below the matrix for an overview where which scope is asserted.
| Claims | Userinfo | Introspection | ID Token | Access Token |
|:------------------------------------------------|:---------------|----------------|---------------------------------------------|--------------------------------------|
| acr | No | No | Yes | No |
| address | When requested | When requested | When requested amd response_type `id_token` | No |
| amr | No | No | Yes | No |
| aud | No | No | Yes | When JWT |
| auth_time | No | No | Yes | No |
| azp | No | No | Yes | When JWT |
| email | When requested | When requested | When requested amd response_type `id_token` | No |
| email_verified | When requested | When requested | When requested amd response_type `id_token` | No |
| exp | No | No | Yes | When JWT |
| family_name | When requested | When requested | When requested amd response_type `id_token` | No |
| gender | When requested | When requested | When requested amd response_type `id_token` | No |
| given_name | When requested | When requested | When requested amd response_type `id_token` | No |
| iat | No | No | Yes | When JWT |
| iss | No | No | Yes | When JWT |
| locale | When requested | When requested | When requested amd response_type `id_token` | No |
| name | When requested | When requested | When requested amd response_type `id_token` | No |
| nonce | No | No | Yes | No |
| phone | When requested | When requested | When requested amd response_type `id_token` | No |
| phone_verified | When requested | When requested | When requested amd response_type `id_token` | No |
| preferred_username (username when Introspect ) | When requested | When requested | Yes | No |
| sub | Yes | Yes | Yes | When JWT |
| urn:zitadel:iam:org:domain:primary:{domainname} | When requested | When requested | When requested | When JWT and requested |
| urn:zitadel:iam:org:project:roles:{rolename} | When requested | When requested | When requested or configured | When JWT and requested or configured |
## Standard Claims
| Claims | Example | Description |
|:-------------------|:-----------------------------------------|-----------------------------------------------------------------------------------------------|
| acr | TBA | TBA |
| address | `Teufener Strasse 19, 9000 St. Gallen` | TBA |
| amr | `pwd mfa` | Authentication Method References as defined in [RFC8176](https://tools.ietf.org/html/rfc8176) |
| aud | `69234237810729019` | By default all client id's and the project id is included |
| auth_time | `1311280969` | Unix time of the authentication |
| azp | `69234237810729234` | Client id of the client who requested the token |
| email | `road.runner@acme.ch` | Email Address of the subject |
| email_verified | `true` | Boolean if the email was verified by ZITADEL |
| exp | `1311281970` | Time the token expires as unix time |
| family_name | `Runner` | The subjects family name |
| gender | `other` | Gender of the subject |
| given_name | `Road` | Given name of the subject |
| iat | `1311280970` | Issued at time of the token as unix time |
| iss | `https://issuer.zitadel.ch` | Issuing domain of a token |
| locale | `en` | Language from the subject |
| name | `Road Runner` | The subjects full name |
| nonce | `blQtVEJHNTF0WHhFQmhqZ0RqeHJsdzdkd2d...` | The nonce provided by the client |
| phone | `+41 79 XXX XX XX` | Phone number provided by the user |
| preferred_username | `road.runner@acme.caos.ch` | ZITADEL's login name of the user. Consist of `username@primarydomain` |
| sub | `77776025198584418` | Subject ID of the user |
## Custom Claims
> This feature is not yet released
## Reserved Claims
ZITADEL reserves some claims to assert certain data.
| Claims | Example | Description |
|:------------------------------------------------|:-----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| urn:zitadel:iam:org:domain:primary:{domainname} | `{"urn:zitadel:iam:org:domain:primary": "acme.ch"}` | This claim represents the primary domain of the organization the user belongs to. |
| urn:zitadel:iam:org:project:roles:{rolename} | `{"urn:zitadel:iam:org:project:roles": [ {"user": {"id1": "acme.zitade.ch", "id2": "caos.ch"} } ] }` | When roles are asserted, ZITADEL does this by providing the `id` and `primaryDomain` below the role. This gives you the option to check in which organization a user has the role. |
| urn:zitadel:iam:roles:{rolename} | TBA | TBA |

View File

@ -0,0 +1,194 @@
---
title: Endpoints
---
## OpenID Connect 1.0 Discovery
The OpenID Connect Discovery Endpoint is located within the issuer domain.
For example with [zitadel.ch](https://zitadel.ch), issuer.zitadel.ch would be the domain. This would give us [https://issuer.zitadel.ch/.well-known/openid-configuration](https://issuer.zitadel.ch/.well-known/openid-configuration).
**Link to spec.** [OpenID Connect Discovery 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-discovery-1_0.html)
## authorization_endpoint
[https://accounts.zitadel.ch/oauth/v2/authorize](https://accounts.zitadel.ch/oauth/v2/authorize)
> The authorization_endpoint is located with the login page, due to the need of accessing the same cookie domain
Required request Parameters
| Parameter | Description |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| client_id | The id of your client as shown in Console. |
| redirect_uri | Callback uri of the authorization request where the code or tokens will be sent to. Must match exactly one of the preregistered in Console. |
| response_type | Determines whether a `code`, `id_token token` or just `id_token` will be returned. Most use cases will need `code`. See flow guide for more info. |
| scope | `openid` is required, see [Scopes](scopes) for more possible values. Scopes are space delimited, e.g. `openid email profile` |
Required parameters for PKCE (see PKCE guide for more information)
| Parameter | Description |
| --------------------- | ----------------------------------------------------- |
| code_challenge | The SHA-256 value of the generated code_verifier |
| code_challenge_method | Method used to generate the challenge, must be `S256` |
Optional parameters
| Parameter | Description |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id_token_hint | Valid `id_token` (of an existing session) used to identity the subject. Should be provided when using prompt `none`. |
| login_hint | A valid logon name of a user. Will be used for username inputs or preselecting a user on `select_account` |
| max_age | Seconds since the last active successful authentication of the user |
| nonce | Random string value to associate the client session with the ID Token and for replay attacks mitigation. |
| prompt | If the Auth Server prompts the user for (re)authentication. <br />no prompt: the user will have to choose a session if more than one session exists<br />`none`: user must be authenticated without interaction, an error is returned otherwise <br />`login`: user must reauthenticate / provide a user name <br />`select_account`: user is prompted to select one of the existing sessions or create a new one |
| state | Opaque value used to maintain state between the request and the callback. Used for Cross-Site Request Forgery (CSRF) mitigation as well. |
Successful Code Response
| Property | Description |
| -------- | ----------------------------------------------------------------------------- |
| code | Opaque string which will be necessary to request tokens on the token endpoint |
| state | Unmodified `state` parameter from the request |
Successful Implicit Response
| Property | Description |
| ------------ | ----------------------------------------------------------- |
| access_token | Only returned if `response_type` included `token` |
| expires_in | Number of second until the expiration of the `access_token` |
| id_token | Only returned if `response_type` included `id_token` |
| token_type | Type of the `access_token`. Value is always `Bearer` |
Error Response
Regardless of the authorization flow chosen, if an error occurs the following response will be returned to the redirect_uri.
> 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
| Property | Description |
| ----------------- | -------------------------------------------------------------------- |
| error | An OAuth / OIDC error_type |
| error_description | Description of the error type or additional information of the error |
| state | Unmodified `state` parameter from the request |
## token_endpoint
[https://api.zitadel.ch/oauth/v2/token](https://api.zitadel.ch/oauth/v2/token)
### Authorization Code Grant (Code Exchange)
Required request Parameters
| Parameter | Description |
| ------------ | ------------------------------------------------------------------------------------------------------------- |
| code | Code that was issued from the authorization request. |
| grant_type | Must be `authorization_code` |
| redirect_uri | Callback uri where the code was be sent to. Must match exactly the redirect_uri of the authorization request. |
Depending on your authorization method you will have to provide additional parameters or headers:
When using `client_secret_basic`
Send your `client_id` and `client_secret` as Basic Auth Header. Check [Client Secret Basic Auth Method](authn-methods#client-secret-basic) on how to build it correctly.
When using `client_secret_post`
Send your `client_id` and `client_secret` as parameters in the body:
| Parameter | Description |
| ------------- | -------------------------------- |
| client_id | client_id of the application |
| client_secret | client_secret of the application |
When using `none` (PKCE)
Send your code_verifier for us to recompute the code_challenge of the authorization request.
| Parameter | Description |
| ------------- | ------------------------------------------------------------ |
| code_verifier | code_verifier previously used to generate the code_challenge |
When using `private_key_jwt`
Send a client assertion as JWT for us to validate the signature against the registered public key.
| Parameter | Description |
| --------------------- | --------------------------------------------------------------------------------------------------------------- |
| client_assertion | JWT built and signed according to [Using JWTs for Client Authentication](authn-methods#jwt-with-private-key) |
| client_assertion_type | Must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` |
### JWT Profile Grant
---
Required request Parameters
| Parameter | Description |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| grant_type | Must be `urn:ietf:params:oauth:grant-type:jwt-bearer` |
| assertion | JWT built and signed according to [Using JWTs for Client Authentication](#Using JWTs for Client Authentication) |
| scope | [Scopes](Scopes) you would like to request from ZITADEL. Scopes are space delimited, e.g. `openid email profile` |
```BASH
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=DKLvnksjndjsflkdjlkfgjslow... \
--data client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
--data client_assertion=eyJhbGciOiJSUzI1Ni...
```
## introspection_endpoint
[https://api.zitadel.ch/oauth/v2/introspect](https://api.zitadel.ch/oauth/v2/introspect)
| Parameter | Description |
| --------- | --------------- |
| token | An access token |
Depending on your authorization method you will have to provide additional parameters or headers:
When using `client_secret_basic`
Send your `client_id` and `client_secret` as Basic Auth Header. Check [Client Secret Basic Auth Method](authn-methods#client-secret-basic) on how to build it correctly.
---
When using `private_key_jwt`
Send a client assertion as JWT for us to validate the signature against the registered public key.
| Parameter | Description |
| --------------------- | ----------------------------------------------------------------------------------------------------------- |
| client_assertion | JWT built and signed according to [Using JWTs for Client Authentication](authn-methods#client-secret-basic) |
| client_assertion_type | must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` |
```BASH
curl --request POST \
--url https://api.zitadel.ch/oauth/v2/introspect \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
--data client_assertion=eyJhbGciOiJSUzI1Ni... \
--data token=VjVxyCZmRmWYqd3_F5db9Pb9mHR5fqzhn...
```
## userinfo_endpoint
[https://api.zitadel.ch/oauth/v2/userinfo](https://api.zitadel.ch/oauth/v2/userinfo)
## end_session_endpoint
[https://accounts.zitadel.ch/oauth/v2/endsession](https://accounts.zitadel.ch/oauth/v2/endsession)
> The end_session_endpoint is located with the login page, due to the need of accessing the same cookie domain
## jwks_uri
[https://api.zitadel.ch/oauth/v2/keys](https://api.zitadel.ch/oauth/v2/keys)
> Be aware that these keys can be rotated without any prior notice. We will however make sure that a proper `kid` is set with each key!
## OAuth 2.0 Metadata
**ZITADEL** does not yet provide a OAuth 2.0 Metadata endpoint but instead provides a [OpenID Connect Discovery Endpoint](#OpenID_Connect_1_0_Discovery).

View File

@ -0,0 +1,133 @@
---
title: Grant Types
---
For a list of supported or unsupported `Grant Types` please have a look at the table below.
| Grant Type | Supported |
|:------------------------------------------------------|:--------------------|
| Authorization Code | yes |
| Authorization Code with PKCE | yes |
| Client Credentials | yes |
| Device Authorization | under consideration |
| Implicit | yes |
| JSON Web Token (JWT) Profile | yes |
| Refresh Token | work in progress |
| Resource Owner Password Credentials | no |
| Security Assertion Markup Language (SAML) 2.0 Profile | no |
| Token Exchange | work in progress |
## Authorization Code
**Link to spec.** [The OAuth 2.0 Authorization Framework Section 1.3.1](https://tools.ietf.org/html/rfc6749#section-1.3.1)
## Proof Key for Code Exchange
**Link to spec.** [Proof Key for Code Exchange by OAuth Public Clients](https://tools.ietf.org/html/rfc7636)
## Implicit
**Link to spec.** [The OAuth 2.0 Authorization Framework Section 1.3.2](https://tools.ietf.org/html/rfc6749#section-1.3.2)
## Client Credentials
**Link to spec.** [The OAuth 2.0 Authorization Framework Section 1.3.4](https://tools.ietf.org/html/rfc6749#section-1.3.4)
## Refresh Token
**Link to spec.** [The OAuth 2.0 Authorization Framework Section 1.5](https://tools.ietf.org/html/rfc6749#section-1.5)
## JSON Web Token (JWT) Profile
**Link to spec.** [JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants](https://tools.ietf.org/html/rfc7523)
### Using JWTs as Authorization Grants
Our service user work with the JWT profile to authenticate them against ZITADEL.
1. Create or use an existing service user
2. Create a new key and download it
3. Generate a JWT with the structure below and sign it with the downloaded key
4. Send the JWT Base64 encoded to ZITADEL's token endpoint
5. Use the received access token
---
Key JSON
| Key | Example | Description |
|:-------|:--------------------------------------------------------------------|:-------------------------------------------------------------------|
| type | `"serviceaccount"` | The type of account, right now only serviceaccount is valid |
| keyId | `"81693565968772648"` | This is unique ID of the key |
| key | `"-----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----"` | The private key generated by ZITADEL, this can not be regenerated! |
| userId | `78366401571647008` | The service users ID, this is the same as the subject from tokens |
```JSON
{
"type": "serviceaccount",
"keyId": "81693565968772648",
"key": "-----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----",
"userId": "78366401571647008"
}
```
---
JWT
| Claim | Example | Description |
|:------|:------------------------------|:--------------------------------------------------------------------------------------------------------------|
| aud | `"https://issuer.zitadel.ch"` | String or Array of intended audiences MUST include ZITADEL's issuing domain |
| exp | `1605183582` | Unix timestamp of the expiry, MUST NOT be longer than 1h |
| iat | `1605179982` | Unix timestamp of the creation singing time of the JWT |
| iss | `"77479219772321307"` | String which represents the requesting party (owner of the key), normally the `userId` from the json key file |
| sub | `"77479219772321307"` | The subject ID of the service user, normally the `userId` from the json key file |
```JSON
{
"iss": "77479219772321307",
"sub": "77479219772321307",
"aud": "https://issuer.zitadel.ch",
"exp": 1605183582,
"iat": 1605179982
}
```
> To identify your key, it is necessary that you provide a JWT with a `kid` header claim representing your keyId from the Key JSON:
>
> ```json
> {
> "alg": "RS256",
> "kid": "81693565968772648"
> }
> ```
---
See [JWT Profile Grant on Token Endpoint](endpoints#token_endpoint) for usage.
### Using JWTs for Client Authentication
See how to build a [JWT for client authentication](authn-methods#jwt-with-private-key) from the downloaded key.
Find out how to use it on the [token endpoint](endpoints#token_endpoint) or the [introspection endpoint](endpoints#introspection_endpoint).
## Token Exchange
**Link to spec.** [OAuth 2.0 Token Exchange](https://tools.ietf.org/html/rfc8693)
## Device Authorization
**Link to spec.** [OAuth 2.0 Device Authorization Grant](https://tools.ietf.org/html/rfc8628)
## Not Supported Grant Types
### Resource Owner Password Credentials
> Due to growing security concerns we do not support this grant type. With OAuth 2.1 it looks like this grant will be removed.
**Link to spec.** [OThe OAuth 2.0 Authorization Framework Section 1.3.3](https://tools.ietf.org/html/rfc6749#section-1.3.3)
### Security Assertion Markup Language (SAML) 2.0 Profile
**Link to spec.** [Security Assertion Markup Language (SAML) 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants](https://tools.ietf.org/html/rfc7522)

View File

@ -0,0 +1,31 @@
---
title: Scopes
---
ZITADEL supports the usage of scopes as way of requesting information from the IAM and also instruct ZITADEL to do certain operations.
## Standard Scopes
| Scopes | Example | Description |
|:--------|:----------|------------------------------------------------------|
| openid | `openid` | When using openid connect this is a mandatory scope |
| profile | `profile` | Optional scope to request the profile of the subject |
| email | `email` | Optional scope to request the email of the subject |
| address | `address` | Optional scope to request the address of the subject |
## Custom Scopes
> This feature is not yet released
## Reserved Scopes
In addition to the standard compliant scopes we utilize the following scopes.
| Scopes | Example | Description |
|:------------------------------------------------|:-------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| urn:zitadel:iam:org:project:role:{rolename} | `urn:zitadel:iam:org:project:role:user` | By using this scope a client can request the claim urn:zitadel:iam:roles:rolename} to be asserted when possible. As an alternative approach you can enable all roles to be asserted from the [project](../../guides/projects) a client belongs to. |
| urn:zitadel:iam:org:domain:primary:{domainname} | `urn:zitadel:iam:org:domain:primary:acme.ch` | When requesting this scope **ZITADEL** will enforce that the user is a member of the selected organization. If the organization does not exist a failure is displayed |
| urn:zitadel:iam:role:{rolename} | | |
| urn:zitadel:iam:org:project:id:{projectid}:aud | ZITADEL's Project id is `urn:zitadel:iam:org:project:id:69234237810729019:aud` | By adding this scope, the requested projectid will be added to the audience of the access and id token |
> If access to ZITADEL's API's is needed with a service user the scope `urn:zitadel:iam:org:project:id:69234237810729019:aud` needs to be used with the JWT Profile request

View File

@ -1,9 +1,7 @@
---
title: Architecture
title: ZITADEL Architecture
---
> Images in better quality follow soon.
### Software Architecture
**ZITADEL** is built with two essential patterns. Eventsourcing and CQRS. Due to the nature of eventsourcing **ZITADEL** provides the unique capability to generate a strong audit trail of ALL the things that happen to its resources, without compromising on storage cost or audit trail length.
@ -12,14 +10,7 @@ The combination with CQRS makes **ZITADEL** eventual consistent which, from our
Each **ZITADEL** contains all components of the IAM, from serving as API, rendering / serving GUI's, background processing of events and task or being a GITOPS style operator. This AiO (All in One) approach makes scaling from a single machine to a multi region (multi cluster) seamless.
<div class="zitadel-gallery" itemscope itemtype="http://schema.org/ImageGallery">
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/zitadel_software_architecture.png" itemprop="contentUrl" data-size="1530x681">
<img src="img/zitadel_software_architecture.png" itemprop="thumbnail" alt="Software Architecture" />
</a>
<figcaption itemprop="caption description">Software Architecture</figcaption>
</figure>
</div>
![Software Architecture](/img/zitadel_software_architecture.png)
#### Component Command Side
@ -67,14 +58,7 @@ If you deploy **ZITADEL** with our GITOPS Tooling [**ORBOS**](https://github.com
> You can horizontaly scale zitadel, but we recommend to use multiple cluster instead to reduce the blast radius from impacts to a single cluster
<div class="zitadel-gallery" itemscope itemtype="http://schema.org/ImageGallery">
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/zitadel_cluster_architecture.png" itemprop="contentUrl" data-size="1530x681">
<img src="img/zitadel_cluster_architecture.png" itemprop="thumbnail" alt="Cluster Architecture" />
</a>
<figcaption itemprop="caption description">Cluster Architecture</figcaption>
</figure>
</div>
![Cluster Architecture](/img/zitadel_cluster_architecture.png)
### Multi Cluster Architecture
@ -89,12 +73,4 @@ With this design even the outage of a whole data-center would have a minimal imp
> East - West connectivity for the database can be solved at you discretion. We recommend to expose the public ips and run traffic directly without any VPN or Mesh
> Use MTLS in combination with IP Allowlist in the firewalls!
<div class="zitadel-gallery" itemscope itemtype="http://schema.org/ImageGallery">
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/zitadel_multicluster_architecture.png" itemprop="contentUrl" data-size="1530x681">
<img src="img/zitadel_multicluster_architecture.png" itemprop="thumbnail" alt="Multi-Cluster Architecture" />
</a>
<figcaption itemprop="caption description">Multi-Cluster Architecture</figcaption>
</figure>
</div>
![Multi-Cluster Architecture](/img/zitadel_multicluster_architecture.png)

View File

@ -1,15 +1,12 @@
---
title: Overview
title: Introduction
---
<i class="las la-project-diagram" style="font-size: 100px; height: 100px; color:#6c8eef"></i>
> All documentations are under active work and subject to change soon!
This part of the **ZITADEL** documentation comprises three major subject areas:
This part of the **ZITADEL** documentation comprises twoo major subject areas:
1. Principles
2. Architecture
3. Protocols
1. ZITADEL Architecture
2. Principles
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 dont hesitate to leave a comment or propose a corresponding change.

View File

@ -1,24 +1,29 @@
---
title: ZITADEL.ch
description: A quick-start reference to use our cloud instance zitadel.ch
title: Get started
---
Most applications need to know the identity of a user allowing to securely store user data in the cloud and provide the same personalised experience across all of the user's devices.
ZITADEL's authentication provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users in your application. It supports authentication using passwords and applies additional security with the help of a second factor, for example OTP, to ensure a safe and secure access.
It additionally leverages industry standards like OAuth 2.0 and OpenID Connect such that it can be easily integrated in your custom backend.
This documentation demonstrates the different installation methods of ZITADEL and provides a quick start guide on how to register your organization as well as creating your first project.
## Trying out ZITADEL
### Installation Types
You can either use our cloud-instance [zitadel.ch](https://zitadel.ch) or deploy a dedicated **ZITADEL** instance. To get started, we recommend you to try out our free tier first.
### Use cloud instance zitadel.ch
To create a ZITADEL project, you have to register as an organization first. Click [here](https://accounts.zitadel.ch/register/org) to register.
You will receive an email prompting you to verify your mail.
Then go to your [Console Projects](https://console.zitadel.ch/projects) view and create a new project.
<div class="zitadel-gallery" itemscope itemtype="http://schema.org/ImageGallery">
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/accounts_org_register_light.png" itemprop="contentUrl" data-size="840x1398">
<img src="img/accounts_org_register_light.png" itemprop="thumbnail" alt="Organisation Overview" />
</a>
<figcaption itemprop="caption description">Organisation Register</figcaption>
</figure>
</div>
![Organisation Register](/img/accounts_org_register_light.png)
Now you can proceed adding users to your organization as well as integrating your applications. We refer to our guides as well as our [quickstarts](quickstarts) to do so.
Now you can proceed adding users to your organization as well as integrating your applications. We refer to our guides as well as our [Quickstarts](../quickstarts/introduction) to do so.
#### Verify your domain name (optional)
@ -27,7 +32,7 @@ If you verify a domain you get the benefit that your organisations users can use
#### Elect Managers
ZITADEL allows you to give other users control over ZITADEL Console itself. This can be restricted to some kind of write and/or read. This can be especially useful for directing administration over several users. You can have managers able to edit project settings and others able to create/add users only.
Read the [guides](guides) for more information.
Read the [guides](introduction) for more information.
> Note: ZITADEL Managers are always located on the right sidepanel of console.
@ -35,4 +40,4 @@ Read the [guides](guides) for more information.
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 [Quickstart Guides](quickstarts).
The wizard should provide some guidance what client is the proper for you. If you are still unsure consult our [Guide Project](projects).

View File

@ -1,7 +1,5 @@
---
title: Identity Brokering
tags: developer, organisation manager
readingtime: 15min
---
<table class="table-wrapper">
@ -24,7 +22,7 @@ readingtime: 15min
<td>Prerequisites</td>
<td>
<ul>
<li>Knowledge of <a href="/zitadel-organizations">ZITADEL Organizations</a></li>
<li>Knowledge of <a href="/docs/guides/organizations">Organizations</a></li>
</ul>
</td>
</tr>
@ -43,12 +41,7 @@ If Google is configured as identity provider on your organization, the user will
ZITADEL will redirect the user to the login screen of Google where he as to authenticated himself (2) and is sent back after he has finished that (3).
Because Google is registered as trusted identity provider the user will be able to login in with the Google account after he linked an existing ZITADEL Account or just registered a new one with the claims provided by Google (4)(5).
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/zitadel_identity_brokering.png" itemprop="contentUrl" data-size="1920x1080">
<img src="img/zitadel_identity_brokering.png" itemprop="thumbnail" alt="Zitadel Identity Brokering" />
</a>
<figcaption itemprop="caption description">Identity Brokering</figcaption>
</figure>
![Identity Brokering](/img/zitadel_identity_brokering.png)
### Exercise: Register an external identity provider
@ -64,31 +57,22 @@ In this exercise we will add a new Google identity provider to federate identiti
> **Information:** Make sure the provider is OIDC 1.0 compliant with a proper Discovery Endpoint
Google Example:
1. Go to the Google Gloud Platform and choose youre project: https://console.cloud.google.com/apis/credentials
1. Go to the Google Gloud Platform and choose youre project: <https://console.cloud.google.com/apis/credentials>
2. Click on "+ CREATE CREDENTIALS" and choose "OAuth client ID"
3. Choose Web application as Application type and give a name
4. Add the redirect uris from above
5. Save clientid and client secret
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/google_add_credentials.gif" itemprop="contentUrl" data-size="1920x1080">
<img src="img/google_add_credentials.gif" itemprop="thumbnail" alt="google_add_oauth_credentials" />
</a>
<figcaption itemprop="caption description">Add new oAuth credentials in Google Console</figcaption>
</figure>
![Add new oAuth credentials in Google Console](/img/google_add_credentials.gif)
#### 2. Add custom login policy on your organisation
1. Go to your organisation settings by clicking on "Organisation" in the menu or using the following link: https://console.zitadel.ch/org
1. Go to your organisation settings by clicking on "Organisation" in the menu or using the following link: <https://console.zitadel.ch/org>
2. Modify your login policy
3. As long as you have the default policy, you can't change the policy. Click create custom policy to set your on settings.
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/console_org_custom_login_policy.gif" itemprop="contentUrl" data-size="1920x1080">
<img src="img/console_org_custom_login_policy.gif" itemprop="thumbnail" alt="add_custom_login_policy" />
</a>
<figcaption itemprop="caption description">Add custom login policy</figcaption>
</figure>
![Add custom login policy](/img/console_org_custom_login_policy.gif)
#### 3.Configure new identity provider
@ -101,25 +85,19 @@ Google Example:
3. Save your configuration
4. Link your new configuration to your login policy. By searching in the organisation category you will get you own configuration. If you choose system you can link all predefined providers.
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/console_org_identity_provider.gif" itemprop="contentUrl" data-size="1920x1080">
<img src="img/console_org_identity_provider.gif" itemprop="thumbnail" alt="configure_new_identity_provider" />
</a>
<figcaption itemprop="caption description">Configure identity provider</figcaption>
</figure>
![Configure identity provider](/img/console_org_identity_provider.gif)
Your user will now be able to choose Google for login instead of username/password or mfa.
### Knowledge Check
* The issuer for your identity provider is https://issuer.zitadel.ch
* The issuer for your identity provider is <https://issuer.zitadel.ch>
- [ ] yes
- [ ] no
* The identity provider has to be oAuth 2.0 compliant
- [ ] yes
- [ ] no
<details>
<summary>
Solutions
@ -132,7 +110,6 @@ Your user will now be able to choose Google for login instead of username/passwo
- [x] yes
- [ ] no
</details>
### Summary
@ -141,5 +118,6 @@ Your user will now be able to choose Google for login instead of username/passwo
* Configure the provider in your custom login policy
Where to go from here:
* ZITADEL Projects
* Service users

View File

@ -0,0 +1,5 @@
---
title: Introduction
---
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.

View File

@ -1,10 +1,7 @@
---
title: Recommended authorization flows
tags: beginner, developer
readingtime: 15min
---
| | |
| --- | --- |
| Description | Learn about the different authentication flows and which flow we recommend you should use for your application. |
@ -26,28 +23,24 @@ So this module will only go over the basics and explain why we recommend the flo
Although Federated Identities are not a new concept ([RFC 6749](https://tools.ietf.org/html/rfc6749), “The OAuth 2.0 Authorization Framework” was released in 2012) it is important to highlight the difference between the traditional client-server authentication model and the concept of delegated authorization and authentication.
The aforementioned RFC provides us with some [problems and limitations](https://tools.ietf.org/html/rfc6749#section-1) of the client-server authentication, where a client requests a protected resource on the server by authenticating with the users credentials:
* Applications need to store users credentials (eg, password) for future use; compromise of any application results in compromise of the end-users credentials
* Servers are required to support password authentication
* Without means of limiting scope when providing the users credentials, the application gains overly broad access to protected resources
* Users cannot revoke access for a single application, but only for all by changing credentials
So what do we want to achieve with delegated authentication?
* Instead of implementing authentication on each server and trusting each server:
* Instead of implementing authentication on each server and trusting each server
* Users only **authenticate** with a trusted server (ie. ZITADEL), that validates the users identity through a challenge (eg, multiple authentication factors) and issues an **ID token** (OpenID Connect 1.x)
* Applications have means of **validating the integrity** of presented access and ID tokens
* Instead of sending around the users credentials:
* Instead of sending around the users credentials
* Clients may access protected resources with an **access token** that is only valid for specific scope and limited lifetime (OAuth 2.x)
* Users have to **authorize** applications to access certain [**scopes**](https://docs.zitadel.ch/architecture#Scopes) (eg, email address or custom roles). Applications can request [**claims**](https://docs.zitadel.ch/architecture#Claims) (key:value pairs, eg email address) for the authorized scopes with the access token or ID token from ZITADEL
* Access tokens are bearer tokens, meaning that possession of the token provides access to a resource. But the tokens expire frequently and the application must request a new access token via **refresh token** or the user must reauthenticate
<div class="zitadel-gallery" itemscope itemtype="http://schema.org/ImageGallery">
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/consulting_federated_identities_basics.png" itemprop="contentUrl" data-size="1920x1080">
<img src="img/consulting_federated_identities_basics.png" itemprop="thumbnail" alt="consulting_federated_identities_basics" />
</a>
<figcaption itemprop="caption description">Overview federated identities</figcaption>
</figure>
</div>
![Overview federated identities](/img/consulting_federated_identities_basics.png)
This is where the so-called “flows” come into play: There are a number of different flows on how to handle the process from authentication, over authorization, getting tokens and requesting additional information about the user.
@ -56,10 +49,12 @@ Maybe interesting to mention is that we are mostly concerned with choosing the r
### Different client profiles
As mentioned in the beginning of this module, there are two main determinants for choosing the optimal authorization flow:
1. Clients ability to maintain the confidentiality of client credentials
2. Technological limitations
OAuth 2.x defines two [client types](https://tools.ietf.org/html/rfc6749#section-2.1) based on their ability to maintain the confidentiality of their client credentials:
* Confidential: Clients capable of maintaining the confidentiality of their credentials (e.g., client implemented on a secure server with restricted access to the client credentials), or capable of secure client authentication using other means.
* Public: Clients incapable of maintaining the confidentiality of their credentials (e.g., clients executing on the device used by the resource owner, such as an installed native application or a web browser-based application), and incapable of secure client authentication via any other means.
@ -70,7 +65,7 @@ The following table gives you a brief overview of different client profiles.
<th>Confidentiality of client credentials</th>
<th>Client profile</th>
<th>Examples of clients</th>
<tr>
</tr>
<tr>
<td rowspan="2">Public</td>
<td>User-Agent</td>
@ -146,6 +141,7 @@ In case you need alternative flows and their advantages and drawbacks, there wil
* There are alternative flows and fallback strategies supported by ZITADEL, if these flows are technically not possible
Where to go from here
* ZITADEL Applications
* ZITADEL Service Accounts
* Applications
* Service Accounts
* Alternative authentication flows (aka. "The Zoo")

View File

@ -1,7 +1,5 @@
---
title: ZITADEL Organizations
tags: beginner, administrator, product owner
readingtime: 10min
title: Organizations
---
@ -11,19 +9,15 @@ readingtime: 10min
| Learning Outcomes | In this module you will: <ul><li>Learn about organizations</li><li>Create a new organization</li><li>Verify your domain name </li></ul> |
|Prerequisites|None|
### What is an organization?
## What is an organization?
ZITADEL is organized around the idea that:
ZITADEL is organized around the idea that
* Multiple organizations share the same system. In this case multiple organizations share the same service, zitadel.ch
* organizations can grant each other rights to self-manage certain aspects of the IAM (eg, roles for access management)
* organizations are vessels for users and projects
<div class="figure-wrapper">
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<img src="img/zitadel_organizations.png" itemprop="thumbnail" alt="Zitadel Organizations" />
<figcaption itemprop="caption description">Overview ZITADEL Organizations</figcaption>
</figure>
</div>
![Overview ZITADEL Organizations](/img/zitadel_organizations.png)
Organizations in ZITADEL are therefore comparable to tenants of a system or organizational units of a directory based system.
@ -31,38 +25,23 @@ You can use projects within your organization to manage the security context of
ZITADEL allows you to give other organizations permission to manage certain aspects of a project within your organization on their own. This means you could set up a project with roles that should exist within your service/software, but allow another organization to allocate the roles to users within their own organization. As a service provider, you will find this feature useful, as it allows you to establish a self-service culture for your business customers.
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/zitadel_organization_grant.png" itemprop="contentUrl" data-size="1920x1080">
<img src="img/zitadel_organization_grant.png" itemprop="thumbnail" alt="Zitadel Organization grant" />
</a>
<figcaption itemprop="caption description">Organization Grant</figcaption>
</figure>
![Organization Grant](/img/zitadel_organization_grant.png)
Each organization has its own pool of usernames, which includes human and service users, for its domain (`{username}@{domainname}.{zitadeldomain}`). A username is unique within your organization. You can configure ZITADEL to use your own domain, and simplify user experience (`{loginname}@{yourdomain.tld}`).
There are several more modules in our documentation to go into more detail regarding organization management, projects, clients, and users. But first lets create a new organization and verify your domain name.
### Exercise - Create a new organization
## Exercise - Create a new organization
To register your organization and create a user for ZITADEL, visit zitadel.ch or directly https://accounts.zitadel.ch/register/org and fill in the required information.
To register your organization and create a user for ZITADEL, visit zitadel.ch or directly <https://accounts.zitadel.ch/register/org> and fill in the required information.
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/console_org_register.png" itemprop="contentUrl" data-size="1920x1080">
<img src="img/console_org_register.png" itemprop="thumbnail" alt="Register Org" />
</a>
<figcaption itemprop="caption description">Register new Organization</figcaption>
</figure>
![Register new Organization](/img/console_org_register.png)
If you already have an existing login for zitadel.ch, you need to visit the console, then click on your organizations name in the upper left corner, and then select “New organization”.
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/console_org_select.png" itemprop="contentUrl" data-size="1920x1080">
<img src="img/console_org_select.png" itemprop="thumbnail" alt="console_org_select" />
</a>
<figcaption itemprop="caption description">Select Organization</figcaption>
</figure>
![Select Organization](/img/console_org_select.png)
### How ZITADEL handles usernames
## How ZITADEL handles usernames
As we mentioned before, each organization has its own pool of usernames, which includes human and service.
@ -70,7 +49,7 @@ This means that, for example a user with the username road.runner, can only exis
When you verify your domain name, then ZITADEL will generate additional logonames for each user with the verified domain. If our example organization would own the domain acme.ch and verify within the organization ACME, then the resulting logonname in our example would be road.runner@acme.ch in addition to the already generated road.runner@acme.zitadel.ch. The user can now use either logonname to authenticate with your application.
### Domain verification and primary domain
## Domain verification and primary domain
Once you have successfully registered your organization, ZITADEL will automatically generate a domain name for your organization (eg, acme.zitadel.ch). Users that you create within your organization will be suffixed with this domain name.
@ -80,9 +59,7 @@ An organization can have multiple domain names, but only one domain can be prima
Please note that domain verification also removes the logonname from all users, who might have used this combination in the global organization (ie. users not belonging to a specific organization). Relating to our example with acme.ch: If a user coyote exists in the global organization with the logonname coyote@acme.ch, then after verification of acme.ch, this logonname will be replaced with `coyote@{randomvalue.tld}`. ZITADEL will notify users affected by this change.
### Exercise - Verify your domain name
## Exercise - Verify your domain name
1. Browse to your organization
2. Click **Add Domain**
@ -90,16 +67,11 @@ Please note that domain verification also removes the logonname from all users,
4. For example, create a TXT record with your DNS provider for the used domain and click verify. ZITADEL will then proceed an check your DNS.
5. When the verification is successful you have the option to activate the domain by clicking **Set as primary**
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/console_verify_domain.gif" itemprop="contentUrl" data-size="1920x1080">
<img src="img/console_verify_domain.gif" itemprop="thumbnail" alt="console_verify_domain" />
</a>
<figcaption itemprop="caption description">Verify Domain</figcaption>
</figure>
![Verify Domain](/img/console_verify_domain.gif)
> **_Please note:_** Do not delete the verification code, as ZITADEL will re-check the ownership of your domain from time to time
### Knowledge Check
## Knowledge Check
* Users exist only within projects or clients
- [ ] yes
@ -128,7 +100,7 @@ Please note that domain verification also removes the logonname from all users,
</details>
### Summary
## Summary
* Create your organization and a new user by visiting zitadel.ch
* Organizations are the top-most vessel for your IAM objects, such as users or projects
@ -136,6 +108,7 @@ Please note that domain verification also removes the logonname from all users,
* You can delegate certain aspects of your IAM to other organizations for self-service
Where to go from here:
* Create a project
* Setup Passwordless MFA
* Manage ZITADEL Roles

View File

@ -0,0 +1,137 @@
---
title: Projects
---
| | |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Description | Learn the basics about applications, roles and authorizations, and how projects allow you to group these together. |
| Learning Outcomes | In this module you will: <ul><li>Learn about projects and granted projects</li><li>Create a new project</li><li>Creating simple roles and authorizations</li><li>Create an organization grant for your project</li></ul> |
| Prerequisites | <ul><li>ZITADEL organizations</li><li>Role Based Access Management (RBAC)</li></ul> |
## What is a project?
The idea of projects is to have a vessel for all components who are closely related to each other. Multiple projects can exist within an organization.
![Organization grant](/img/zitadel_organization_grant.png)
All applications within a project share the same roles, grants, and authorizations:
* **Applications** is your software that initiates the authorization flow. This could be a web app and a mobile app that share the same roles.
* **Roles** are a means of managing user access rights for a project.
* **Authorizations** define which users have which roles. Authorizations are also called “user grants”.
* **Granted Organizations** can manage selected roles for your project on their own.
![Organization grant](/img/console_projects_overview.png)
The goal of this module is to give you an overview, but not dive too deep into details around managing access rights and delegating management of roles to third parties. So lets create a straightforward example project first.
## Exercise - Create a simple project
Visit <https://console.zitadel.ch/projects> or select “Projects” within your organization, then click the button to create a new project.
![Empty Project](/img/console_projects_empty.png)
Enter the name “ My first project” and continue.
Lets make this more interesting and add some basic roles and authorizations to your project and then confirm the scope of the roles and authorizations.
Jump to the section ROLES and create two new roles with the following values
* Key: reader
* Display Name: Reader
* Group: user
and
* Key: editor
* Display Name: Editor
* Group: user
![Add New Roles](/img/console_projects_add_new_roles.gif)
Now, you can add roles to your own user, or you can create a new user. To create a new user, go to Users and click “New”. Enter the required contact details and save by clicking “Create”.
![Create new user](/img/console_users_create_new_user.gif)
To grant users certain roles, you need to create authorizations. Go back to the project, and jump to the section AUTHORIZATIONS.
![Verify your authorization](/img/console_projects_create_authorization.gif)
You can verify the role grant on the user. Select Users from the navigation menu and click on the user Coyote. Scroll down to the section AUTHORIZATION, there you should be able to verify that the user has the role reader for your project My first project.
![Organization grant](/img/console_projects_authorization_created.png)
Now create another project (eg. “My second project”) and verify that there are no roles or authorizations on your second project.
## What is a granted project?
![Organization Grant](/img/zitadel_organization_grant.png)
With ZITADEL you can grant selected roles within your project to an organization. The receiving organization can then create authorizations for their users on their own (self-service).
An example could be a service provider that offers a SaaS solution that has different permissions for employees working in Sales and Accounting. As soon as a new client purchases the service, the provider could grant the roles sales and accounting to that organization, allowing them to self-manage how they want to allocate the roles to their users.
The process of assigning certain roles by default or according to rules can be further automated by utilizing Service Users in the service providers business process.
Obviously, your organization can grant projects and receive projects. When you are granting, then the receiving organization will be displayed in the section GRANTED ORGANIZATIONS of your project.
![Project granted to organization](/img/console_projects_granted.png)
A granted project, on the other hand, belongs to a third party, granting you some rights to manage certain roles of their project. ZITADEL Console shows granted projects in a dedicated navigation menu, to clearly separate from your organizations projects.
![Granted Projects Overview](/img/console_granted_projects_overview.png)
Please note that you can also grant selected roles of a project to an individual user, instead of an organization. We will discuss this in more detail in a later section.
## Exercise - Grant a project
1. Visit the project that you have created before, then in the section GRANTED ORGANIZATIONS click New.
2. Enter the domain acme.zitadel.ch, search the organization and continue to the next step.
3. Select some roles you would like to grant to the organization ACME and confirm.
4. You should now see ACME in the section GRANTED ORGANIZATIONS
![Grant a project](/img/projects_create_org_grant_caos2acme.gif)
## Knowledge Check (2)
* You can setup multiple projects within an organization to manage scope
- [ ] yes
- [ ] no
* Authorizations are define more detailed access rights within your application
- [ ] yes
- [ ] no
* Your projects as well as projects granted to your organization are visible within the Tab Projects of your organization
- [ ] yes
- [ ] no
<details>
<summary>
Solutions
</summary>
* You can setup multiple projects within an organization to manage scope
- [x] yes
- [ ] no
* Authorizations are define more detailed access rights within your application
- [ ] yes
- [x] no (Authorizations link users to certain roles)
* Your projects as well as projects granted to your organization are visible within the Tab Projects of your organization
- [ ] yes
- [x] no (Projects and Granted Projects are shown on different tabs)
</details>
## Summary (2)
* Manage scope of roles, authorizations and applications with projects
* Create and assign roles to users of your organization within your project
* Use project grants to enable other organizations to self-manage access rights (roles) to your applications
Where to go from here:
* Manage roles for your project
* Grant roles to other organizations or users
* Service Users
* Manage IAM Roles
* Setup a SaaS Application with granted projects (Learning Path)

View File

@ -1,7 +1,5 @@
---
title: ZITADEL Service Users
tags: beginner, developer, product manager
readingtime: 10min
title: Service Users
---
<table class="table-wrapper">
@ -24,32 +22,27 @@ readingtime: 10min
<td>Prerequisites</td>
<td>
<ul>
<li>Knowledge of <a href="/oauth-recommended-flows#Our_recommended_authorization_flows">Recommended Authorization Flows</a></li>
<li>Knowledge of <a href="/docs/guides/oauth-recommended-flows">Recommended Authorization Flows</a></li>
</ul>
</td>
</tr>
</table>
### Human vs. Machine
## Human vs. Machine
ZITADEL supports human an machine users. We call human users simply "Users" and machine users "Service Users".
With Service Users you would typically secure backend services. For example in ZITADEL you would require an authenticated Service User to access the Management API. The main difference between human and machine users is the type of credentials that can be used for authentication: Human users typically logon via an login prompt, but Machine users require a non-interactive logon process.
### Exercise: Create a Service User
## Exercise: Create a Service User
1. Navigate to Service Users
2. Click on **New**
3. Enter a user name and a display name
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/console_serviceusers_create.gif" itemprop="contentUrl" data-size="1920x1080">
<img src="img/console_serviceusers_create.gif" itemprop="thumbnail" alt="console_serviceusers_create" />
</a>
<figcaption itemprop="caption description">Create new service user</figcaption>
</figure>
![Create new service user](/img/console_serviceusers_create.gif)
### Authenticating a service user
## Authenticating a service user
In ZITADEL we use the `private_jwt` (**“JWT bearer token with private key”**, [RFC7523](https://tools.ietf.org/html/rfc7523)) authorization grant for this non-interactive authentication.
@ -61,22 +54,17 @@ You need to follow these steps to authenticate a service user and receive a acce
With this token you can make subsequent requests, just like a human user.
### Exercise: Get an access token
## Exercise: Get an access token
In this exercise we will authenticate a service user and receive an access_token to
In this exercise we will authenticate a service user and receive an access_token to use against a API.
> **Information:** Are you stuck? Don't hesitate to reach out to us on [Github Discussions](https://github.com/caos/zitadel/discussions) or [contact us](https://zitadel.ch/contact/) privately.
#### 1. Generate a private-public key pair in ZITADEL
### 1. Generate a private-public key pair in ZITADEL
Select your service user and in the section KEYS click **New**. Enter an expiration date and click **Add**. Make sure to download the json by clicking **Download**.
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="img/console_serviceusers_new_key.gif" itemprop="contentUrl" data-size="1920x1080">
<img src="img/console_serviceusers_new_key.gif" itemprop="thumbnail" alt="console_serviceusers_new_key" />
</a>
<figcaption itemprop="caption description">Create private key</figcaption>
</figure>
![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.
@ -89,20 +77,23 @@ The downloaded json should look something like outlined below. The value of `key
}
```
#### 2. Create a JWT and sign with private key
### 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",
@ -119,13 +110,13 @@ Payload
* `iat` is a unix timestamp of the creation signing time of the JWT, e.g. now
* `exp` is the unix timestamp of expiry of this assertion. Must be less than 1 hour from `iat`
Please refer to [JWT_with_Private_Key](/architecture#JWT_with_Private_Key#JWT_with_Private_Keyvate_Key) in the documentation for further information.
Please refer to [JWT_with_Private_Key](../apis/openidoauth/authn-methods#jwt-with-private-key) in the documentation for further information.
> **Information:** The `exp` claim is currently not validated, but will be with a future release. Make sure that `exp` is less than 1 hour starting from `iat`.
If you use Go, you might want to use the [provided tool](https://github.com/caos/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
### 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:
@ -139,7 +130,7 @@ curl --request POST \
```
* `grant_type` should be set to `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`
* `scope` should contain any [Scopes](/architecture#Scopes) you want to include, but must include `openid`. For this example, please include `profile` and `email`
* `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`.
@ -155,7 +146,7 @@ Content-Type: application/json
}
```
#### 4. Verify that you have a valid access toaken
### 4. Verify that you have a valid access toaken
For this example let's call the userinfo endpoint to verfiy that our access token works.
@ -165,6 +156,7 @@ curl --request POST \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Bearer MtjHodGy4zxKylDOhg6kW90WeEQs2q...'
```
You should receive a response with your service user's information.
```bash
@ -178,7 +170,7 @@ Content-Type: application/json
}
```
### Knowledge Check
## Knowledge Check
* To secure backend APIs you can request an API key via ZITADEL's console
- [ ] yes
@ -207,12 +199,13 @@ Content-Type: application/json
</details>
### Summary
## 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

View File

@ -0,0 +1,5 @@
---
title: Introduction
---
In this section we provide manuals for different user profiles.

View File

@ -0,0 +1,3 @@
---
title: Login
---

View File

@ -1,7 +1,40 @@
---
title: Angular Setup
title: Angular
---
This Integration guide shows you the recommended way to integrate **ZITADEL** into your Angular Application.
It demonstrates how to add a user login to your application and fetch some data from the user info endpoint.
At the end of the guide you should have an application able to login a user and read the user profile.
> This documentation refers to our [Template](https://github.com/caos/zitadel-angular-template) in Github. Note that our **ZITADEL Console** is also written in Angular and can therefore be used as a reference.
## Setup Application and get Keys
Before we can start building our application we have do do a few configuration steps in ZITADEL Console.
You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your [Project](https://console.zitadel.ch/projects) and add a new application at the top of the page.
Select Web Application and continue.
We recommend that you use [Authorization Code](../apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange](../apis/openidoauth/grant-types#proof-key-for-code-exchange) for all web applications.
![Create app in console](/img/angular/app-create-light.png)
### Redirect URLs
A redirect URL is a URL in your application where ZITADEL redirects the user after they have authenticated. Set your url to the domain the web app will be deployed to or use `localhost:4200` for development as Angular will be running on port 4200.
> If you are following along with the [sample](https://github.com/caos/zitadel-angular-template) project you downloaded from our templates, you should set the Allowed Callback URL to <http://localhost:4200/auth/callback>. You will also have to set dev mode to `true` as this will enable unsecure http for the moment.
If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the post redirectURI field.
Continue and Create the application.
### Client ID and Secret
After successful app creation a popup will appear showing you your clientID as well as a secret.
Copy your client ID as it will be needed in the next step.
## Angular Setup
### Install Angular dependencies
You need to install an oauth / oidc client to connect with ZITADEL. Run the following command:
@ -50,6 +83,7 @@ You can use Angulars schematics to do so:
```bash
ng g component services/authentication
```
This will create an AuthenticationService automatically for you.
Copy the following code to your service. This code provides a function `authenticate()` which redirects the user to ZITADEL. After the user has logged in it will be redirected back to your redirectURI set in Auth Module and Console. Make sure both correspond, otherwise ZITADEL will throw an error.
@ -111,6 +145,7 @@ export class AuthenticationService {
Our template includes a statehandler service to redirect the user back to the route where he initially came from. It saves the route information to a unique id so that the user can be redirected back after a successful authentication.
If you don't need such a behaviour you can escape the following lines from the `authenticate()` method above.
```ts
...
const newState = setState ? await this.statehandler.createState().toPromise() : undefined;
@ -158,13 +193,16 @@ To login a user, a component or a guard is needed.
The use of this components totally depends on your application. In most cases you need both.
To create a component use
To create a component use:
```bash
ng g component components/login
```
and then inject the authService to call `authenticate()`.
Same for the guard:
```bash
ng g guard guards/auth
```
@ -254,3 +292,16 @@ and in your html
</div>
```
## Completion
You have successfully integrated ZITADEL in your Angular Application!
If you get stuck consider checking out our [template](https://github.com/caos/zitadel-angular-template) application which includes all the mentioned functionality of this quickstart. You can simply start by cloning the repo and replacing the AuthConfig in the app.module with your own configuration. If your run into issues don't hesitate to contact us or raise an issue on [Github](https://github.com/caos/zitadel).
![App in console](/img/angular/app-screen.png)
### Whats next?
Now you can proceed implementing our APIs to include Authorization. Refer to our [Docs](introduction) or checkout our Console Code on [Github](https://github.com/caos/zitadel) which is using GRPC to access data.
For more information about creating an angular application we refer to [Angular](https://angular.io/start) and for more information about the used oauth/oidc library consider reading their docs at [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc).

View File

@ -0,0 +1,5 @@
---
title: Introduction
---
Start with ZITADEL quickly by choosing your language.

View File

@ -0,0 +1,66 @@
---
title: OAuth 2.0 Proxy
---
[OAuth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy) is a project which allows services to delegate the authentication flow to a IDP, for example **ZITADEL**
## Configure Zitadel
### Setup Application and get Keys
Before we can start building our application we have do do a few configuration steps in ZITADEL Console.
You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your [Project](https://console.zitadel.ch/projects) and add a new application at the top of the page.
Select Web Application and continue.
We recommend that you use [Authorization Code](../apis/openidoauth/grant-types#authorization-code) for the OAuth 2.0 Proxy.
> Make sure Authentication Method is set to `BASIC` and the Application Type is set to `Web`.
### Redirect URLs
A redirect URL is a URL in your application where ZITADEL redirects the user after they have authenticated. Set your url to the domain the proxy will be deployed to or use the default one `http://127.0.0.1:4180/oauth2/callback`.
> If you are following along with the sample project you downloaded from our templates, you should set the Allowed Callback URL to <http://localhost:4200/auth/callback>. You will also have to set dev mode to `true` as this will enable unsecure http for the moment.
If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the post redirectURI field.
Continue and Create the application.
### Client ID and Secret
After successful app creation a popup will appear showing you your clientID as well as a secret.
Copy your client ID and Secrets as it will be needed in the next step.
> Note: You will be able to regenerate the secret at a later time if you loose it.
## OAuth 2.0 Proxy Setup
### Authentication Example
```toml
provider = "oidc"
user_id_claim = "sub" #uses the subject as ID instead of the email
provider_display_name = "ZITADEL"
redirect_url = "http://127.0.0.1:4180/oauth2/callback"
oidc_issuer_url = "https://issuer.zitadel.ch"
upstreams = [
"https://example.corp.com"
]
email_domains = [
"*"
]
client_id = "{ZITADEL_GENERATED_CLIENT_ID}"
client_secret = "{ZITADEL_GENERATED_CLIENT_SECRET}"
pass_access_token = true
cookie_secret = "{SUPPLY_SOME_SECRET_HERE}"
skip_provider_button = true
cookie_secure = false #localdev only false
http_address = "127.0.0.1:4180" #localdev only
```
> This was tested with version `oauth2-proxy v6.1.1 (built with go1.14.2)`
## Completion
You have successfully integrated ZITADEL in your proxy!
### What next?

136
docs/docusaurus.config.js Normal file
View File

@ -0,0 +1,136 @@
/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
title: 'ZITADEL Docs',
url: 'https://docs.zitadel.ch',
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.ico',
organizationName: 'caos',
projectName: 'zitadel',
themeConfig: {
navbar: {
title: 'ZITADEL',
logo: {
alt: 'ZITADEL logo',
src: 'img/zitadel-logo-solo-darkdesign.svg',
},
items: [
{
type: 'doc',
docId: 'manuals/introduction',
label: 'Manuals',
position: 'left'
},
{
type: 'doc',
label: 'Quickstarts',
docId: 'quickstarts/introduction',
position: 'left'
},
{
type: 'doc',
label: 'Guides',
docId: 'guides/introduction',
position: 'left'
},
{
type: 'doc',
label: 'APIs',
docId: 'apis/introduction',
position: 'left'
},
{
type: 'doc',
docId: 'concepts/introduction',
label: 'Concepts',
position: 'left'
},
{
href: 'https://github.com/caos/zitadel',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Community',
items: [
{
label: 'GitHub Discussions',
href: 'https://github.com/caos/zitadel/discussions',
},
{
label: 'Twitter',
href: 'https://twitter.com/zitadel_ch',
},
{
label: 'Linkedin',
href: 'https://www.linkedin.com/company/caos-ag/',
},
{
label: 'Blog',
href: 'https://zitadel.ch/blog',
},
],
},
{
title: 'Company',
items: [
{
label: 'About CAOS Ltd.',
href: 'https://caos.ch/#about',
},
{
label: 'Contact',
href: 'https://zitadel.ch/contact/',
},
{
label: 'GitHub',
href: 'https://github.com/caos',
},
{
label: 'Status',
href: 'https://status.zitadel.ch/',
},
{
label: 'Terms and Conditions',
href: 'https://zitadel.ch/pdf/tos.pdf',
},
{
label: 'Privacy Policy',
href: 'https://zitadel.ch/pdf/privacy.pdf',
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} CAOS Ltd. Built with Docusaurus.`,
},
},
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
editUrl:
'https://github.com/caos/zitadel/edit/main/docs/',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
},
],
],
plugins: [
[
'docusaurus-plugin-plausible',
{
domain: 'docs.zitadel.ch',
},
]
],
};

29725
docs/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

37
docs/package.json Normal file
View File

@ -0,0 +1,37 @@
{
"name": "zitadel-docs",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "2.0.0-alpha.72",
"@docusaurus/preset-classic": "2.0.0-alpha.72",
"@mdx-js/react": "^1.6.21",
"clsx": "^1.1.1",
"docusaurus-plugin-plausible": "^0.0.5",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

48
docs/sidebars.js Normal file
View File

@ -0,0 +1,48 @@
module.exports = {
manuals: [
'manuals/introduction',
{
type: 'category',
label: 'User',
items: ['manuals/user'],
},
],
quickstarts: [
'quickstarts/introduction',
{
type: 'category',
label: 'Single Page Applications',
items: ['quickstarts/angular'],
},
{
type: 'category',
label: 'Identity Aware Proxy',
items: ['quickstarts/oauth2-proxy'],
}
],
guides: [
'guides/introduction',
{
type: 'category',
label: 'Get to know ZITADEL',
items: ['guides/get-started', 'guides/organizations', 'guides/projects', 'guides/serviceusers', 'guides/oauth-recommended-flows', 'guides/identity-brokering'],
},
],
apis: [
'apis/introduction',
'apis/domains',
'apis/authn',
'apis/admin',
'apis/mgmt',
{
type: 'category',
label: 'OpenID Connect & OAuth',
items: ['apis/openidoauth/endpoints', 'apis/openidoauth/scopes', 'apis/openidoauth/claims', 'apis/openidoauth/authn-methods', 'apis/openidoauth/grant-types'],
},
],
concepts: [
'concepts/introduction',
'concepts/architecture',
'concepts/principles',
]
};

49
docs/src/css/custom.css Normal file
View File

@ -0,0 +1,49 @@
/* stylelint-disable docusaurus/copyright-header */
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
@import url('https://fonts.googleapis.com/css2?family=Montserrat');
:root {
--ifm-color-primary: #556cd1;
--ifm-color-primary-dark: #3e58cb;
--ifm-color-primary-darker: #3550c5;
--ifm-color-primary-darkest: #2c42a2;
--ifm-color-primary-light: #6c80d7;
--ifm-color-primary-lighter: #788ada;
--ifm-color-primary-lightest: #9aa8e4;
--ifm-code-font-size: 95%;
--ifm-font-family-base: 'Montserrat', sans-serif;
}
.docusaurus-highlight-code-line {
background-color: rgb(72, 77, 91);
display: block;
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
}
.get-started {
border: 1px solid;
background-color: var(--ifm-font-color-base-inverse);
color: var(--ifm-color-primary);
}
.get-started:hover {
background-color: var(--ifm-color-primary);
color: var(--ifm-font-color-base-inverse);
}
.docs-link a {
text-decoration: none;
color: inherit;
}
.docs-link a:hover {
color: var(--ifm-color-primary);
}

117
docs/src/pages/index.js Normal file
View File

@ -0,0 +1,117 @@
import React from 'react';
import clsx from 'clsx';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl';
import styles from './styles.module.css';
const features = [
{
title: 'Manuals',
imageUrl: 'img/zitadel-logo-solo-light.png',
link: 'docs/manuals/introduction',
description: (
<>
Follow this guide to get started with ZITADEL as a user.
</>
),
},
{
title: 'Quickstarts',
imageUrl: 'img/zitadel-logo-solo-light.png',
link: 'docs/quickstarts/introduction',
description: (
<>
Learn how to integrate your applications and build secure workflows and APIs with ZITADEL
</>
),
},
{
title: 'Guides',
imageUrl: 'img/zitadel-logo-solo-light.png',
link: 'docs/guides/introduction',
description: (
<>
Read our guides on how to manage your data and role associations in ZITADEL and on what we recommend.
</>
),
},
{
title: 'APIs',
imageUrl: 'img/zitadel-logo-solo-light.png',
link: '/docs/apis/introduction',
description: (
<>
Learn more about our APIs and how to integrate them in your apps.
</>
),
},
{
title: 'Concepts',
imageUrl: 'img/zitadel-logo-solo-light.png',
link: 'docs/concepts/introduction',
description: (
<>
Learn more about engineering and design principles, ZITADELs architecture and used technologies.
</>
),
},
];
function Feature({imageUrl, title, description, link}) {
const imgUrl = useBaseUrl(imageUrl);
return (
<div className={clsx('col col--4 docs-link', styles.feature)}>
<Link to={useBaseUrl(link)}>
{imgUrl && (
<div className="text--center">
<img className={styles.featureImage} src={imgUrl} alt={title} />
</div>
)}
<h3>{title}</h3>
<p>{description}</p>
</Link>
</div>
);
}
export default function Home() {
const context = useDocusaurusContext();
const {siteConfig = {}} = context;
return (
<Layout
title={`${siteConfig.title}`}
description="This site bundles ZITADELs Documentations">
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className={clsx(
'button button--outline button--lg get-started',
styles.getStarted,
)}
to={useBaseUrl('docs/guides/get-started')}>
Get Started
</Link>
</div>
</div>
</header>
<main>
{features && features.length > 0 && (
<section className={styles.features}>
<div className="container">
<div className="row">
{features.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
)}
</main>
</Layout>
);
}

View File

@ -0,0 +1,37 @@
/* stylelint-disable docusaurus/copyright-header */
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
}
@media screen and (max-width: 966px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
}
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureImage {
height: 200px;
width: 200px;
}

0
docs/static/.nojekyll vendored Normal file
View File

View File

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View File

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

Before

Width:  |  Height:  |  Size: 259 KiB

After

Width:  |  Height:  |  Size: 259 KiB

View File

Before

Width:  |  Height:  |  Size: 261 KiB

After

Width:  |  Height:  |  Size: 261 KiB

View File

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 196 KiB

View File

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

View File

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 208 KiB

View File

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 197 KiB

View File

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 175 KiB

View File

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View File

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 163 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 138 KiB

View File

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 163 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 MiB

After

Width:  |  Height:  |  Size: 4.5 MiB

View File

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

View File

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 139 KiB

View File

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 126 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 MiB

After

Width:  |  Height:  |  Size: 3.0 MiB

View File

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 126 KiB

View File

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View File

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

View File

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

View File

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 109 KiB

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

Before

Width:  |  Height:  |  Size: 5.8 MiB

After

Width:  |  Height:  |  Size: 5.8 MiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 9.7 MiB

After

Width:  |  Height:  |  Size: 9.7 MiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

Before

Width:  |  Height:  |  Size: 7.9 MiB

After

Width:  |  Height:  |  Size: 7.9 MiB

View File

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 181 KiB

View File

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 MiB

After

Width:  |  Height:  |  Size: 9.6 MiB

Some files were not shown because too many files have changed in this diff Show More