Files
DongHyeonkaandClaude Opus 5 ab59130196 chore: 이전 세션이 남긴 변경을 커밋한다
이번 파이프라인 작업과 무관하게 작업 트리에 남아 있던 것을 그대로 올린다.
사용자가 「전부 커밋」으로 정했고, 이번 작업과 섞이지 않게 커밋만 나눴다.

대부분은 clean-architecture-backend-template 의 그림 정본 재배치다 —
final/assets/diagrams/<이름>/ 에 있던 것이 CLAUDE.md 가 적은 배치인
final/assets/<이름>/ 로 옮겨졌고 .techviz/<이름>/ 이 함께 들어왔다.
삽입 줄의 대부분(3.15M)이 그 .techviz context.json 이다.

그 밖에 ca-tmpl·document-haness 의 정리, .claude/agents/ 열한 개,
writing-practitioner-guides 스킬, .playwright-mcp 세션 산출물,
scripts/check-ssot-facts.py 와 그 시험이 들어 있다.

이 커밋의 내용은 내가 만든 것이 아니라 이전 세션이 남긴 것이고 검증하지 않았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 11:02:02 +09:00

8.8 KiB

id, kind, slug, title, topic, topicName, project, status, version, questionStatus, studio, public, sourceRevision, source
id kind slug title topic topicName project status version questionStatus studio public sourceRevision source
7ff40767-a00b-4db2-98f6-0cdfce8c8936 QUESTION edge-authorization-scope Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가 oauth-oidc-auth-boundary OAuth/OIDC 인증 경계 KeyCloak Patterns 게시 중 36 OPEN https://hyeonworks.com/studio/documents/7ff40767-a00b-4db2-98f6-0cdfce8c8936/edit https://hyeonworks.com/questions/edge-authorization-scope keycloak-patterns-lab@2026-08
final/document.md#검토한-선택지와-막힌-지점-ap4
final/document.md#얻은-것-잃은-것-적용하지-않을-때-ap4

Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가

지금 엣지는 인증된 사용자의 useremail만 헤더로 넘기고, 업스트림 애플리케이션은 역할(role)을 보고 인가를 판단하지 않는다.

관계

  • Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유 엣지가 user와 email만 넘긴다는 사실을 여기서 가져왔다.
  • Forward-Auth에서 Identity Header를 신뢰하기 위한 조건 넘길 헤더를 허용 목록(allowlist)으로 두는 기준과 검증 조건이 이 기록에 있다.
  • BFF 인증 구조 설계 기준 네 번째 선택지로 되돌아갈 때 따를 기준이 이 기록이다.

사실

  • 지금 엣지 응답은 user와 email만 넘긴다. 역할과 그룹, 테넌트, 인증 방식, 토큰 만료는 넘기지 않는다.
  • 업스트림의 신원 응답 엔드포인트는 역할을 확인하지 않고 누가 왔는지만 돌려준다.
  • 내부 토큰(internal token) 검증은 컨트롤러 한 곳에서만 하고, Spring Security 설정은 그 경로를 permitAll로 열어 둔다. 검증이 그 컨트롤러 안에만 있으니 같은 내부 경로 아래에 엔드포인트를 새로 추가해도 검증이 따라붙지 않는다. 필터나 인터셉터, Spring Security의 인증 처리 단계처럼 모든 요청이 지나는 공통 경계로 이 검사를 옮겨야 한다.
  • Nginx는 클라이언트가 보낸 같은 이름의 헤더를 합치지 않고 덮어쓴다. 헤더를 늘리면 늘어난 헤더도 똑같이 덮어쓰게 해야 한다.
  • 업스트림은 JWT를 입력으로 받지 않아서 헤더로 넘어온 값이 맞는지 확인할 방법이 없다.

가정

  • 헤더 종류가 늘어나면 그만큼 정해야 할 계약도 늘어난다.
  • 역할이 바뀌는 시각과 요청이 들어오는 시각이 달라서, 그 사이에 들어온 요청은 바뀌기 전 값을 볼 수도 있다.

미지수

  • 역할 기반 인가가 필요한 요구가 들어왔을 때 어떻게 처리할지. 엣지가 사용자의 역할까지 확인해 헤더로 넘길지, 애플리케이션이 역할과 권한을 직접 조회해 인가를 판단할지.
  • 역할이 여러 개일 때 어떤 구분자와 이스케이프 규칙으로 보낼지. 값 안에 그 구분자가 들어오면 어떻게 되는지.
  • 헤더 크기 상한을 넘으면 어떻게 되는지. 프록시가 잘라 내는지, 요청 자체가 거부되는지. 현재 fixture는 /api/edge/를 모두 /edge/me로 바꿔서 큰 헤더가 실린 요청을 통과시켜 본 적이 없다.
  • 역할이 바뀌었을 때 프록시 세션과 다운스트림 인가에 언제 반영되는지. 권한을 바꾸고 몇 분 뒤에 반영되는지.
  • 업스트림이 헤더가 있는지만 볼지, 값과 내부 서비스 식별값(service identity)까지 함께 볼지.

제약

  • 넘길 헤더는 허용 목록으로 정해야 하고, 클라이언트가 보낸 같은 이름의 헤더는 언제나 덮어써야 한다.
  • 내부 토큰 검사가 컨트롤러 한 곳에만 있다. 헤더를 늘리기 전에 이 검사를 공통 경계로 옮겨야 한다.

선택지

1. 인증만 엣지에 둔다

엣지가 넘기는 헤더를 user와 email 정도로 묶어 두면 엣지와 업스트림 사이의 계약을 작게 유지할 수 있다. 역할이나 권한을 헤더에 계속 더하지 않으니 헤더가 커지는 문제도 줄일 수 있다.

대신 인가는 업스트림 애플리케이션이 직접 판단한다. 넘겨받은 사용자 식별 정보로 자기 저장소에서 역할이나 권한을 조회하고, 그 요청을 허용할지 정해야 한다.

인가를 서비스가 직접 판단하다 보니 권한 조회와 인가 코드를 서비스마다 따로 만들어야 한다.

2. 역할 전달까지 엣지에 둔다

엣지가 공통 역할을 확인해 업스트림에 넘기면, 서비스마다 사용자 권한을 따로 조회하는 일을 줄일 수 있다.

대신 역할을 헤더로 넘기는 계약을 먼저 정해야 한다. 한 사용자가 역할을 여럿 가질 때 어떤 형식으로 직렬화할지, 헤더에 허용할 최대 크기를 얼마로 둘지, 역할을 바꾼 뒤 언제부터 새 값이 요청에 실리는지를 적어 두어야 한다.

업스트림은 넘겨받은 역할이 원래 인증 시스템의 값과 같은지 확인할 수 있어야 한다. 확인하지 못하면 엣지가 넘긴 값을 그대로 믿게 되는데, 엣지가 역할을 잘못 계산하거나 오래된 값을 넘기면 업스트림의 인가 판단도 그대로 틀어질 수 있다.

이 선택지를 고르면 엣지가 역할을 만드는 과정과 헤더가 지나는 경로까지 신뢰 경계 안으로 들어온다. 역할을 언제 갱신하고 전달 오류를 어떻게 잡을지도 같이 설계해야 한다.

3. 테넌트와 인가 판단까지 엣지에 둔다

테넌트는 어느 조직의 데이터까지 볼 수 있는지를 정하는 값이다. 그래서 잘못된 테넌트 값 하나가 넘어가면 다른 조직의 데이터에 접근하는 문제로 바로 이어질 수 있다.

테넌트를 엣지 헤더로 넘기려면 업스트림이 그 사용자가 실제로 그 테넌트에 속하는지 다시 확인할 방법이 있어야 한다. 지금 구성에는 다시 확인할 수단이 없어서 테넌트까지 엣지가 맡는 구조로 넓히기에는 위험이 크다.

테넌트나 역할로 인가를 판단하는 일까지 엣지로 옮기면 엣지가 애플리케이션의 도메인 규칙을 알아야 한다. 어떤 사용자가 어느 조직의 어떤 기능을 쓸 수 있는지 같은 정책이 바뀔 때마다 엣지 코드도 함께 고쳐 배포해야 한다.

그래서 엣지는 인증된 사용자 정보를 넘기는 쪽에 가깝게 두고, 테넌트 소속 여부나 도메인에 묶인 인가 규칙은 업스트림 애플리케이션이 검증하는 구조를 먼저 검토한다.

4. 헤더 계약 대신 BFF가 인가와 API 호출을 맡는다

역할이나 테넌트 같은 값을 엣지 헤더에 계속 더하는 대신, BFF(Backend For Frontend)가 필요한 정보를 직접 조회해 인가를 판단하고 API까지 부르는 구조도 고를 수 있다. BFF는 화면에 필요한 API를 브라우저 대신 불러 조합하는 서버다.

이러면 엣지는 애플리케이션의 역할과 테넌트, 권한 정책을 알 필요가 없다. BFF가 사용자와 권한을 조회해 인가를 판단하고, 화면에 필요한 여러 Resource Server의 API를 불러 결과를 합칠 수 있다.

대신 BFF를 넣으면 서버가 다시 인증 상태를 들고 있어야 한다. 브라우저와 BFF 사이의 애플리케이션 세션을 보호해야 한다. 쿠키 기반 세션을 쓴다면 쿠키가 요청마다 자동으로 붙으니, 값을 바꾸는 요청에는 사용자가 의도한 것인지 확인하는 CSRF(Cross-Site Request Forgery) 검증도 있어야 한다. BFF를 여러 대로 늘려 인증 상태를 유지하려면 세션과 authorized client를 어떻게 공유할지 정하고, 공유 저장소의 장애와 만료 처리까지 운영해야 한다.

이 구조를 골랐다가 다시 엣지 쪽으로 되돌린다면 BFF가 맡던 사용자별 인가를 업스트림이나 별도 정책 서비스로 다시 옮겨야 한다.

다음 검증

업스트림이 실제로 요구하는 사용자 속성(claim)부터 적는다.

  1. 넘기려는 속성이 계속 늘어나는가.
  2. 역할이나 테넌트를 바꾸면 곧바로 반영돼야 하는가.
  3. 정책이 애플리케이션 도메인을 알아야 하는가.
  4. 헤더 값이 인가 판단의 근거가 되는가.
  5. 서비스마다 정책 차이가 커지는가.

2번부터 5번 가운데 하나라도 그렇다면 헤더를 늘리는 대신 BFF 구조를 검토한다.

역할을 헤더에 담는 구성을 먼저 만들고, 값을 여러 개 넣고 크기 상한까지 올려 무엇이 먼저 깨지는지 확인한다. 역할을 바꾼 뒤 몇 번째 요청부터 새 값이 실리는지도 센다.

어느 쪽으로 옮길지는 새로 일을 맡는 쪽이 상태와 검증을 감당할 수 있는지를 보고 정한다.