Skip to content

docs: 식별자 은닉의 근거를 전역 조인 키·접근 통제로 다시 쓴다 (06 §5.3) - #24

Merged
cherry-go-round merged 1 commit into
mainfrom
docs/identifier-concealment-rationale
Jul 29, 2026
Merged

docs: 식별자 은닉의 근거를 전역 조인 키·접근 통제로 다시 쓴다 (06 §5.3)#24
cherry-go-round merged 1 commit into
mainfrom
docs/identifier-concealment-rationale

Conversation

@minyongP

Copy link
Copy Markdown
Contributor

요약

06 §5.3member.id 비공개의 근거로 든 두 가지가 성립하지 않아 다시 썼다. 규칙은 그대로다 — 진입점을 collectionId로 두는 설계는 이미 구현돼 있고 바꾸지 않는다. 근거만 고친다.

Closes #23

근거가 부실하면 다음 결정이 그 위에 잘못 쌓인다. 실제로 한 번 그렇게 됐다 — Team-PinLog/back#63에서 "공개 조회 경로가 Record 엔티티를 공유해 memberId가 조립 함수까지 닿는다"를 §5.3 근거로 문제 삼았는데, 따져보니 §5.3이 부실해서 지적 자체가 성립하지 않았다.

성립하지 않는 근거 2건

기존 문장:

순차 값이므로 노출 시 사용자 열거가 가능해지고, 가입 순번이 신원 추론 단서가 됩니다.

1. "열거 가능" — 실행 수단이 없다. 열거가 위험하려면 그 id를 받는 엔드포인트가 있어야 하는데 없다. back dev(d0f7cbf)에서 확인했다.

$ grep -rn "@PathVariable\|@RequestParam" --include=*.java src/main/java | grep -i member
→ memberId를 받는 경로 0건 (전부 @LoginMember로 쿠키에서 식별)

$ grep -rn "memberId" src/main/java/**/dto/**
→ 공개 응답 DTO 0건

2. "가입 순번" — 순환이다. 숫자를 사람에 묶을 수단을 전제하는데, 그 수단이 1에서 없다고 한 것이다.

덤으로 자기모순 1건. 같은 절이 *"Collection id는 … 사용자 열거와는 성격이 다릅니다"*라고 단언만 하고 왜 다른지 말하지 않았다. collection.id도 똑같이 순차다. 순차 열거가 문제라면 collection id도 같은 문제여야 한다.

남는 진짜 근거

04 §1이 "동일 User의 Collection은 하나의 Shelf로 연결되고 다른 사용자가 조회할 수 있다"고 하므로 작성자별 묶어보기는 의도된 기능이다. memberId를 숨겨도 상관관계 자체는 막지 못한다. 실제 차이는 범위다.

진입점 상관관계 범위
collectionId 서버가 내주는 만큼만 묶인다
공개 응답의 memberId 클라이언트가 모든 응답을 가로질러 조인할 전역 키를 갖는다

이것을 그대로 적었다. Collection id가 다른 이유도 "결합 키가 되지 않는다"로 실제 차이를 쓴다.

함께 고친 것 3건

① 막는 층은 공개 DTO 하나임을 명시. member.id에는 §5.2의 쿼리 분리가 적용되지 않는다 — 조회 결과에 member_id가 실려 와도 공개 DTO에 필드가 없으면 충족된다. §5.2의 쿼리 분리는 context.body 조항이다. 두 절이 섞여서 back#63의 잘못된 지적이 나왔으므로, 섞지 말라는 것을 문서에 남긴다.

② 실제 방어선이 접근 통제임을 명시. id를 아는 것 자체는 그 id로 남의 것에 접근할 수 있을 때만 위험하다. 그 통제는 이미 구현·검증돼 있다(소유권 확인 후 404 은닉). "id를 숨겼으니 안전하다"로 읽히면 다음 사람이 그 방어선을 빠뜨린다.

③ 본인 id 예외 조항 삭제 — 이건 근거 수정이 아니라 드리프트 정정이다.

기존 §5.3: "예외적으로 로그인·가입 확정 응답에만 본인의 id(memberId)를 반환합니다."
08 §1.1: "내부 사용자 ID는 응답에 포함하지 않는다. 클라이언트는 자신의 memberId를 알 필요가 없다."

두 정본이 정면으로 충돌하고 있었다. 코드는 08 쪽이 맞다 — 쿠키 인증 개정(#12) 이후 로그인은 쿠키 리다이렉트이고, domain/auth에 응답 DTO 자체가 없다. §5.3의 예외 조항은 Bearer 토큰 시절 잔존물이다.

되짚은 선택지 — 규칙을 뒤집지 않는 이유

근거 2건이 죽었으니 "공개해도 된다"로 뒤집는 것도 선택지다. 뒤집어서 얻는 것은 Shelf 전용 URL 하나인데(BD-14이 "감수하는 것"으로 명시하고 포기한 항목), BD-14의 재검토 트리거가 그 경우의 답을 이미 member.public_id UUID 추가로 정해뒀다.

순차 member.id 공개 public_id UUID
Shelf URL 얻는다 똑같이 얻는다
열거·순번 잃는다 (memberId를 받는 엔드포인트가 하나 생기면 되살아남) 유지
되돌리기 불가 — Front가 붙으면 필드 제거는 계약 파괴 해당 없음

얻는 것이 UUID 안과 같은데 되돌릴 수 없는 쪽을 고를 이유가 없다. 이 판단을 §5.3에 한 줄로 남겼다.

후속 (이 PR 범위 밖)

  • back BD-14에 같은 예외 조항이 남아 있다"예외는 로그인·가입 확정 응답에서 본인의 memberId를 받는 것뿐이다." ③과 같은 잔존물이라 back 레포에서 따로 정정해야 한다.
  • back#63 §1·§2 — 이 PR이 "member.id는 §5.2 소관이 아니다"를 못박았으므로, 남는 것은 context.body 쿼리 분리를 규약대로 이름 갈지 / "엔티티에 민감 필드가 없어 조회는 공유하고 조립만 가른다"를 BD로 남길지의 판단이다.
  • §5.2의 "단일 공개 조회 서비스" 문구는 실물이 없다(조립이 2곳에 흩어져 있음). back#76·#63이 정리되면 그때 맞춘다.

확인

  • 변경은 static/06_데이터모델_및_무결성.md §5.3 한 절뿐이다.
  • 열거·가입 순번 표현이 docs 레포 전체에서 사라졌다(변경 전 2건, 모두 §5.3).
  • 규칙·API 계약·구현 변경 없음. 문서만.

🤖 Generated with Claude Code

§5.3이 `member.id` 비공개의 이유로 든 "순차 값이라 열거 가능"과
"가입 순번이 신원 추론 단서"가 둘 다 성립하지 않는다.

- 열거에는 그 id를 받는 엔드포인트가 필요한데 없다. 개인 API는 전부
  `@LoginMember`로 쿠키에서 식별하고, `memberId`를 경로변수·쿼리로
  받는 경로는 0건이다.
- 가입 순번 논거는 숫자를 사람에 묶을 수단을 전제하므로 위의 부재에
  의존한다. 순환이다.
- "Collection id는 사용자 열거와 성격이 다르다"도 근거 없는 단언이었다.
  collection id도 똑같이 순차다.

남는 실제 근거는 익명 서비스에서 클라이언트에게 전역 조인 키를 주지
않는다는 것이고, 그것을 그대로 적었다. Collection id가 다른 이유도
"결합 키가 되지 않는다"로 실제 차이를 쓴다.

함께 고친 것

- 막는 층이 공개 DTO 하나임을 명시한다. §5.2의 쿼리 분리는
  `context.body` 조항이며 `member.id`에는 적용되지 않는다. 두 절을
  섞어 공개 조회 쿼리를 따로 두는 근거로 쓰지 않는다.
- 실제 방어선이 접근 통제(소유권 확인 후 404 은닉)임을 명시한다.
  "id를 숨겼으니 안전하다"로 읽히지 않게 한다.
- 본인 id 예외 조항을 걷어낸다. 쿠키 인증 개정 이후 로그인은 쿠키
  리다이렉트이고 응답에 `memberId`를 담는 경로가 없다. 08 §1.1의
  "내부 사용자 ID는 응답에 포함하지 않는다"와 어긋나 있었다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@minyongP minyongP added the documentation Improvements or additions to documentation label Jul 29, 2026
@minyongP minyongP self-assigned this Jul 29, 2026
@cherry-go-round
cherry-go-round merged commit 95f8e4b into main Jul 29, 2026
@cherry-go-round
cherry-go-round deleted the docs/identifier-concealment-rationale branch July 29, 2026 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

06 §5.3 식별자 은닉의 근거가 부실하다 — 열거·가입순번 논거 재작성

2 participants