Files
zitadel/AGENTS.md
fac78678c2 chore(deps): bump npm dependencies and prune pnpm overrides (#12819)
> [!IMPORTANT]
> Our engineering team is currently focused on the [next generation of
ZITADEL](https://github.com/zitadel/nextgen), so our capacity to review
community pull requests is limited. We cannot guarantee that your pull
request will be reviewed or merged. For larger changes, please open an
issue or discussion before you begin. Thank you for contributing and for
your understanding.

# Which Problems Are Solved

- Several npm dependencies in the workspace were behind their latest
releases, and some transitive dependencies were locked to older versions
even though their parents already allowed newer ones.
- The `overrides` list in `pnpm-workspace.yaml` had drifted. Four
entries were no longer needed, and none of them said which package
pinned the old version, so it was hard to tell when an entry could be
removed.
- `apps/docs` declared `@scalar/api-reference`, which isn't used
anywhere and pulled in a large dependency tree.

# How the Problems Are Solved

**Direct dependency bumps**

| Package | From | To | Where | Type |
|---|---|---|---|---|
| `next` (+ `@next/eslint-plugin-next`) | 16.2.11 | 16.3.6 | login, docs
| minor |
| `@faker-js/faker` | ^9.9.0 | ^10.6.0 | login (dev) | **major** |
| `testcontainers` | ^11.14.0 | ^12.1.0 | login (dev) | **major** |
| `vitest` | ^4.1.6 | ^4.1.11 | login, client (dev) | patch |
| `@angular/*` (framework, build, cli) | ^21.2.19 | ^21.2.24 | console |
patch |
| `nx` | 22.7.7 | 22.7.12 | root (dev) | patch |
| `@changesets/cli` | ^2.31.0 | ^2.31.1 | root (dev) | patch |
| `wait-on` | ^9.0.10 | ^9.1.0 | root (dev) | minor |
| `js-yaml` | ^4.3.1 | ^4.3.2 | docs | patch |
| `tsx` | 4.21.0 | 4.23.15 | docs (dev) | minor |
| `@scalar/api-reference` | ^1.55.3 | removed | docs | unused |

**Transitive dependencies refreshed within their existing ranges**
(lockfile only): `qs`, `body-parser`, `hono`, `fast-uri`, `joi`,
`js-yaml@3`, `@vitest/mocker`, `sharp`.

**Overrides**

- Removed, because their parents now depend on fixed versions: `axios`
(nx), `postcss` and `sharp` (next 16.3), `uuid` (testcontainers 12 no
longer uses it).
- Kept or added, each with a comment naming the parent that pins the old
version:
- `brace-expansion`, `smol-toml`: `nx` pins exact versions, even in its
latest 22.x and 23.x releases.
  - `esbuild`: `tsup` (latest 8.5.1) still allows only `^0.27`.
- `@opentelemetry/core`, `@opentelemetry/propagator-jaeger`: kept on
purpose, see Additional Context.

# Additional Changes

- **Login build config:** Next.js 16.3 type-checks every file matched by
`tsconfig.json` during `next build`. That now includes unit tests, which
vitest runs without type-checking. `next.config.mjs` now points
`typescript.tsconfigPath` to a new `tsconfig.build.json` that extends
`tsconfig.json` and excludes `*.test.ts(x)`. Editors and vitest keep
using `tsconfig.json`.
- **`.nvmrc`:** `lts/iron` (Node 20) → `lts/jod` (Node 22), to match
`CONTRIBUTING.md`, CI and the devcontainer.
- **Login `esbuild` range:** `^0.28.0` → `^0.28.1`, so the manifest
matches the specifier pnpm records after applying the `esbuild`
override.
- **Skill:** a new tool-neutral runbook,
`skills/npm-dependency-audit.md`, with a small helper script
(`skills/npm-dependency-audit-summary.mjs`). It's listed in
`skills/README.md` and linked from `AGENTS.md`, and describes this
workflow for contributors and coding agents: fixing findings at the
package that introduces them, pruning overrides and documenting the ones
that remain.

## Breaking or behavior-changing updates and what to check

### `next` 16.2 → 16.3 (login, docs)

Upstream changes that are relevant here:
- Proxy (middleware) matching and request URL normalization were
reworked.
- Turbopack changes, a deprecation warning for the Edge runtime, and
`next/image` cache hardening.
- A CSP nonce is now added to loading and template scripts.
- Stricter TypeScript checking during the build (handled above).

The login's `src/proxy.ts` matcher and `basePath` are the most sensitive
parts.

Manual checks:
- **Login, standalone image:** `pnpm nx run @zitadel/login:pack`, or run
the Docker Compose setup and go through the login at `/ui/v2/login`:
  - `/ui/v2/login/loginname` → `/password` → signed in
  - `/ui/v2/login/register` (with email verification at `/verify`)
  - MFA: `/otp/time-based`, `/otp/email`, `/otp/sms`, `/passkey`, `/u2f`
  - external IdP login through `/idp` and the `/idps/callback/*` route
  - `/logout` and the device flow at `/device`
- **Login, proxy passthrough:** requests to
`/.well-known/openid-configuration`, `/oidc/v1/*` (authorize, end
session), `/saml/v2/*` and `/oauth/*` still get the forwarded headers.
For example, an OIDC authorization-code flow started from a sample app
completes.
- **Login, server actions behind a reverse proxy** with
`SERVER_ACTION_ALLOWED_ORIGINS` set: submitting a form, for example the
password page, still works.
- **Login, OTEL:** with `OTEL_SDK_DISABLED` unset, traces and metrics
still reach the collector. The build now prints a Turbopack warning
about `process.exit` in `src/instrumentation.ts` for the Edge runtime.
It's harmless: `register()` returns early unless `NEXT_RUNTIME ===
"nodejs"`.
- **Docs:** `/docs` home, search, a versioned page such as
`/docs/v4.17/...`, an API reference page under
`/docs/reference/api/...`, and an OG image under `/og/docs/...`.

### `@faker-js/faker` 9 → 10 (login acceptance tests only)

v10 is ESM-only, requires Node ≥ 20.19 and removes deprecated modules
(`faker.name`, `faker.address`, `internet.userName`). The acceptance
tests only use `internet.email`, `person.firstName`, `person.lastName`
and `phone.number`, which didn't change. Check: the login acceptance
(Playwright) job is green.

### `testcontainers` 11 → 12 (login dockerized tests only)

v12 requires Node ≥ 22.22. CI, `CONTRIBUTING.md` (v22.x) and the
devcontainer already use Node 22. `.nvmrc` still pointed to Node 20
(`lts/iron`, end of life), so it now points to `lts/jod` (Node 22). If
you use nvm, run `nvm install` again. Its default wait strategy is now
the image's Docker healthcheck instead of the listening ports. Every
container in `apps/login/dockerized/**` sets an explicit
`withWaitStrategy(...)`, so they aren't affected. Check: `pnpm --filter
@zitadel/login test-dockerized` (needs Docker).

### `@scalar/api-reference` removed (docs)

It isn't imported anywhere in `apps/docs`, and `fumadocs-openapi` only
has an optional peer on `@scalar/api-client-react`, which is unrelated.
Check: the API reference pages in the docs render and the "try it" panel
behaves as before.

### Tooling (`nx`, `@changesets/cli`, `wait-on`, `vitest`, `tsx`,
Angular patch releases)

These are patch or minor releases with no expected impact. `wait-on` is
used by `apps/api` and `tests/functional-ui` to wait for `/debug/ready`.
`tsx` runs the docs generation scripts (`generate-index-pages`,
`generate-error-reference`, `check-links`).

Check: the console smoke test. Sign in to the console and open the
organization, users, projects and an application detail page.

## Verification done locally

- `pnpm audit`: no findings.
- `@zitadel/login`: `build`, `lint`, `test-unit` (62 files / 938 tests)
pass.
- `@zitadel/console`: `build`, `lint` pass.
- `@zitadel/client`: `build`, `lint`, `test-unit` pass.
- `@zitadel/docs`: `build` passed with Next 16.3.6 before
`@scalar/api-reference` was removed. `check-types` passes after the
removal. A second full build couldn't finish locally because the disk
ran out of space (`ENOSPC`), so please rely on CI for it. `docs:lint`
reports MDX `no-undef` errors, mostly in fetched versioned content. None
of the lint tooling changed in this PR, so these don't come from it.
- Not run locally: login acceptance (Playwright), login dockerized
tests, functional UI (Cypress).

# Additional Context

- Follow-up: bump the login's OpenTelemetry packages
(`@opentelemetry/sdk-node` 0.218 → 0.222, `auto-instrumentations-node`
0.76 → 0.80, stable packages 2.7 → 2.11) and then remove the last two
overrides. It's a separate PR because `instrumentation-http` then only
emits stable HTTP semantic conventions (`http.request.method`,
`http.response.status_code`, `url.path` instead of `http.method`,
`http.status_code`, `http.target`). That affects operators' dashboards
and alerts, and the OTEL integration tests need updating.
- Follow-up: remove the `nx` overrides once a stable nx release ships
`smol-toml` ≥ 1.7.1 (already in `23.3.0-beta`), and the `esbuild`
override once `tsup` allows esbuild 0.28.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com>
2026-10-01 11:49:30 +00:00

8.4 KiB

ZITADEL Monorepo Guide for AI Agents

Mission & Context

ZITADEL is an open-source Identity Management System (IAM) written in Go and Angular/React. It provides secure login, multi-tenancy, and audit trails.

Read Order

  1. Read this file first.
  2. Read the nearest scoped AGENTS.md for the area you edit.
  3. If multiple scopes apply, use the most specific path.

Repository Structure Map

  • apps/: Consumer-facing web applications.
    • login: Next.js authentication UI. See apps/login/AGENTS.md.
    • docs: Fumadocs documentation app. See apps/docs/AGENTS.md.
    • api: Backend Nx app target. See apps/api/AGENTS.md.
  • console/: Angular Management Console. See console/AGENTS.md.
  • internal/: Backend domain and service logic. See internal/AGENTS.md.
  • proto/: API definitions. See proto/AGENTS.md.
  • packages/: Shared TypeScript packages. See packages/AGENTS.md.
  • tests/functional-ui/: Cypress functional UI tests. See tests/functional-ui/AGENTS.md.

Technology Stack & Conventions

  • Orchestration: Nx is used for build and task orchestration.
  • Package Manager: pnpm.
  • Backend:
    • Go Version Source of Truth: Inspect go.mod before Go work (go and optional toolchain directives).
    • Communication: For V2 APIs, connectRPC is the primary transport. gRPC and HTTP/JSON endpoints are also supported.
    • Pattern: The backend is transitioning to a relational design. Events are still persisted in a separate table for history/audit, but events are not the system of record.
  • Frontend:
    • Console: Angular + RxJS.
    • Login/Docs: Next.js + React.

ZITADEL Domain & Multi-Tenancy Logic

1. Hierarchy & Ownership

ZITADEL follows a strict hierarchical containment model. When generating code, logic, or translations, adhere to this structure:

  • System (Installation): The entire ZITADEL deployment. Global settings are applied through runtime configuration files or environment variables. See cmd/defaults.yaml.
  • Instance (The "Identity System"):
    • Definition: A logical partition/virtual tenant. It is a "System inside a System."
    • Isolation: Data and settings are strictly isolated between instances.
    • Translation Rule: NEVER translate as "Example" or "Case." Use technical terms like "Tenant," "Environment," or the local equivalent of "Logical System Entity."
  • Organization: A group within an Instance. It owns Users, Projects, and Roles.
  • Project: A collection of Applications and Auth Policies within an Org.

2. Permission Scoping (The "Administrative" Context)

  • System User: Manages the entire Installation and creates Instances over the system API.
  • Instance Admin: Manages Instance-wide policies (Password complexity, Identity Providers, Organizations).
  • Organization Admin: Manages users and access within a specific Organization.

3. Language & Tone Guidelines

  • Avoid Ambiguity: When referring to an 'Instance', the context is always infrastructure/tenancy.
  • Technical Precision: In UI strings, prefer clarity over brevity if "Instance" is likely to be misinterpreted in the target language.

4. Technical Glossary & Localization Mapping

Language Technical Term (SaaS/Cloud) Why this term? "Avoid this (The ""Example"" Trap)"
Chinese (Simplified) 实例 (Shílì) Standard for a cloud resource/entity. 例子 (Lìzi)
Japanese インスタンス (Insutansu) Katakana transliteration; industry standard. 例 (Rei)
Korean 인스턴스 (Inseuteonseu) Hangul transliteration; industry standard. 예 (Ye)
German Instanz Matches English but implies a technical occurrence. Beispiel
French Instance "Standard but often requires ""de ZITADEL"" for clarity." Exemple
Spanish Instancia Technical entity in software architecture. Ejemplo
Portuguese Instância Standard technical terminology. Exemplo
Russian Инстанс (Instans) Modern SaaS jargon (transliterated). Пример (Primer)

Translation Guardrails

If a translation is requested for a language not listed above, follow these priority rules for the word 'Instance':

  1. Priority 1 (Transliteration): Use the phonetic transliteration into the local script (common in Japanese/Korean/Russian).
  2. Priority 2 (System Entity): Use a term that implies a "running process" or "logical environment."
  3. Priority 3 (Tenant): If 'Instance' is ambiguous, use the local word for 'Tenant' (e.g., 租户 in Chinese).
  4. Strict Ban: NEVER use words that mean "an illustration", "a case", "a sample", or "an example."

5. Deployment Targets

ZITADEL supports multiple deployment methods. Each has its own directory and conventions:

Target Location Status Notes
Docker Compose deploy/compose/ Supported Single-node, graduated from quickstart to semi-production. See deploy/compose/AGENTS.md for directory-specific rules.
Kubernetes (Helm) External (zitadel-charts) Supported Official Helm chart for production workloads. Docs at apps/docs/content/self-hosting/deploy/kubernetes/.
apt/rpm packages Planned Not yet available Future packaging target.

When generating deployment-related content:

  • Docker Compose is the recommended path for getting started and homelab/single-node deployments
  • Kubernetes is the recommended path for production workloads
  • Always reference the correct deployment method for the user's context
  • The same ZITADEL_* environment variable model applies across all deployment methods

Command Rules

Run commands from the repository root.

  • Use verified Nx targets only.
  • If target availability is unclear, run pnpm nx show project <project>.
  • Do not assume all projects have test, lint, build, or generate targets.
  • Known exception: @zitadel/console has no configured test target.

Verified Common Targets

  • @zitadel/api: prod, build, build-linux, pack, generate, generate-install, lint, test, test-unit, test-integration
  • @zitadel/login: dev, build, pack, lint, test, test-unit, test-integration
  • @zitadel/docs: dev, build, generate, install-proto-plugins, check-links, check-types, test, lint
  • @zitadel/console: dev, build, generate, install-proto-plugins, lint
  • @zitadel/compose: test-config, test-run, test-e2e, test, test-full, stop

Proto Plugin Binaries

All proto plugins are installed to .artifacts/bin/<GOOS>/<GOARCH>/ and Nx-cached. generate targets wire up the correct install dependency and prepend .artifacts/bin/ to $PATH — no manual install step is needed.

PR Title Convention

PR titles are validated by the Semantic PR app. Format:

<type>(<scope>): <short summary>

Types: must come from the list in .github/semantic.yml under types: — e.g. feat, fix, docs, refactor, perf, test, build, ci, chore, revert.

Scopes: optional, but if used must come from the list in .github/semantic.yml under scopes:. When in doubt, omit the scope — do not invent values not on that list.

Skills

Tool-neutral runbooks live in skills/ (see skills/README.md). Read the matching one before starting such a task.

  • skills/npm-dependency-audit.md: Fix pnpm audit findings at their origin, prune pnpm-workspace.yaml overrides and prepare a version-bump PR.
  • skills/test-actor-in-action-v2.md: Verify the impersonation actor reaches Actions v2 targets on a local instance.

Documentation

  • Human Guide: See CONTRIBUTING.md for setup and contribution details.
  • API Design: See API_DESIGN.md for API specific guidelines.