mirror of
https://github.com/zitadel/zitadel.git
synced 2026-10-24 23:27:43 -05:00
> Stacked on zitadel/zitadel#12875 (reuses `SystemDefaults.QueryLimit`). Retarget to `main` once that's merged. ## Which Problems Are Solved The v1 list endpoints (admin, auth, management, system) apply no limit. A request without `limit` returns all matching rows, and an explicit `limit` is never capped. The same applies to the 6 change endpoints (`ListOrgChanges`, `ListUserChanges`, `ListProjectChanges`, `ListProjectGrantChanges`, `ListAppChanges`, `ListMyUserChanges`). Without a limit, they return the full history of the object. The only bound is the audit log retention, which restricts events by age (not by count) and is disabled by default (`AuditLogRetention: 0s`). This is a regression. The v1 endpoints previously applied `Auth/Admin/Mgmt.SearchLimit` (1000) through `EnsureLimit`: a missing limit defaulted to 1000, and a higher limit was rejected. The check lived in the old eventsourcing repositories and was dropped when the endpoints were migrated to the `query` package: #2342, #2433, #2383, #2612, #2820, #2818, #2838, #3075, #3096. The `ListQuery.limit` docs still describe the old behavior. ## How the Problems Are Solved - New `SystemDefaults.V1QueryLimit`: uses `MaxQueryLimit` (1000 by default) as both the default and the maximum, restoring the previous v1 behavior. Limits above it return `InvalidArgument` (`QUERY-4M0fs`). - `object.ListQueryToModel` now takes the `SystemDefaults` and applies it. All 43 v1 call sites were updated. - The change endpoints apply the same check through `change.ChangeQueryToModel` (their `ChangeQuery.limit` docs promise the same default and maximum). Console always passes 30 / 20 there. - `SystemDefaults` is passed to the admin and system servers. Management and auth already had them. - Removed the `Auth.SearchLimit` and `Admin.SearchLimit` configs: - `Admin.SearchLimit` was never read. - `Auth.SearchLimit` only capped the refresh tokens of `ListMyRefreshTokens` and `RevokeAllMyRefreshTokens` (which revokes the listed tokens). Both now use `MaxQueryLimit` instead, with the same default of 1000. This only concerns the legacy refresh tokens, which haven't been issued since v2.53. - Unknown config keys are ignored, so existing configs and env vars keep working. - Removed the unused `EnsureLimit` methods. - The v1 list converters take the context first, followed by the system defaults. - Updated the `ListQuery.limit` and `ChangeQuery.limit` API docs and the `MaxQueryLimit` comment in `defaults.yaml`, which now describes where it applies (v1 lists and change histories, refresh tokens) and that the events API (`ListEvents`) keeps its own cap of 1000. ## ⚠️ Behavior change - Requests without `limit` return at most `MaxQueryLimit` (1000) results. - Requests with `limit` > 1000 fail with `InvalidArgument`. - Self-hosters can restore the previous behavior with `MaxQueryLimit: 0`. This applies globally, including to v2. Console: all v1 list calls pass page sizes ≤ 250, except two that load all projects of an organization: - the startup project preload (`listProjects(0, 0)` / `listGrantedProjects(0, 0)`), used for the project counts, shortcuts and breadcrumbs. zitadel/zitadel#12881 replaces it (counts from `details.totalResult`, projects loaded by ID). - the projects grid view (`project-grid.component.ts`), which has no pagination. With the default of 1000, it only misses projects (and pinned grid entries) for organizations with more than 1000 owned or granted projects. The largest organizations on ZITADEL Cloud are well below 1000 projects. ## Additional Changes - Deprecated the unused `query` and `result` fields of `ListProjectGrantMemberRolesRequest`. The endpoint has no list semantics: it always returns all roles possible on the project grant level, like the other member role endpoints, whose requests are empty. ## Additional Context - Tests: - unit tests for `V1QueryLimit` and `ListQueryToModel` - limit-exceeded integration tests for admin `ListOrgs`, management `ListUsers`, `ListProjects` and `ListOrgChanges`, and system `ListInstances` - A technical advisory covering both PRs is planned. - Needs a v4.x backport together with zitadel/zitadel#12875. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>