Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/self-disclosure-grading/case/case-a-startup-validator-that-requires-a-key-nothing-signs-with.md
T
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.

Follows the import procedure in README.md.

  source/     the originating repository verbatim — 78 documents, 28 SVGs,
              8 manifests, plus .source-revision recording the commit
  final/      the SSOT
    document.md   729 lines written from the 29 experiment documents, not
                  concatenated: what was predicted, what was measured, and
                  where the measurement itself was wrong
    evidence/raw    125 outputs, flattened to <experiment>__<file> because
                    the originals collided (01-baseline.txt appeared three
                    times) and the audit only globs the top level
    evidence/meta   one per raw file; command and exitCode are null and the
                    README says why rather than inventing them
    evidence/browser  22 captures
    assets/       three diagrams through techviz
    .techviz/     their VizSpecs

A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.

Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.

verify-pipeline.py passes. audit-records.py reports no issues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:51:59 +09:00

9.0 KiB

kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, assets, evidence, source
kind slug title topic project status sourceRevision rootTreeNode evidenceCapturedOn assets evidence source
CASE a-startup-validator-that-requires-a-key-nothing-signs-with 시작 검증기가 커서 서명 키를 요구하는데 그 키로 서명하는 코드가 없다 self-disclosure-grading clean-architecture-backend-template 게시 전 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 case:a-startup-validator-that-requires-a-key-nothing-signs-with 2026-09-02
key file
a-startup-validator-that-requires-a-key-nothing-signs-with ../../../final/evidence/rendered/a-startup-validator-that-requires-a-key-nothing-signs-with.svg
../../../final/evidence/raw/a-startup-validator-that-requires-a-key-nothing-signs-with.txt
분석 문서는 inbound-graphql 어댑터 편 §24.1 이다. 서명하는 코드가 없다는 사실은 같은 문서 §23.2, 액추에이터 엔드포인트가 등록되지 않는다는 것은 §8.1, 매니페스트의 네 번째 신호는 §29.2 다. websocket 어댑터 편 §18.3 이 같은 형태의 재개 토큰 서명을 대조한다.

시작 검증기가 커서 서명 키를 요구하는데 그 키로 서명하는 코드가 없다

시작 검증기가 프로덕션에서 커서 서명 키를 요구하고, 그 검증기는 실제로 돈다. 그 키로 서명하는 코드는 없고, 서명될 커서도 아직 없다.

관계

  • 등급표 13행 중 일곱을 스스로 강등하고 한 행만 관측과 어긋났다 등급표가 이 능력을 모형 단계로 적고 있다.
  • 하위 시스템 전체가 미배선인데 그것을 켜는 플래그는 시작 검사를 수행한다 같은 형태가 mongo 어댑터에서 나타난 사례다.
  • 커서에 서명하는 이유는 기밀성이 아니라 무결성이다 이 커서 서명이 지키려는 성질이다.

문제

시작 검증기가 프로덕션 배포에서 커서 서명 키를 요구한다. 없으면 기동을 거절하고 이유를 적는다 — 서명되지 않은 커서는 클라이언트가 편집할 수 있다는 것이다.

이 검증기는 자동설정이 실제로 부른다.

결론

그 키를 소비하는 프로덕션 코드는 둘이다. 거절하는 검증기가 하나, 보고하는 액추에이터가 하나다. 뒤쪽을 만드는 코드는 아직 없다.

그 키로 서명하는 코드는 없다. 커서 코덱 쪽도 같다. 구현이 하나인데 만드는 프로덕션 코드가 없다.

서명될 커서도 아직 없다. 커넥션 조립기를 만드는 프로덕션 코드가 0 이고, 배포되는 스키마는 상태 확인 필드 하나다.

그런데 릴리스 게이트가 읽는 매니페스트는 이 능력을 안정 등급 승인 목록에 넣어 두었다.

즉 결함은 능력이 미완이라는 것이 아니다. 미완인 능력에 대해 플랫폼이 요구하고 승인해 주는 신호를 이미 켜 두었다는 것이다.

닫는 것은 배선 결정이 아니라 설계 결정이다. 키링 팩토리는 키 재료를 인자로 받는데, 설정은 키 자체가 설정에 나타나지 않는다고 일부러 정해 두었다.

그때까지의 최소 조치는 요구를 남기고 문구를 사실에 맞추는 것이다. 테스트의 네 번째 케이스가 요구를 남기라고 못 박는다.

검증 환경

OpenJDK : 21.0.12 확인 방식 : 설정 소비 지점과 생성 지점의 계수, 배포 스키마 확인, 컨텍스트 테스트 확인 소스 수정 : x

재현 조건

  1. 시작 검증기가 프로덕션을 거절하는 조건과 문구를 읽고, 자동설정이 그것을 부르는 지점을 확인한다.
  2. 그 키 설정을 소비하는 프로덕션 코드를 세고, 그중 만들어지지 않는 것이 있는지 확인한다.
  3. 커서 코덱 구현체와 그것을 만드는 프로덕션 코드를 센다.
  4. 커넥션 조립기를 만드는 코드를 세고, 배포되는 스키마를 읽는다.
  5. 릴리스 게이트 매니페스트의 승인 목록을 확인한다.
  6. 부재를 고정하는 테스트와 요구를 남기라고 적은 케이스를 읽는다.

본문

프로덕션 배포에 커서 서명 키가 없으면 시작 검증기가 기동을 거절한다. 이유도 함께 적는다 — 서명되지 않은 커서는 클라이언트가 편집할 수 있다.

이 검증기는 발행만 되고 마는 종류가 아니다. 자동설정이 실제로 부른다.

프로덕션이 요구하고, 운영자가 주고, 아무것도 서명하지 않는다

:::evidence key="a-startup-validator-that-requires-a-key-nothing-signs-with" alt="코드베이스에서 시작 검증기가 커서 서명 키 없이 프로덕션을 거절하는 문구와 그 검증기가 자동설정에서 실제로 불리는 지점, 그 키 설정을 소비하는 두 곳과 그중 액추에이터 엔드포인트를 만드는 코드 수, 커서 코덱 구현체 수와 그것을 만드는 코드 수, 커넥션 조립기를 만드는 코드 수와 배포되는 스키마 전체, 릴리스 게이트가 읽는 매니페스트의 승인 목록, 부재를 고정하는 테스트의 단언과 요구를 남기라고 적은 네 번째 케이스, 그리고 등급표가 이 능력에 매긴 등급을 뽑은 출력. 배포되는 스키마에 커서가 없고 서명 코덱을 만드는 코드도 0 이라는 것이 그 출력에 보인다." caption="검증기의 거절 문구와 실제 호출 · 소비 두 곳과 미조립 엔드포인트 · 코덱 생성 0 · 스키마는 _health 하나 · 매니페스트의 승인 · 요구를 남기라는 테스트" zoom="true" :::

그 키 설정을 읽는 프로덕션 코드는 둘이다. 없으면 거절하는 검증기와, 설정되었다고 보고하는 액추에이터 엔드포인트다.

뒤쪽은 아직 만들어지지 않는다. 그 엔드포인트를 생성하는 프로덕션 코드가 0 이고, 그 클래스의 javadoc 이 등록을 컴포지션 루트의 몫으로 남겨 두었다.

서명하는 코드는 없다. 커서 코덱 구현은 하나뿐이고, 그것과 키링을 만드는 프로덕션 코드가 0 이다.

서명될 커서 자체가 아직 없다

커넥션 조립기를 만드는 프로덕션 코드가 0 이다.

배포되는 스키마는 상태 확인 필드 하나다. 그 파일의 주석이 왜 그런지 적는다 — 이 모듈은 기능 없이도 독립으로 부팅해야 하고, Spring for GraphQL 은 빈 스키마로는 시작하지 않으며, 스켈레톤은 기능 타입 이름을 절대 대면 안 된다는 것이다.

커서는 발급되지도 소비되지도 않는다. 검증기 문구가 막는다고 말한 상태는 지금 존재하지 않는다.

그런데 승인 신호는 이미 켜져 있다

릴리스 게이트가 읽는 능력 매니페스트가 있다. 안정 스타터에서 켜도 되는 능력의 목록이다.

서명 커서 커넥션이 그 목록에 들어 있다. 켜도 된다고 판정되고, 켜는 코드는 없다.

결함은 미완이 아니다

컨텍스트 테스트가 그 부재를 고정한다. 설정에 키가 담기는 것을 먼저 확인하고, 그다음 코덱 빈도 키링 빈도 없다는 것을 단언한다.

단언 문구가 판정을 적는다 — 아무것도 지키지 않는 키가 없다는 이유로 프로덕션이 기동을 거절하는 것은, 그 키를 아예 요구하지 않는 것보다 나쁘다.

같은 테스트가 두 번째 능력도 같은 방식으로 고정한다. 변이 멱등성 인터셉터가 어떤 설정에서도 참조되지 않는다. 등급표가 둘 다 모형 단계로 적어 두었다.

미완인 능력을 미완이라고 적는 것과, 미완인 능력에 대해 요구하고 승인해 주는 신호를 켜 두는 것은 다르다.

websocket 어댑터의 같은 형태는 결함이 아니다

websocket 어댑터에 재개 토큰 코덱과 키링이 있다. 이 둘도 조립되지 않는다.

차이는 하나다. websocket 어댑터에는 키를 요구하는 시작 검증기가 없다. 그래서 잘못된 확인 신호도 없다.

미배선은 양쪽이 같고 결함은 한쪽에만 있다. 결함을 만드는 것이 미완이 아니라 검증기라는 것을 그 대조가 보여 준다.

닫는 것은 배선이 아니라 설계다

키링 팩토리는 키 재료 자체를 인자로 받는다. 그런데 설정은 키 자체가 설정에 절대 나타나지 않는다고 일부러 정해 두었다.

키 재료가 어디서 오는지를 먼저 정해야 무엇을 어디에 붙일지가 정해진다.

그동안 할 수 있는 일이 없는 것은 아니다. 요구는 남기고 문구를 사실에 맞추면 된다.

테스트의 네 번째 케이스가 그것을 못 박는다. 요구는 지우지 말고 남기라는 것, 요구 자체는 옳고 빠진 절반은 구현이라는 것, 커서 서명이 요청 경로에 닿으면 앞의 두 케이스는 뒤집히고 이 케이스만 그대로 남는다는 것이다.

확인하지 못한 것

키 없이 기동해 거절을 재현해 보지는 않았다. 참조 계수를 이름 기반 정적 검색으로 냈기 때문에 리플렉션 조립 경로까지는 배제하지 못했다.