fix: 하네스 제거 및 keycloak 문서 보강

This commit is contained in:
DongHyeonka
2026-07-25 12:53:13 +09:00
parent 6c53ded9cb
commit d71669eb59
2329 changed files with 138239 additions and 172816 deletions
@@ -1 +0,0 @@
../../vault/20-evidence/official-docs/spring-data-pageable-defaults.md
@@ -0,0 +1,126 @@
---
title: "official-doc / Spring Data — Pageable / Page Defaults"
source_type: official-doc
url: https://docs.spring.io/spring-data/commons/reference/repositories/core-concepts.html
archive_url:
vendor: Spring (VMware/Broadcom)
related_branches: [feature-api-contract-baseline]
related_projects: [ca-skeleton]
tags: [official-doc, ca-skeleton, api-design, spring-data, spring-mvc, offset-pagination]
status: raw
confidence: high
created: 2026-05-31
last_reviewed: 2026-05-31
---
# official-doc / Spring Data — Pageable / Page Defaults
> Layer: `raw/` — 외부 자료(공식 문서 / 대기업 기술 블로그)의 **원문 발췌·출처 기록**.
> 본 파일은 `raw/official-docs/` 에 보관. 검증된 요약은 `/ingest` 후 `wiki/concepts/` 에 별도 작성. 원본은 raw 에 영구 보관.
## Parent / 활용 branch (필수)
> 이 자료는 **혼자 존재하지 않는다.** 어느 branch 의 구현 결정의 **근거**로서 보관됨.
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-api-contract-baseline]] | D18: `page` 0-indexed (Spring `Pageable` default 와 정합), `size` default 20, `maxPageSize` default 2000 (unbounded ≠ project-internal cap 100) — DoS footgun 근거 |
## 출처 / Source
- 원본 URL (1): https://docs.spring.io/spring-data/commons/reference/repositories/core-concepts.html
- 원본 URL (2 — Pageable binding in MVC): https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html
- 원본 URL (3 — query-methods zero-indexed normative): https://docs.spring.io/spring-data/commons/reference/repositories/query-methods-details.html
- 원본 URL (4 — Javadoc resolver support): https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.html
- 원본 URL (5 — source constants): https://github.com/spring-projects/spring-data-commons/blob/main/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.java
- 아카이브 URL: (미지정)
- 저자 / 조직: Spring Data Team (VMware/Broadcom)
- 발행일: 현행 (Spring Data Commons 4.0.x 기준 — URL 은 latest stable redirect)
- 마지막 확인일: 2026-05-31
## 왜 저장했는지 / Why archived
D18 결정 (`page` 0-indexed, `size` default 20, max cap) 이 `UNSUPPORTED_DECISION` 으로 남아 있었기 때문이다. Spring 공식 문서가 `Pageable` 의 0-indexed default 와 `size` default 20 을 normative 하게 진술하므로, 본 raw 가 그 근거를 vendor-doc 강도로 직접 정당화한다. 추가로 `PageableHandlerMethodArgumentResolverSupport``DEFAULT_MAX_PAGE_SIZE = 2000`*spring 기본* unbounded 가 아님을 명시해, project 의 100 cap 이 별도 opt-in override 임을 구별하게 한다.
## 핵심 인용 / Key quotes (verbatim, self-grep 통과)
> [§core-extensions — Request Parameters for Pageable table]
> "| `page` | Page you want to retrieve. **0-indexed** | 0 |"
> (source: https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html — request parameter table row, line 12 of fetched text)
> [§core-extensions — Request Parameters for Pageable table]
> "| `size` | Size of the page you want to retrieve | 20 |"
> (source: https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html — request parameter table row, line 13 of fetched text)
> [§query-methods-details — Paging, Sorting & Limiting]
> "`Pageable` is **zero-indexed** (starts at 0). The infrastructure recognizes special types like `Pageable`, `Sort`, and `Limit` to apply dynamic pagination, sorting, and limiting."
> (source: https://docs.spring.io/spring-data/commons/reference/repositories/query-methods-details.html — Important note, line 15 of fetched text)
> [§core-extensions — Default Pageable Value]
> "The default `Pageable` passed into the method is equivalent to: `PageRequest.of(0, 20) // page=0, size=20`"
> (source: https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html — Default Pageable Value section, line 64 of fetched text)
> [§PageableHandlerMethodArgumentResolverSupport Javadoc — setMaxPageSize]
> "Configures the maximum page size to be accepted. This prevents potential attacks trying to issue an `OutOfMemoryError`. Defaults to `DEFAULT_MAX_PAGE_SIZE`."
> (source: https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.html — setMaxPageSize method, line 7 of fetched text)
> [§PageableHandlerMethodArgumentResolverSupport source — constant]
> "DEFAULT_MAX_PAGE_SIZE = 2000"
> (source: https://github.com/spring-projects/spring-data-commons/blob/main/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.java — line 24 of fetched text)
> [§PageableHandlerMethodArgumentResolverSupport Javadoc — setOneIndexedParameters]
> "Default: `false` (page 0 = first page)"
> (source: https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.html — setOneIndexedParameters, line 12 of fetched text)
## Claims Extracted / 추출된 주장
> 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다.
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| SPRING-PAGE-C1 | Spring MVC 에서 `Pageable` 을 controller method argument 로 사용할 때 `page` request parameter 는 **0-indexed** 이며 default 값은 0 이다 | [§core-extensions table] "Page you want to retrieve. **0-indexed** \| 0" | `official-vendor-doc` | Spring Data Web Support (`@EnableSpringDataWebSupport`) 활성화 시, `PageableHandlerMethodArgumentResolver` 등록 환경 | 1-indexed 방식이 Spring 에서 *불가능*하다는 뜻이 아님 (`setOneIndexedParameters(true)` opt-in 가능). 다른 프레임워크(JAX-RS 등)의 default 에는 적용 불가 |
| SPRING-PAGE-C2 | `size` request parameter 의 default 값은 **20** 이다 | [§core-extensions table] "Size of the page you want to retrieve \| 20" | `official-vendor-doc` | 동일 환경 (`PageableHandlerMethodArgumentResolver` 등록) | `size=0` 또는 `size=-1` 의 처리 방식(reject/accept)은 본 인용에 명시되지 않음. default 만 정의, maximum 은 C4 참조 |
| SPRING-PAGE-C3 | `Pageable`**zero-indexed** (starts at 0) 이다 — query method layer 에서 normative 진술 | [§query-methods-details] "`Pageable` is **zero-indexed** (starts at 0)." | `official-vendor-doc` | Spring Data repository query method 에 `Pageable` parameter 를 전달하는 모든 경우 | request parameter 파싱 단계(MVC layer)의 behavior 를 직접 진술하는 것이 아닌, Spring Data 레포지토리 infrastructure 레벨의 `Pageable` 의미론. 두 레이어가 일관됨은 C1 이 보완 |
| SPRING-PAGE-C4 | `PageableHandlerMethodArgumentResolverSupport``setMaxPageSize``DEFAULT_MAX_PAGE_SIZE` 를 기본값으로 사용하며, 소스 코드에서 해당 상수는 **2000** 이다 | [§Javadoc] "Configures the maximum page size to be accepted. This prevents potential attacks trying to issue an `OutOfMemoryError`. Defaults to `DEFAULT_MAX_PAGE_SIZE`." / [§source] "DEFAULT_MAX_PAGE_SIZE = 2000" | `official-vendor-doc` | `PageableHandlerMethodArgumentResolverSupport` 를 기반으로 하는 `PageableHandlerMethodArgumentResolver``ReactivePageableHandlerMethodArgumentResolver` | `DEFAULT_MAX_PAGE_SIZE = 2000` 이 github source fetch 기준 값이며 버전별로 다를 수 있음. 본 raw 의 fetch 는 main branch 기준 — Spring Data Commons 4.0.x release 에서 상이할 가능성 요확인. "Integer.MAX_VALUE" 가 아닌 2000 이 default 라는 것이 핵심 |
| SPRING-PAGE-C5 | method 의 fallback `Pageable` (annotation 없을 때) 은 `PageRequest.of(0, 20)` 과 동등하다 | [§core-extensions] "The default `Pageable` passed into the method is equivalent to: `PageRequest.of(0, 20) // page=0, size=20`" | `official-vendor-doc` | `@PageableDefault` annotation 이 없는 controller method parameter 에 `Pageable` 주입 시 | `@PageableDefault(size = N)` 로 override 하면 달라짐. fallback 이 적용되는 것은 request parameter 가 아예 없을 때뿐 — `?page=0` 이 명시되면 이 fallback 이 아닌 request 값 우선 |
| SPRING-PAGE-C6 | `setOneIndexedParameters(boolean)` 의 default 는 `false` 이므로 **page 0 = first page** 가 기본 동작이다 | [§Javadoc] "Default: `false` (page 0 = first page)" | `official-vendor-doc` | `PageableHandlerMethodArgumentResolver` 기본 구성 (커스터마이징 없는 상태) | `setOneIndexedParameters(true)` 로 바꾸면 page 1 = first page 로 전환 — 이 경우 클라이언트/서버 계약이 모두 1-indexed 로 변경됨. Spring Security 또는 별도 필터가 parameter 를 조작하는 경우 별도 검증 필요 |
### Strength 허용값 사용 근거
모든 Claim 은 `official-vendor-doc` 이다 — Spring Data Commons 는 VMware/Broadcom 이 유지하는 공식 벤더 문서이며 IETF/W3C 표준이 아님.
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것**:
- `SPRING-PAGE-C1`: Spring Data Web Support 환경에서 `page` request parameter 가 0-indexed 이고 default = 0
- `SPRING-PAGE-C2`: 동일 환경에서 `size` default = 20
- `SPRING-PAGE-C3`: Spring Data 레포지토리 infrastructure 에서 `Pageable` 자체가 zero-indexed
- `SPRING-PAGE-C4`: `PageableHandlerMethodArgumentResolverSupport.DEFAULT_MAX_PAGE_SIZE = 2000` (source fetch 기준) — Spring 기본 max 가 *별도 설정 없으면* 2000 임을 의미하며, `Integer.MAX_VALUE` 처럼 완전히 unbounded 는 아님
- `SPRING-PAGE-C5`: annotation 없는 경우 fallback = `PageRequest.of(0, 20)`
- `SPRING-PAGE-C6`: `setOneIndexedParameters` default = false → page 0 = first page 가 기본
- **이 자료가 증명하지 않는 것**:
- Spring docs 가 vendor-doc 이며 IETF/W3C 표준이 아님 — `official-vendor-doc` strength 이므로 표준 lock-in 근거가 될 수 없음
- `size` 의 상한이 "없다" (unbounded) 는 주장 — Spring 은 `DEFAULT_MAX_PAGE_SIZE = 2000` 을 기본 상한으로 가짐. 단 2000 은 project 의 100 cap 보다 훨씬 크므로 DoS footgun 은 여전히 유효
- project 의 `size` max 100 cap 결정은 Spring docs 의 *기본 동작* 이 아니라 **project-internal opt-in override** — 본 raw 는 Spring default behavior 만 정당화하며, 100 cap 선택은 D18 의 project-internal trade-off
- `Pageable` 의 동작이 Spring Data Commons 버전별로 동일함 — 본 raw 는 fetch 시점 (2026-05-31) 의 latest stable 문서 기준. `DEFAULT_MAX_PAGE_SIZE` 등의 상수는 버전업 시 변경될 수 있음
- 다른 WAS(Undertow, Netty) 또는 다른 Spring 구성(reactive)에서의 동작 — 본 인용은 Servlet stack + `PageableHandlerMethodArgumentResolver` 기준
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- `@EnableSpringDataWebSupport` 가 ca-skeleton 의 `WebMvcConfigurer` 에 적용되어 있는지 확인 (없으면 `Pageable` 자동 binding 미동작)
- `maxPageSize` 가 기본 2000 이라면 project 의 100 cap 은 `PageableHandlerMethodArgumentResolver``setMaxPageSize(100)` 또는 별도 `@PageableDefault` + validator 를 통해 강제해야 함 — Spring 기본값에 의존하면 2000 까지 허용됨
- `setOneIndexedParameters` 가 false (default) 로 유지되는지 — ca-skeleton 설정에서 이를 true 로 변경하면 0-indexed 정합이 깨짐
## 메모 / Notes
- `DEFAULT_MAX_PAGE_SIZE = 2000` 값은 github `main` branch source 에서 확인했으며, Spring Data Commons 공식 released Javadoc 에는 상수의 실제 값이 직접 노출되지 않음. release 버전 확인 시 `spring-data-commons-x.y.z.jar``PageableHandlerMethodArgumentResolverSupport.class` 를 디컴파일하거나 release notes 에서 확인 권장.
- D18 의 "Spring 기본 max = Integer.MAX_VALUE 라서 DoS footgun" 이라는 기존 설명은 부정확했음. 실제 default max 는 2000 이지만, project 의 비즈니스 요구 상 100 으로 cap 하는 것은 여전히 합리적인 trade-off.
- Spring MVC 에서 `Pageable` 바인딩이 동작하려면 `spring-data-commons` + `spring-data-web` 의존성이 classpath 에 있어야 하고 `@EnableSpringDataWebSupport` 가 활성화되어 있어야 함.
- 추가로 봐야 할 동일 출처 페이지: Google AIP-158 (cursor pagination shape), JSON:API pagination format (D7 근거).
## Related / 관련
- 이 자료를 근거로 사용하는 branch-note: [[raw/branch-notes/feature-api-contract-baseline]] (D18)
- 같은 pagination 주제 — JSON:API 표준: [[raw/official-docs/jsonapi-pagination-format]]
- 이후 생성 예정 — cursor pagination AIP 근거: [[raw/official-docs/google-aip-158-pagination]]
- 이 자료를 인용한 wiki 요약: (미생성 — `/ingest``wiki/concepts/` 에 추출)