diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml
index f45c602c8..a5a562ef7 100644
--- a/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml
+++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml
@@ -1,7 +1,7 @@
name: Bug Report
description: "Create a bug report to help us improve ZITADEL. Click [here](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#product-management) to see how we process your issue."
title: "[Bug]: "
-labels: ["type: bug", "state: triage"]
+labels: ["bug"]
body:
- type: markdown
attributes:
@@ -27,11 +27,16 @@ body:
- Self-hosted
validations:
required: true
-- type: textarea
- id: description
+- type: input
+ id: version
attributes:
- label: Describe the bug
- description: A clear and concise description of what the bug is.
+ label: Version
+ description: Which version of ZITADEL are you using.
+- type: textarea
+ id: impact
+ attributes:
+ label: Describe the problem caused by this bug
+ description: A clear and concise description of the problem you have and what the bug is.
validations:
required: true
- type: textarea
@@ -57,11 +62,6 @@ body:
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
-- type: input
- id: version
- attributes:
- label: Version
- description: Which version of ZITADEL are you using.
- type: textarea
id: os
attributes:
diff --git a/.github/ISSUE_TEMPLATE/docs.yaml b/.github/ISSUE_TEMPLATE/docs.yaml
new file mode 100644
index 000000000..777692f11
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/docs.yaml
@@ -0,0 +1,31 @@
+name: 📄 Documentation
+description: Create an issue for missing or wrong documentation.
+title:
+labels: ["docs"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this issue.
+ - type: checkboxes
+ id: preflight
+ attributes:
+ label: Preflight Checklist
+ options:
+ - label:
+ I could not find a solution in the existing issues, docs, nor discussions
+ required: true
+ - label:
+ I have joined the [ZITADEL chat](https://zitadel.com/chat)
+ - type: textarea
+ id: docs
+ attributes:
+ label: Describe the docs your are missing or that are wrong
+ placeholder: As a [type of user], I want [some goal] so that [some reason].
+ validations:
+ required: true
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: Please add any other infos that could be useful.
diff --git a/.github/ISSUE_TEMPLATE/improvement.yaml b/.github/ISSUE_TEMPLATE/improvement.yaml
new file mode 100644
index 000000000..1cd864755
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/improvement.yaml
@@ -0,0 +1,55 @@
+name: 🛠️ Improvement
+description:
+title:
+labels: ["improvement"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this improvement request
+ - type: checkboxes
+ id: preflight
+ attributes:
+ label: Preflight Checklist
+ options:
+ - label:
+ I could not find a solution in the existing issues, docs, nor discussions
+ required: true
+ - label:
+ I have joined the [ZITADEL chat](https://zitadel.com/chat)
+ - type: textarea
+ id: problem
+ attributes:
+ label: Describe your problem
+ description: Please describe your problem this improvement is supposed to solve.
+ placeholder: Describe the problem you have
+ validations:
+ required: true
+ - type: textarea
+ id: solution
+ attributes:
+ label: Describe your ideal solution
+ description: Which solution do you propose?
+ placeholder: As a [type of user], I want [some goal] so that [some reason].
+ validations:
+ required: true
+ - type: input
+ id: version
+ attributes:
+ label: Version
+ description: Which version of the ZITADEL are you using.
+ - type: dropdown
+ id: environment
+ attributes:
+ label: Environment
+ description: How do you use ZITADEL?
+ options:
+ - ZITADEL Cloud
+ - Self-hosted
+ validations:
+ required: true
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: Please add any other infos that could be useful.
diff --git a/.github/ISSUE_TEMPLATE/proposal.yaml b/.github/ISSUE_TEMPLATE/proposal.yaml
new file mode 100644
index 000000000..29b08db5c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/proposal.yaml
@@ -0,0 +1,55 @@
+name: 💡 Proposal / Feature request
+description:
+title:
+labels: ["enhancement"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this proposal / feature reqeust
+ - type: checkboxes
+ id: preflight
+ attributes:
+ label: Preflight Checklist
+ options:
+ - label:
+ I could not find a solution in the existing issues, docs, nor discussions
+ required: true
+ - label:
+ I have joined the [ZITADEL chat](https://zitadel.com/chat)
+ - type: textarea
+ id: problem
+ attributes:
+ label: Describe your problem
+ description: Please describe your problem this proposal / feature is supposed to solve.
+ placeholder: Describe the problem you have.
+ validations:
+ required: true
+ - type: textarea
+ id: solution
+ attributes:
+ label: Describe your ideal solution
+ description: Which solution do you propose?
+ placeholder: As a [type of user], I want [some goal] so that [some reason].
+ validations:
+ required: true
+ - type: input
+ id: version
+ attributes:
+ label: Version
+ description: Which version of ZITADEL are you using.
+ - type: dropdown
+ id: environment
+ attributes:
+ label: Environment
+ description: How do you use ZITADEL?
+ options:
+ - ZITADEL Cloud
+ - Self-hosted
+ validations:
+ required: true
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: Please add any other infos that could be useful.
diff --git a/.github/ISSUE_TEMPLATE/task.md b/.github/ISSUE_TEMPLATE/task.md
deleted file mode 100644
index 7ea32464e..000000000
--- a/.github/ISSUE_TEMPLATE/task.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-name: User Story
-about: A user story is a brief description of a feature that has to be implemented from the perspective of the end user.
-title: ''
-assignees: ''
-
----
-
-As a [type of user], I want [some goal] so that [some reason].
-
-```[tasklist]
-### Acceptance Criteria
-- [ ] ...
-```
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 2347e029a..23e35ceb6 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -43,7 +43,7 @@ jobs:
go run main.go init --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml
go run main.go setup --masterkeyFromEnv --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml
- name: Run integration tests
- run: go test -tags=integration -race -parallel 1 -v -coverprofile=profile.cov -coverpkg=./internal/...,./cmd/... ./internal/integration ./internal/api/grpc/...
+ run: go test -tags=integration -race -p 1 -v -coverprofile=profile.cov -coverpkg=./internal/...,./cmd/... ./internal/integration ./internal/api/grpc/...
- name: Publish go coverage
uses: codecov/codecov-action@v3.1.0
with:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 00238fd51..06be1797a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -208,7 +208,7 @@ export INTEGRATION_DB_FLAVOR="cockroach" ZITADEL_MASTERKEY="MasterkeyNeedsToHave
docker compose -f internal/integration/config/docker-compose.yaml up --wait ${INTEGRATION_DB_FLAVOR}
go run main.go init --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml
go run main.go setup --masterkeyFromEnv --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml
-go test -tags=integration -race -parallel 1 ./internal/integration ./internal/api/grpc/...
+go test -count 1 -tags=integration -race -p 1 ./internal/integration ./internal/api/grpc/...
docker compose -f internal/integration/config/docker-compose.yaml down
```
diff --git a/README.md b/README.md
index bfabb60be..d92927437 100644
--- a/README.md
+++ b/README.md
@@ -155,7 +155,9 @@ Use [Console](https://zitadel.com/docs/guides/manage/console/overview) or our [A
## Security
-See the policy [here](./SECURITY.md)
+See the policy [here](./SECURITY.md).
+
+[Technical Advisories](https://zitadel.com/docs/support/technical_advisory) are published regarding major issues with the ZITADEL platform that could potentially impact security or stability in production environments.
## License
diff --git a/cmd/setup/10.go b/cmd/setup/10.go
index 1661ccf7d..a83113cb1 100644
--- a/cmd/setup/10.go
+++ b/cmd/setup/10.go
@@ -19,6 +19,10 @@ var (
correctCreationDate10FillTable string
//go:embed 10/10_update.sql
correctCreationDate10Update string
+ //go:embed 10/10_count_wrong_events.sql
+ correctCreationDate10CountWrongEvents string
+ //go:embed 10/10_empty_table.sql
+ correctCreationDate10Truncate string
)
type CorrectCreationDate struct {
@@ -31,7 +35,7 @@ func (mig *CorrectCreationDate) Execute(ctx context.Context) (err error) {
defer cancel()
for {
- var affected int64
+ affected := int64(0)
err = crdb.ExecuteTx(ctx, mig.dbClient.DB, nil, func(tx *sql.Tx) error {
if mig.dbClient.Type() == "cockroach" {
if _, err := tx.Exec("SET experimental_enable_temp_tables=on"); err != nil {
@@ -43,16 +47,24 @@ func (mig *CorrectCreationDate) Execute(ctx context.Context) (err error) {
return err
}
+ _, err = tx.ExecContext(ctx, correctCreationDate10Truncate)
+ if err != nil {
+ return err
+ }
_, err = tx.ExecContext(ctx, correctCreationDate10FillTable)
if err != nil {
return err
}
- res, err := tx.ExecContext(ctx, correctCreationDate10Update)
+ res := tx.QueryRowContext(ctx, correctCreationDate10CountWrongEvents)
+ if err := res.Scan(&affected); err != nil || affected == 0 {
+ return err
+ }
+
+ _, err = tx.ExecContext(ctx, correctCreationDate10Update)
if err != nil {
return err
}
- affected, _ = res.RowsAffected()
logging.WithFields("count", affected).Info("creation dates changed")
return nil
})
diff --git a/cmd/setup/10/10_count_wrong_events.sql b/cmd/setup/10/10_count_wrong_events.sql
new file mode 100644
index 000000000..2bd0bd7c8
--- /dev/null
+++ b/cmd/setup/10/10_count_wrong_events.sql
@@ -0,0 +1 @@
+SELECT COUNT(*) FROM wrong_events
\ No newline at end of file
diff --git a/cmd/setup/10/10_empty_table.sql b/cmd/setup/10/10_empty_table.sql
new file mode 100644
index 000000000..9139fbe18
--- /dev/null
+++ b/cmd/setup/10/10_empty_table.sql
@@ -0,0 +1 @@
+TRUNCATE wrong_events
\ No newline at end of file
diff --git a/cmd/setup/10/10_fill_table.sql b/cmd/setup/10/10_fill_table.sql
index e62bbd839..b2ac9e307 100644
--- a/cmd/setup/10/10_fill_table.sql
+++ b/cmd/setup/10/10_fill_table.sql
@@ -1,5 +1,3 @@
-TRUNCATE wrong_events;
-
INSERT INTO wrong_events (
SELECT * FROM (
SELECT
diff --git a/cmd/setup/11.go b/cmd/setup/11.go
index 4126216da..544188d12 100644
--- a/cmd/setup/11.go
+++ b/cmd/setup/11.go
@@ -3,7 +3,7 @@ package setup
import (
"context"
"database/sql"
- _ "embed"
+ "embed"
"time"
"github.com/cockroachdb/cockroach-go/v2/crdb"
@@ -21,11 +21,18 @@ var (
fillCreatedAt string
//go:embed 11/11_set_column.sql
setCreatedAtDetails string
+ //go:embed 11/postgres/create_index.sql
+ //go:embed 11/cockroach/create_index.sql
+ createdAtIndexCreateStmt embed.FS
+ //go:embed 11/postgres/drop_index.sql
+ //go:embed 11/cockroach/drop_index.sql
+ createdAtIndexDropStmt embed.FS
)
type AddEventCreatedAt struct {
- step10 *CorrectCreationDate
- dbClient *database.DB
+ BulkAmount int
+ step10 *CorrectCreationDate
+ dbClient *database.DB
}
func (mig *AddEventCreatedAt) Execute(ctx context.Context) error {
@@ -39,10 +46,19 @@ func (mig *AddEventCreatedAt) Execute(ctx context.Context) error {
return err
}
+ createIndex, err := readStmt(createdAtIndexCreateStmt, "11", mig.dbClient.Type(), "create_index.sql")
+ if err != nil {
+ return err
+ }
+ _, err = mig.dbClient.ExecContext(ctx, createIndex)
+ if err != nil {
+ return err
+ }
+
for {
var count int
err = crdb.ExecuteTx(ctx, mig.dbClient.DB, nil, func(tx *sql.Tx) error {
- rows, err := tx.Query(fetchCreatedAt)
+ rows, err := tx.Query(fetchCreatedAt, mig.BulkAmount)
if err != nil {
return err
}
@@ -80,7 +96,7 @@ func (mig *AddEventCreatedAt) Execute(ctx context.Context) error {
if err != nil {
return err
}
- logging.WithFields("count", count).Debug("creation dates set")
+ logging.WithFields("count", count).Info("creation dates set")
if count < 20 {
break
}
@@ -88,6 +104,16 @@ func (mig *AddEventCreatedAt) Execute(ctx context.Context) error {
logging.Info("set details")
_, err = mig.dbClient.ExecContext(ctx, setCreatedAtDetails)
+ if err != nil {
+ return err
+ }
+
+ dropIndex, err := readStmt(createdAtIndexDropStmt, "11", mig.dbClient.Type(), "drop_index.sql")
+ if err != nil {
+ return err
+ }
+ _, err = mig.dbClient.ExecContext(ctx, dropIndex)
+
return err
}
diff --git a/cmd/setup/11/11_fetch_events.sql b/cmd/setup/11/11_fetch_events.sql
index 7c7512526..f66882675 100644
--- a/cmd/setup/11/11_fetch_events.sql
+++ b/cmd/setup/11/11_fetch_events.sql
@@ -1 +1,12 @@
-SELECT id, creation_date FROM eventstore.events WHERE created_at IS NULL ORDER BY event_sequence DESC, instance_id LIMIT 20 FOR UPDATE
\ No newline at end of file
+SELECT
+ id
+ , creation_date
+FROM
+ eventstore.events
+WHERE
+ created_at IS NULL
+ORDER BY
+ event_sequence DESC
+ , instance_id
+LIMIT $1
+FOR UPDATE
\ No newline at end of file
diff --git a/cmd/setup/11/cockroach/create_index.sql b/cmd/setup/11/cockroach/create_index.sql
new file mode 100644
index 000000000..6fdd768a3
--- /dev/null
+++ b/cmd/setup/11/cockroach/create_index.sql
@@ -0,0 +1,8 @@
+CREATE INDEX IF NOT EXISTS ca_fill_idx ON eventstore.events (
+ event_sequence DESC
+ , instance_id
+) STORING (
+ id
+ , creation_date
+ , created_at
+) WHERE created_at IS NULL;
\ No newline at end of file
diff --git a/cmd/setup/11/cockroach/drop_index.sql b/cmd/setup/11/cockroach/drop_index.sql
new file mode 100644
index 000000000..da91018d7
--- /dev/null
+++ b/cmd/setup/11/cockroach/drop_index.sql
@@ -0,0 +1 @@
+DROP INDEX IF EXISTS eventstore.events@ca_fill_idx;
\ No newline at end of file
diff --git a/cmd/setup/11/postgres/create_index.sql b/cmd/setup/11/postgres/create_index.sql
new file mode 100644
index 000000000..a6fb37c99
--- /dev/null
+++ b/cmd/setup/11/postgres/create_index.sql
@@ -0,0 +1,4 @@
+CREATE INDEX IF NOT EXISTS ca_fill_idx ON eventstore.events (
+ event_sequence DESC
+ , instance_id
+) WHERE created_at IS NULL;
\ No newline at end of file
diff --git a/cmd/setup/11/postgres/drop_index.sql b/cmd/setup/11/postgres/drop_index.sql
new file mode 100644
index 000000000..acfe2f49b
--- /dev/null
+++ b/cmd/setup/11/postgres/drop_index.sql
@@ -0,0 +1 @@
+DROP INDEX IF EXISTS eventstore.ca_fill_idx;
\ No newline at end of file
diff --git a/cmd/setup/config.go b/cmd/setup/config.go
index 5e9819e4c..0d659e6e7 100644
--- a/cmd/setup/config.go
+++ b/cmd/setup/config.go
@@ -66,7 +66,7 @@ type Steps struct {
s8AuthTokens *AuthTokenIndexes
s9EventstoreIndexes2 *EventstoreIndexesNew
CorrectCreationDate *CorrectCreationDate
- s11AddEventCreatedAt *AddEventCreatedAt
+ AddEventCreatedAt *AddEventCreatedAt
}
type encryptionKeyConfig struct {
diff --git a/cmd/setup/setup.go b/cmd/setup/setup.go
index 59b7c5d6b..3f42503c2 100644
--- a/cmd/setup/setup.go
+++ b/cmd/setup/setup.go
@@ -91,7 +91,8 @@ func Setup(config *Config, steps *Steps, masterKey string) {
steps.s8AuthTokens = &AuthTokenIndexes{dbClient: dbClient}
steps.s9EventstoreIndexes2 = New09(dbClient)
steps.CorrectCreationDate.dbClient = dbClient
- steps.s11AddEventCreatedAt = &AddEventCreatedAt{dbClient: dbClient, step10: steps.CorrectCreationDate}
+ steps.AddEventCreatedAt.dbClient = dbClient
+ steps.AddEventCreatedAt.step10 = steps.CorrectCreationDate
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil)
logging.OnError(err).Fatal("unable to start projections")
@@ -129,7 +130,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
logging.OnError(err).Fatal("unable to migrate step 9")
err = migration.Migrate(ctx, eventstoreClient, steps.CorrectCreationDate)
logging.OnError(err).Fatal("unable to migrate step 10")
- err = migration.Migrate(ctx, eventstoreClient, steps.s11AddEventCreatedAt)
+ err = migration.Migrate(ctx, eventstoreClient, steps.AddEventCreatedAt)
logging.OnError(err).Fatal("unable to migrate step 11")
for _, repeatableStep := range repeatableSteps {
diff --git a/cmd/setup/steps.yaml b/cmd/setup/steps.yaml
index f5cb4b0c2..e495276e5 100644
--- a/cmd/setup/steps.yaml
+++ b/cmd/setup/steps.yaml
@@ -30,5 +30,9 @@ FirstInstance:
MachineKey:
ExpirationDate:
Type:
+
CorrectCreationDate:
FailAfter: 5m
+
+AddEventCreatedAt:
+ BulkAmount: 100
\ No newline at end of file
diff --git a/console/src/app/modules/idp-table/idp-table.component.html b/console/src/app/modules/idp-table/idp-table.component.html
index 111023285..2990f196d 100644
--- a/console/src/app/modules/idp-table/idp-table.component.html
+++ b/console/src/app/modules/idp-table/idp-table.component.html
@@ -13,7 +13,7 @@
{{ 'IDP.TYPE' | translate }} |
-
+ |

@@ -87,7 +87,7 @@
{{ 'IDP.STATE' | translate }} |
-
+ |
| {{ 'IDP.CREATIONDATE' | translate }} |
-
+ |
{{ idp.details.creationDate | timestampToDate | localizedDate : 'dd. MMM, HH:mm' }}
|
{{ 'IDP.CHANGEDATE' | translate }} |
-
+ |
{{ idp.details.changeDate | timestampToDate | localizedDate : 'dd. MMM, HH:mm' }}
|
{{ 'IDP.OWNER' | translate }} |
-
+ |
{{ 'IDP.OWNERTYPES.' + idp.owner | translate }}
|
@@ -140,7 +140,7 @@
"
mat-icon-button
matTooltip="{{ 'IDP.SETAVAILABLE' | translate }}"
- (click)="addIdp(idp)"
+ (click)="addIdp(idp); $event.stopPropagation()"
>
@@ -160,7 +160,7 @@
"
mat-icon-button
matTooltip="{{ 'IDP.SETUNAVAILABLE' | translate }}"
- (click)="removeIdp(idp)"
+ (click)="removeIdp(idp); $event.stopPropagation()"
>
@@ -185,7 +185,7 @@
mat-icon-button
color="warn"
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
- (click)="deleteIdp(idp)"
+ (click)="deleteIdp(idp); $event.stopPropagation()"
>
@@ -194,7 +194,7 @@
|
- |
+
diff --git a/console/src/app/modules/idp-table/idp-table.component.ts b/console/src/app/modules/idp-table/idp-table.component.ts
index 4719f282a..6df954413 100644
--- a/console/src/app/modules/idp-table/idp-table.component.ts
+++ b/console/src/app/modules/idp-table/idp-table.component.ts
@@ -2,7 +2,7 @@ import { SelectionModel } from '@angular/cdk/collections';
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog';
import { MatLegacyTableDataSource as MatTableDataSource } from '@angular/material/legacy-table';
-import { RouterLink } from '@angular/router';
+import { Router, RouterLink } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
import { BehaviorSubject, Observable } from 'rxjs';
@@ -31,6 +31,8 @@ import { AdminService } from 'src/app/services/admin.service';
import { ManagementService } from 'src/app/services/mgmt.service';
import { ToastService } from 'src/app/services/toast.service';
+import { OverlayWorkflowService } from 'src/app/services/overlay/overlay-workflow.service';
+import { ContextChangedWorkflowOverlays } from 'src/app/services/overlay/workflows';
import { PageEvent, PaginatorComponent } from '../paginator/paginator.component';
import { PolicyComponentServiceType } from '../policies/policy-component-types.enum';
import { WarnDialogComponent } from '../warn-dialog/warn-dialog.component';
@@ -60,7 +62,13 @@ export class IdpTableComponent implements OnInit {
public IDPStylingType: any = IDPStylingType;
public loginPolicy!: LoginPolicy.AsObject;
- constructor(public translate: TranslateService, private toast: ToastService, private dialog: MatDialog) {
+ constructor(
+ private workflowService: OverlayWorkflowService,
+ public translate: TranslateService,
+ private toast: ToastService,
+ private dialog: MatDialog,
+ private router: Router,
+ ) {
this.selection.changed.subscribe(() => {
this.changedSelection.emit(this.selection.selected);
});
@@ -241,6 +249,16 @@ export class IdpTableComponent implements OnInit {
}
}
+ navigateToIDP(row: Provider.AsObject) {
+ this.router.navigate(this.routerLinkForRow(row)).then(() => {
+ if (this.serviceType === PolicyComponentServiceType.MGMT && row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM) {
+ setTimeout(() => {
+ this.workflowService.startWorkflow(ContextChangedWorkflowOverlays, null);
+ }, 1000);
+ }
+ });
+ }
+
private async getIdps(): Promise {
switch (this.serviceType) {
case PolicyComponentServiceType.MGMT:
diff --git a/console/src/app/services/overlay/workflows.ts b/console/src/app/services/overlay/workflows.ts
index 1c6c8263b..6f9c11e56 100644
--- a/console/src/app/services/overlay/workflows.ts
+++ b/console/src/app/services/overlay/workflows.ts
@@ -66,3 +66,17 @@ export const OrgContextChangedWorkflowOverlays: CnslOverlay[] = [
},
},
];
+
+export const ContextChangedWorkflowOverlays: CnslOverlay[] = [
+ {
+ id: 'contextswitcher',
+ origin: 'orgbutton',
+ toHighlight: ['orgbutton'],
+ content: {
+ i18nText: 'OVERLAYS.SWITCHEDTOINSTANCE.TEXT',
+ },
+ requirements: {
+ permission: ['iam.read'],
+ },
+ },
+];
diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json
index 68d81ac77..832ce451b 100644
--- a/console/src/assets/i18n/de.json
+++ b/console/src/assets/i18n/de.json
@@ -204,6 +204,9 @@
},
"CONTEXTCHANGED": {
"TEXT": "Achtung! Soeben wurde die Organisation gewechselt."
+ },
+ "SWITCHEDTOINSTANCE": {
+ "TEXT": "Soeben wurde die Ansicht auf Instanz gewechselt."
}
},
"FILTER": {
diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json
index 2d27939ee..d6a19679e 100644
--- a/console/src/assets/i18n/en.json
+++ b/console/src/assets/i18n/en.json
@@ -204,7 +204,10 @@
"TEXT": "This navigation changes based on your selected organization above or your instance"
},
"CONTEXTCHANGED": {
- "TEXT": "Attention! The organization context has changed."
+ "TEXT": "The organization context has changed."
+ },
+ "SWITCHEDTOINSTANCE": {
+ "TEXT": "The view just changed to instance!"
}
},
"FILTER": {
diff --git a/console/src/assets/i18n/es.json b/console/src/assets/i18n/es.json
index 0fea6748a..8e1164d09 100644
--- a/console/src/assets/i18n/es.json
+++ b/console/src/assets/i18n/es.json
@@ -205,6 +205,9 @@
},
"CONTEXTCHANGED": {
"TEXT": "¡Atención! El contexto de la organización ha cambiado."
+ },
+ "SWITCHEDTOINSTANCE": {
+ "TEXT": "¡La vista acaba de cambiar a instancia!"
}
},
"FILTER": {
diff --git a/console/src/assets/i18n/fr.json b/console/src/assets/i18n/fr.json
index e24116fd8..07e0829e8 100644
--- a/console/src/assets/i18n/fr.json
+++ b/console/src/assets/i18n/fr.json
@@ -204,6 +204,9 @@
},
"CONTEXTCHANGED": {
"TEXT": "Attention ! Le contexte de l'organisation a changé."
+ },
+ "SWITCHEDTOINSTANCE": {
+ "TEXT": "La vue vient de changer en instance !"
}
},
"FILTER": {
diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json
index 4d18722af..e025b4839 100644
--- a/console/src/assets/i18n/it.json
+++ b/console/src/assets/i18n/it.json
@@ -204,6 +204,9 @@
},
"CONTEXTCHANGED": {
"TEXT": "Attenzione! L'organizzazione è appena stata cambiata."
+ },
+ "SWITCHEDTOINSTANCE": {
+ "TEXT": "La visualizzazione è appena stata modificata in istanza!"
}
},
"FILTER": {
diff --git a/console/src/assets/i18n/ja.json b/console/src/assets/i18n/ja.json
index 2ba3863ad..6dea6b8db 100644
--- a/console/src/assets/i18n/ja.json
+++ b/console/src/assets/i18n/ja.json
@@ -205,6 +205,9 @@
},
"CONTEXTCHANGED": {
"TEXT": "注意! 組織のコンテキストが変更されました。"
+ },
+ "SWITCHEDTOINSTANCE": {
+ "TEXT": "ビューがインスタンスに変更されました。"
}
},
"FILTER": {
diff --git a/console/src/assets/i18n/pl.json b/console/src/assets/i18n/pl.json
index 0dd538ba3..3d9a3f825 100644
--- a/console/src/assets/i18n/pl.json
+++ b/console/src/assets/i18n/pl.json
@@ -204,6 +204,9 @@
},
"CONTEXTCHANGED": {
"TEXT": "Uwaga! Kontekst organizacji uległ zmianie."
+ },
+ "SWITCHEDTOINSTANCE": {
+ "TEXT": "Widok właśnie zmienił się na instancję!"
}
},
"FILTER": {
diff --git a/console/src/assets/i18n/zh.json b/console/src/assets/i18n/zh.json
index dbc8dcc19..b8f735d51 100644
--- a/console/src/assets/i18n/zh.json
+++ b/console/src/assets/i18n/zh.json
@@ -204,6 +204,9 @@
},
"CONTEXTCHANGED": {
"TEXT": "注意!组织环境发生了变化。"
+ },
+ "SWITCHEDTOINSTANCE": {
+ "TEXT": "视图刚刚更改为实例!"
}
},
"FILTER": {
diff --git a/docs/docs/apis/openidoauth/endpoints.mdx b/docs/docs/apis/openidoauth/endpoints.mdx
index 8c8a3dc48..8e9b8b231 100644
--- a/docs/docs/apis/openidoauth/endpoints.mdx
+++ b/docs/docs/apis/openidoauth/endpoints.mdx
@@ -1,5 +1,5 @@
---
-title: Endpoints
+title: OpenID Connect Endpoints
---
import Tabs from "@theme/Tabs";
@@ -101,7 +101,7 @@ no additional parameters required
| state | Opaque value used to maintain state between the request and the callback. Used for Cross-Site Request Forgery (CSRF) mitigation as well, therefore highly **recommended**. |
| ui_locales | Spaces delimited list of preferred locales for the login UI, e.g. `de-CH de en`. If none is provided or matches the possible locales provided by the login UI, the `accept-language` header of the browser will be taken into account. |
-### Successful Code Response
+### Successful code response
When your `response_type` was `code` and no error occurred, the following response will be returned:
@@ -110,7 +110,7 @@ When your `response_type` was `code` and no error occurred, the following respon
| code | Opaque string which will be necessary to request tokens on the token endpoint |
| state | Unmodified `state` parameter from the request |
-### Successful Implicit Response
+### Successful implicit response
When your `response_type` was either `it_token` or `id_token token` and no error occurred, the following response will be returned:
@@ -123,7 +123,7 @@ When your `response_type` was either `it_token` or `id_token token` and no error
| scope | Scopes of the `access_token`. These might differ from the provided `scope` parameter. |
| state | Unmodified `state` parameter from the request |
-### Error Response
+### Error response
Regardless of the authorization flow chosen, if an error occurs the following response will be returned to the redirect_uri.
@@ -158,11 +158,11 @@ The token_endpoint will as the name suggests return various tokens (access, id a
When using [`authorization_code`](#authorization-code-grant-code-exchange) flow call this endpoint after receiving the code from the authorization_endpoint.
When using [`refresh_token`](#authorization-code-grant-code-exchange) or [`urn:ietf:params:oauth:grant-type:jwt-bearer` (JWT Profile)](#jwt-profile-grant) you will call this endpoint directly.
-### Authorization Code Grant (Code Exchange)
+### Authorization code grant (Code Exchange)
As mention above, when using `authorization_code` grant, this endpoint will be your second request for authorizing a user with its user agent (browser).
-#### Required request Parameters
+#### Required request parameters
| Parameter | Description |
| ------------ | ------------------------------------------------------------------------------------------------------------- |
@@ -229,9 +229,9 @@ Send a client assertion as JWT for us to validate the signature against the regi
| refresh_token | An opaque token. Only returned if `offline_access` scope was requested |
| token_type | Type of the `access_token`. Value is always `Bearer` |
-### JWT Profile Grant
+### JWT profile grant
-#### Required request Parameters
+#### Required request parameters
| Parameter | Description |
| ---------- | ----------------------------------------------------------------------------------------------------------------------- |
@@ -247,7 +247,7 @@ curl --request POST \
--data assertion=eyJhbGciOiJSUzI1Ni...
```
-#### Successful JWT Profile response {#token-jwt-response}
+#### Successful JWT profile response {#token-jwt-response}
| Property | Description |
| ------------ | ------------------------------------------------------------------------------------- |
@@ -257,12 +257,12 @@ curl --request POST \
| scope | Scopes of the `access_token`. These might differ from the provided `scope` parameter. |
| token_type | Type of the `access_token`. Value is always `Bearer` |
-### Refresh Token Grant
+### Refresh token grant
To request a new `access_token` without user interaction, you can use the `refresh_token` grant.
See [offline_access Scope](scopes#standard-scopes) for how to request a `refresh_token` in the authorization request.
-#### Required request Parameters
+#### Required request parameters
| Parameter | Description |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -325,9 +325,9 @@ Send a `client_assertion` as JWT for us to validate the signature against the re
| refresh_token | An new opaque refresh_token. |
| token_type | Type of the `access_token`. Value is always `Bearer` |
-### Client Credentials Grant
+### Client credentials grant
-#### Required request Parameters
+#### Required request parameters
| Parameter | Description |
| ---------- | ----------------------------------------------------------------------------------------------------------------------- |
@@ -363,7 +363,7 @@ curl --request POST \
--data scope=openid profile
```
-#### Successful Client Credentials response {#token-client-credentials-response}
+#### Successful client credentials response {#token-client-credentials-response}
| Property | Description |
| ------------ | ------------------------------------------------------------------------------------- |
@@ -584,8 +584,27 @@ If both parameters are provided, they must be equal.
{your_domain}/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!
+The endpoint returns a JSON Web Key Set (JWKS) containing the public keys that can be used to locally validate JWTs you received from ZITADEL.
+The alternative would be to validate tokens with the [introspection endpoint](#introspection_endpoint).
-## OAuth 2.0 Metadata
+### Key rotation
+
+Keys are automatically rotated on a regular basis or on demand, meaning keys can change in irregular intervals.
+ZITADEL ensures that a proper `kid` is set with each key.
+
+:::info Keys rotate without prior notice
+Be aware that these keys can be rotated without any prior notice.
+:::
+
+### Caching
+
+You can optimize performance of your clients by caching the response from the keys endpoint.
+We recommend to regularly update the cached response, since the [keys can be rotated without prior notice](#key-rotation).
+You could also combine caching with a risk-based on-demand refresh when a critical operation is executed.
+
+Without caching you will call this endpoint on each request.
+This might result in being rate limited for a large number of requests that come from the same backend.
+
+## OAuth 2.0 metadata
**ZITADEL** does not yet provide a OAuth 2.0 Metadata endpoint but instead provides a [OpenID Connect Discovery Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html).
diff --git a/docs/docs/apis/saml/endpoints.md b/docs/docs/apis/saml/endpoints.md
index 4cd186510..eeae326d9 100644
--- a/docs/docs/apis/saml/endpoints.md
+++ b/docs/docs/apis/saml/endpoints.md
@@ -1,8 +1,8 @@
---
-title: Endpoints
+title: SAML endpoints
---
-## SAML 2.0 Metadata
+## SAML 2.0 metadata
The SAML Metadata is located within the issuer domain. This would give us {your_domain}/saml/v2/metadata.
@@ -11,14 +11,14 @@ This metadata contains all the information defined in the spec.
**Link to
spec.** [Metadata for the OASIS Security Assertion Markup Language (SAML) V2.0 – Errata Composite](https://www.oasis-open.org/committees/download.php/35391/sstc-saml-metadata-errata-2.0-wd-04-diff.pdf)
-## Certificate Endpoint
+## Certificate endpoint
{your_domain}/saml/v2/certificate
The certificate endpoint provides the certificate which is used to sign the responses for download, for easier use with
different service providers which want the certificate separately instead of inside the metadata.
-## SSO Endpoint
+## SSO endpoint
{your_domain}/saml/v2/SSO
@@ -40,7 +40,7 @@ spec.** [Bindings for the OASIS Security Assertion Markup Language (SAML) V2.0
| SigAlg | Algorithm used to sign the request, only if binding is 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' as signature has to be provided es separate parameter. (base64 encoded) |
| Signature | Signature of the request as parameter with 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' binding. (base64 encoded) |
-### Successful Response
+### Successful response
Depending on the content of the request the response comes back in the requested binding, but the content is the same.
@@ -51,7 +51,7 @@ Depending on the content of the request the response comes back in the requested
| SigAlg | Algorithm used to sign the response, only if binding is 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' as signature has to be provided es separate parameter. (base64 encoded) |
| Signature | Signature of the response as parameter with 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' binding. (base64 encoded) |
-### Error Response
+### Error response
Regardless of the error, the used http error code will be '200', which represents a successful request. Whereas the
response will contain a StatusCode include a message which provides more information if an error occurred.
diff --git a/docs/docs/concepts/architecture/software.md b/docs/docs/concepts/architecture/software.md
index 29dcb2c1e..565221774 100644
--- a/docs/docs/concepts/architecture/software.md
+++ b/docs/docs/concepts/architecture/software.md
@@ -147,5 +147,5 @@ The storage layer of ZITADEL is responsible for multiple things. For example:
ZITADEL currently supports CockroachDB as first choice of storage due to its perfect match for ZITADELs needs.
Postgres is currently in [Beta](/docs/support/software-release-cycles-support#beta) and will be [Enterprise Supported](/docs/support/software-release-cycles-support#partially-supported) afterwards.
Beta state will be removed as soon as [automated tests](https://github.com/zitadel/zitadel/issues/5741) are implemented.
-Make sure to read our [Production Guide](./self-hosting/manage/production#prefer-cockroachdb) before you decide to use it.
+Make sure to read our [Production Guide](/docs/self-hosting/manage/production#prefer-cockroachdb) before you decide to use it.
diff --git a/docs/docs/concepts/architecture/solution.md b/docs/docs/concepts/architecture/solution.md
index 176c15173..9b0656c98 100644
--- a/docs/docs/concepts/architecture/solution.md
+++ b/docs/docs/concepts/architecture/solution.md
@@ -11,7 +11,7 @@ Depending on your projects needs our general recommendation is to run ZITADEL an
Consult the [CockroachDB documentation](https://www.cockroachlabs.com/docs/) for more details or use the [CockroachCloud Service](https://www.cockroachlabs.com/docs/cockroachcloud/create-an-account.html)
Postgres is currently in [Beta](/docs/support/software-release-cycles-support#beta) and will be [Enterprise Supported](/docs/support/software-release-cycles-support#partially-supported) afterwards.
Beta state will be removed as soon as [automated tests](https://github.com/zitadel/zitadel/issues/5741) are implemented.
-Make sure to read our [Production Guide](./self-hosting/manage/production#prefer-cockroachdb) before you decide to use it.
+Make sure to read our [Production Guide](/self-hosting/manage/production#prefer-cockroachdb) before you decide to use it.
## Scalability
diff --git a/docs/docs/concepts/features/audit-trail.md b/docs/docs/concepts/features/audit-trail.md
index bf1992453..12cd77606 100644
--- a/docs/docs/concepts/features/audit-trail.md
+++ b/docs/docs/concepts/features/audit-trail.md
@@ -4,7 +4,7 @@ title: Audit Trail
ZITADEL provides you with an built-in audit trail to track all changes and events over an unlimited period of time.
Most other solutions replace a historic record and track changes in a separate log when information is updated.
-ZITADEL only ever appends data in an [Eventstore](https://zitadel.com/docs/concepts/eventstore), keeping all historic record.
+ZITADEL only ever appends data in an [Eventstore](/docs/concepts/eventstore/overview), keeping all historic record.
The audit trail itself is identical to the state, since ZITADEL calculates the state from all the past changes.

diff --git a/docs/docs/examples/sdks.md b/docs/docs/examples/sdks.md
index 6c70dba16..fc868a08a 100644
--- a/docs/docs/examples/sdks.md
+++ b/docs/docs/examples/sdks.md
@@ -94,5 +94,4 @@ You might want to check out the following links to find a good library:
- [awesome-auth](https://github.com/casbin/awesome-auth)
- [OpenID General References](https://openid.net/developers/libraries/)
-- [OpenID certified libraries](https://openid.net/developers/certified/)
-- [OpenID uncertified libraries](https://openid.net/developers/uncertified/)
\ No newline at end of file
+- [OpenID certified developer tools](https://openid.net/certified-open-id-developer-tools/)
\ No newline at end of file
diff --git a/docs/docs/guides/migrate/introduction.md b/docs/docs/guides/migrate/introduction.md
index 887a374a2..6ac351f43 100644
--- a/docs/docs/guides/migrate/introduction.md
+++ b/docs/docs/guides/migrate/introduction.md
@@ -8,7 +8,7 @@ The individual guides in this section should give you an overview of things to c
When moving from a previous auth solution to ZITADEL, it is important to note that some decisions and features are unique to ZITADEL.
Without duplicating too much content here are some important features and patterns to consider in terms of solution architecture.
-You can read more about the basic structure and important concepts of ZITADEL in our [concepts section](https://zitadel.com/docs/concepts/introduction).
+You can read more about the basic structure and important concepts of ZITADEL in our [concepts section](/docs/concepts/).
## Multi-Tenancy Architecture
diff --git a/docs/docs/legal/acceptable-use-policy.md b/docs/docs/legal/acceptable-use-policy.md
index 683bca365..5fb99138a 100644
--- a/docs/docs/legal/acceptable-use-policy.md
+++ b/docs/docs/legal/acceptable-use-policy.md
@@ -3,8 +3,6 @@ title: Acceptable Use Policy
custom_edit_url: null
---
-## Introduction
-
This policy is an annex to the [Terms of Service](terms-of-service) and clarifies your obligations while using our Services.
## Use
diff --git a/docs/docs/legal/policies/account-lockout-policy.md b/docs/docs/legal/policies/account-lockout-policy.md
new file mode 100644
index 000000000..14463392d
--- /dev/null
+++ b/docs/docs/legal/policies/account-lockout-policy.md
@@ -0,0 +1,62 @@
+---
+title: Account Lockout Policy
+custom_edit_url: null
+---
+
+This policy is an annex to the [Terms of Service](../terms-of-service) that clarifies your obligations and our procedure handling requests where you can't get access to your ZITADEL Cloud services and data. This policy is applicable to situations where we, ZITADEL, need to restore your access for a otherwise available service and not in cases where the services are unavailable.
+
+## Why to do we have this policy?
+
+Users may not be able to access our services anymore due to loss of credentials or misconfiguration.
+In certain circumstances it might not be possible to recover the credentials through a self-service flow (eg, loss of 2FA credentials) or access the system to undo the configuration that caused the issue.
+These cases might require help from our support, so you can regain access to your data.
+
+We will require some initial information and conditions to be able to assist you, and will require further information to handle the request.
+We also keep the right to refuse any such request without providing a reason, in case you can't provide the requested information.
+
+## Scope
+
+In scope of this policy are requests to recover
+
+- ZITADEL Cloud account (customer portal)
+- Manager accounts to a specific instance
+- Undo configuration changes resulting in lockout (eg, misconfigured Action)
+
+Out of scope are requests to recover access
+
+- Where you have to option to ask another Admin/Manager
+- by end-users who should ask an Admin/Manager instead
+- self-hosted instances
+
+## Process
+
+Before you send a request to restore access to your account, please make sure that can't ask your manager/admin or another manager/admin to recover access.
+
+### ZITADEL Cloud account
+
+If you need to recover your ZITADEL Cloud account for the customer portal, please send an email to [support@zitadel.com](mailto:support@zitadel.com?subject=ZITADEL%20Cloud%20account%20lockout):
+
+- State clearly in the subject line that this is related to an account lockout for a ZITADEL Cloud account
+- The sender's email address must match the verified email address of the account owner
+- State the reason why you're not able to recover the account yourself
+
+Please allow us time to validate your request.
+Our support will get back to you to request additional information for verification.
+
+### Manager access to an Instance
+
+If you need to recover a Manager account to an instance, please make sure you can't recover the account via another user or service user with Manager permissions.
+
+Please visit the [support page in the customer portal](https://zitadel.cloud/admin/support):
+
+- State clearly in the subject line that this is related to an account lockout the affected instance
+- State the reason why you're not able to recover the account yourself
+
+Please allow us time to validate your request.
+Our support will get back to you to request additional information for verification.
+
+## Entry into force
+
+This policy is valid from May 31, 2023.
+
+Last revised May 31, 2023
\ No newline at end of file
diff --git a/docs/docs/legal/rate-limit-policy.md b/docs/docs/legal/rate-limit-policy.md
index 8cae76e99..48c78b6a4 100644
--- a/docs/docs/legal/rate-limit-policy.md
+++ b/docs/docs/legal/rate-limit-policy.md
@@ -2,7 +2,6 @@
title: Rate Limit Policy
custom_edit_url: null
---
-## Introduction
This policy is an annex to the [Terms of Service](terms-of-service) and clarifies your obligations while using our Services, specifically how we will use rate limiting to enforce certain aspects of our [Acceptable Use Policy](acceptable-use-policy).
diff --git a/docs/docs/legal/vulnerability-disclosure-policy.mdx b/docs/docs/legal/vulnerability-disclosure-policy.mdx
index 7b6cc85eb..74d04258e 100644
--- a/docs/docs/legal/vulnerability-disclosure-policy.mdx
+++ b/docs/docs/legal/vulnerability-disclosure-policy.mdx
@@ -3,8 +3,6 @@ title: Vulnerability Disclosure Policy
custom_edit_url: null
---
-## Introduction
-
At ZITADEL we are extremely grateful for security aware people who disclose vulnerabilities to us and the open source community.
All reports will be investigated by our team and we will work with you closely to validate and fix vulnerabilities reported to us.
@@ -91,6 +89,6 @@ In case we have confirmed your report, we may compensate you, given prior writte
## Entry into force
-This privacy policy is valid from March 16, 2023.
+This policy is valid from March 16, 2023.
Last revised March 16, 2023
diff --git a/docs/docs/self-hosting/deploy/kubernetes.mdx b/docs/docs/self-hosting/deploy/kubernetes.mdx
index 7d3385666..fa214d577 100644
--- a/docs/docs/self-hosting/deploy/kubernetes.mdx
+++ b/docs/docs/self-hosting/deploy/kubernetes.mdx
@@ -10,49 +10,61 @@ Installation and configuration details are described in the [open source ZITADEL
By default, the chart installs a secure and highly available ZITADEL instance.
For running an easily testable, insecure, non-HA ZITADEL instance, run the following commands.
-## Helm
-### Add the helm repositories for CockroachDB and ZITADEL
+## Add the Helm Repositories for CockroachDB and ZITADEL
```bash
helm repo add cockroachdb https://charts.cockroachdb.com/
helm repo add zitadel https://charts.zitadel.com
```
-### Install zitadel
+After you have your repositories added,
+you can setup ZITADEL and either
+- initialize an [IAM owner who is a human user](#setup-zitadel-and-a-human-admin) or
+- initialize an [IAM owner who is a service account](#setup-zitadel-and-a-service-account-admin)
-#### Install an insecure cockroachdb and zitadel release that works with localhost
+## Setup ZITADEL and a Human Admin
```bash
-# CockroachDB
+# Install CockroachDB
helm install crdb cockroachdb/cockroachdb \
--set fullnameOverride=crdb \
--set single-node=true \
--set statefulset.replicas=1
-# ZITADEL
+# Install ZITADEL
helm install my-zitadel zitadel/zitadel \
--set zitadel.masterkey="MasterkeyNeedsToHave32Characters" \
--set zitadel.configmapConfig.ExternalSecure=false \
--set zitadel.configmapConfig.TLS.Enabled=false \
--set zitadel.secretConfig.Database.cockroach.User.Password="a-zitadel-db-user-password" \
--set replicaCount=1
+
+# Make ZITADEL locally accessible
+kubectl port-forward svc/my-zitadel 8080
```
-#### Install an insecure zitadel release that works with localhost with a service account
+## Setup ZITADEL and a Service Account Admin
-!!!Caution!!! With this setup you only get a service account with a key and no admin account where you can login directly into ZITADEL.
+With this setup, you don't create a human user that has the IAM_OWNER role.
+Instead, you create a service account that has the IAM_OWNER role.
+ZITADEL will also create a key for your, with which you can authenticate to the ZITADEL API.
+For example, you can install ZITADEL and seemlessly provision ZITADEL resources after installation using [Terraform](/docs/guides/manage/terraform/basics.md).
+
+:::caution
+With this setup you only get a key for a service account. Logging in at ZITADEL using the login screen is not possible until you create a user with the ZITADEL API.
+:::
```bash
-# CockroachDB
+# Install CockroachDB
helm install crdb cockroachdb/cockroachdb \
--set fullnameOverride=crdb \
--set single-node=true \
--set statefulset.replicas=1
-# ZITADEL
+# Install ZITADEL
helm install --namespace zitadel --create-namespace my-zitadel zitadel/zitadel \
--set zitadel.masterkey="MasterkeyNeedsToHave32Characters" \
--set zitadel.configmapConfig.ExternalSecure=false \
@@ -63,20 +75,15 @@ helm install --namespace zitadel --create-namespace my-zitadel zitadel/zitadel \
--set zitadel.configmapConfig.FirstInstance.Org.Machine.Machine.Username="zitadel-admin-sa" \
--set zitadel.configmapConfig.FirstInstance.Org.Machine.Machine.Name="Admin" \
--set zitadel.configmapConfig.FirstInstance.Org.Machine.MachineKey.Type=1
+
+# Make ZITADEL locally accessible
+kubectl port-forward svc/my-zitadel 8080
```
-When helm is done, you get a command to retrieve your machine key, which is saved as a kubernetes secret, for example:
+When Helm is done, you can print your service account key from a Kubernetes secret:
```bash
kubectl -n zitadel get secret zitadel-admin-sa -o jsonpath='{ .data.zitadel-admin-sa\.json }' | base64 -D
```
-This key can be used to provision resources with for example [Terraform](/docs/guides/manage/terraform/basics.md).
-
-### Forward the ZITADEL service port to your local machine
-
-```bash
-kubectl port-forward svc/my-zitadel 8080:8080
-```
-
diff --git a/docs/docs/self-hosting/deploy/overview.mdx b/docs/docs/self-hosting/deploy/overview.mdx
index 8797c4359..d7ba3c92e 100644
--- a/docs/docs/self-hosting/deploy/overview.mdx
+++ b/docs/docs/self-hosting/deploy/overview.mdx
@@ -14,7 +14,7 @@ Choose your platform and run ZITADEL with the most minimal configuration possibl
## Prerequisites
- For test environments, ZITADEL does not need many resources, 1 CPU and 512MB memory are more than enough. (With more CPU, the password hashing might be faster)
-- A CockroachDB or Postgresql as only needed storage. Make sure to read our [Production Guide](./self-hosting/manage/production#prefer-cockroachdb) before you decide to use Postgresql.
+- A CockroachDB or Postgresql as only needed storage. Make sure to read our [Production Guide](/docs/self-hosting/manage/production#prefer-cockroachdb) before you decide to use Postgresql.
)
## Releases
diff --git a/docs/docs/self-hosting/manage/database/_postgres.mdx b/docs/docs/self-hosting/manage/database/_postgres.mdx
index ace58ef32..d012ac080 100644
--- a/docs/docs/self-hosting/manage/database/_postgres.mdx
+++ b/docs/docs/self-hosting/manage/database/_postgres.mdx
@@ -10,7 +10,7 @@ Be aware that PostgreSQL is only [Enterprise Supported](/docs/support/software-r
:::
If you want to use a PostgreSQL database instead of CockroachDB you can [overwrite the default configuration](../configure/configure.mdx).
-Make sure to read our [Production Guide](./self-hosting/manage/production#prefer-cockroachdb) before you decide to use it.
+Make sure to read our [Production Guide](/docs/self-hosting/manage/production#prefer-cockroachdb) before you decide to use it.
Currently versions >= 14 are supported.
diff --git a/docs/docs/self-hosting/manage/productionchecklist.md b/docs/docs/self-hosting/manage/productionchecklist.md
index e6f7d1bac..2f02361b7 100644
--- a/docs/docs/self-hosting/manage/productionchecklist.md
+++ b/docs/docs/self-hosting/manage/productionchecklist.md
@@ -9,13 +9,15 @@ To apply best practices to your production setup we created a step by step check
- [ ] Make use of configuration management tools such as Terraform to provision all of the below
- [ ] Use a secrets manager to store your confidential information
-- [ ] Reduce the manual interaction with your platform to an absolute minimum
+- [ ] Reduce the manual interaction with your platform to an absolute minimum
+
#### HA Setup
+
- [ ] High Availability for ZITADEL containers
- [ ] Use a container orchestrator such as Kubernetes
- [ ] Use serverless platform such as Knative or a hyperscaler equivalent (e.g. CloudRun from Google)
- [ ] Split `zitadel init` and `zitadel setup` for fast start-up times when [scaling](/docs/self-hosting/manage/updating_scaling) ZITADEL
-- [ ] High Availability for database
+- [ ] High Availability for database
- [ ] Follow the [Production Checklist](https://www.cockroachlabs.com/docs/stable/recommended-production-settings.html) for CockroachDB if you selfhost the database or use [CockroachDB cloud](https://www.cockroachlabs.com/docs/cockroachcloud/create-an-account.html)
- [ ] Configure backups on a regular basis for the database
- [ ] Test the restore scenarios before going live
@@ -26,12 +28,14 @@ To apply best practices to your production setup we created a step by step check
- [ ] Web Application Firewall
#### Networking
+
- [ ] Use a Layer 7 Web Application Firewall to secure ZITADEL that supports **[HTTP/2](/docs/self-hosting/manage/http2)**
- [ ] Limit the access by IP addresses if needed
- - [ ] Secure the access by rate limits for specific endpoints (e.g. API vs frontend) to secure availability on high load. See the [ZITADEL Cloud rate limits](https://zitadel.com/docs/apis/ratelimits) for reference.
- - [ ] Check that your firewall also filters IPv6 traffic```
+ - [ ] Secure the access by rate limits for specific endpoints (e.g. API vs frontend) to secure availability on high load. See the [ZITADEL Cloud rate limits](/docs/legal/rate-limit-policy) for reference.
+ - [ ] Check that your firewall also filters IPv6 traffic
### ZITADEL configuration
+
- [ ] Configure a valid [SMTP Server](/docs/guides/manage/console/instance-settings#smtp) and test the email delivery
- [ ] Add [Custom Branding](/docs/guides/manage/customize/branding) if required
- [ ] Configure a valid [SMS Service](/docs/guides/manage/console/instance-settings#sms) such as Twilio if needed
@@ -40,12 +44,14 @@ To apply best practices to your production setup we created a step by step check
- [ ] Declare and apply zitadel configuration using the zitadel terraform [provider](https://github.com/zitadel/terraform-provider-zitadel)
### Security
+
- [ ] Use a FQDN and a trusted valid certificate for external [TLS](/docs/self-hosting/manage/tls_modes#http2) connections
- [ ] Create service accounts for applications that interact with ZITADEL's APIs
- [ ] Make use of a CDN service to decrease the load for static assets served by ZITADEL
- [ ] Make use of a [security scanner](https://owasp.org/www-community/Vulnerability_Scanning_Tools) to test your application and deployment environment
### Monitoring
+
Use an appropriate monitoring solution to have an overview about your ZITADEL instance. In particular you may want to watch out for things like:
- [ ] CPU and memory of ZITADEL and the database
diff --git a/docs/docs/support/technical_advisory.mdx b/docs/docs/support/technical_advisory.mdx
index c866c3293..7fba13420 100644
--- a/docs/docs/support/technical_advisory.mdx
+++ b/docs/docs/support/technical_advisory.mdx
@@ -28,6 +28,13 @@ We understand that these advisories may include breaking changes, and we aim to
+## Subscribe to our Mailing List
+
+If you want to stay up to date on our technical advisories, we recommend subscribing to the mailing list.
+Go to the subscription form and add your email address.
+
+As ZITADEL Cloud customer, you can also login to the ZITADEL Customer Portal and enable the Technical Advisory Notifications in your settings.
+
## Categories
### Breaking Behaviour Change
diff --git a/docs/docs/support/troubleshooting.md b/docs/docs/support/troubleshooting.md
index 05e986fd4..8027152c3 100644
--- a/docs/docs/support/troubleshooting.md
+++ b/docs/docs/support/troubleshooting.md
@@ -37,6 +37,42 @@ If you're self hosting with a custom domain, you need to instruct ZITADEL to use
You can find further instructions in our guide about [custom domains](https://zitadel.com/docs/self-hosting/manage/custom-domain).
We also provide a guide on how to [configure](https://zitadel.com/docs/self-hosting/manage/configure) ZITADEL with variables from files or environment variables.
+## Invalid audience
+
+`invalid audience (APP-Zxfako)`
+
+This error message refers to the audience claim (`aud`) of your token.
+This claim identifies the audience, i.e. the resource server, that this token is intended for.
+If a resource server does not identify itself with a value in the "aud" claim when this claim is present, then the must be rejected (see [RFC7519](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3) for more details).
+
+You might encounter this error message from ZITADEL, typically when you authenticated with a client in one project and trying to access an application in another project.
+You need add a specific [reserved scope](http://localhost:3000/docs/apis/openidoauth/scopes#reserved-scopes) to add the projectID to the audience of the access token.
+
+The two scenarios should help you troubleshoot this issue:
+
+### Frontend to Backend
+
+You have one project for your frontend application and one project for your backend application.
+End-users authenticate to an application in your frontend project.
+The frontend then sends requests to the backend, validates the token with ZITADEL's introspection endpoint, and returns a payload to the frontend.
+The backend returns the error `invalid audience (APP-Zxfako)`.
+
+You must add the scope `urn:zitadel:iam:org:project:id:{projectId}:aud` to the auth request that is send from the front end.
+Replace `projectId` with the projectId of your backend.
+
+### Accessing ZITADEL's APIs
+
+You have a project for a frontend application.
+The application should also access the API of your ZITADEL, for example to pull a list of all users and display them on a user page.
+End-users authenticate to the application in the frontend project, but when calling the management API you get the error `invalid audience (APP-Zxfako)`.
+
+You must add the scope `urn:zitadel:iam:org:project:id:zitadel:aud` to the auth request that is send from the front end.
+
+When accessing your ZITADEL instance's APIs they act as a resource server.
+You can check the Console or via API and see that when you open your default organization there exists a project "ZITADEL" that contains different applications for each API and the Console.
+Like in the scenario above the access token requires to have an `aud` claim that includes the "ZITADEL" project.
+Instead of `urn:zitadel:iam:org:project:id:zitadel:aud` you could also use `urn:zitadel:iam:org:project:id:{projectId}:aud`, where `projectId` is the projectId of the Project "ZITADEL".
+
## WebFinger requirement for Tailscale
The WebFinger requirement and setup is a step a user has to take outside of their IdP set-up. WebFinger is a protocol which supports the ability for OIDC issuer discovery, and we use it to prove that the user has administrative control over the domain and to retrieve the issuer. This is a requirement we have in place for all users, regardless of their IdP, who use custom OIDC with Tailscale.
diff --git a/docs/sidebars.js b/docs/sidebars.js
index 3615dee28..cace2f404 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -150,6 +150,23 @@ module.exports = {
"guides/integrate/logout",
],
},
+ {
+ type: "category",
+ label: "Authenticate service users",
+ link: {
+ type: "generated-index",
+ title: "Authenticate Service Users",
+ slug: "/guides/integrate/serviceusers",
+ description:
+ "How to authenticate service users for machine-to-machine (M2M) communication between services. You also need to authenticate service users to access ZITADEL's APIs.",
+ },
+ collapsed: true,
+ items: [
+ "guides/integrate/private-key-jwt",
+ "guides/integrate/client-credentials",
+ "guides/integrate/pat",
+ ],
+ },
{
type: "category",
label: "Configure identity providers",
@@ -179,21 +196,9 @@ module.exports = {
collapsed: true,
items: [
{
- type: "category",
- label: "Authenticate service users",
- link: {
- type: "generated-index",
- title: "Authenticate Service Users",
- slug: "/guides/integrate/serviceusers",
- description:
- "How to authenticate service users",
- },
- collapsed: true,
- items: [
- "guides/integrate/private-key-jwt",
- "guides/integrate/client-credentials",
- "guides/integrate/pat",
- ],
+ type: 'link',
+ label: 'Authenticate service users',
+ href: '/guides/integrate/serviceusers',
},
"guides/integrate/access-zitadel-apis",
"guides/integrate/access-zitadel-system-api",
@@ -587,10 +592,17 @@ module.exports = {
type: "category",
label: "Policies",
collapsed: false,
+ link: {
+ type: "generated-index",
+ title: "Policies",
+ slug: "/legal/policies",
+ description: "Policies and guidelines in addition to our terms of services.",
+ },
items: [
"legal/privacy-policy",
"legal/acceptable-use-policy",
"legal/rate-limit-policy",
+ "legal/policies/account-lockout-policy",
"legal/vulnerability-disclosure-policy",
],
},
diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js
index 544f43cbb..0e88b075a 100644
--- a/docs/src/pages/index.js
+++ b/docs/src/pages/index.js
@@ -72,7 +72,7 @@ const features = [
description=""
/>
|