7.0 KiB
id, kind, slug, title, topic, topicName, project, status, version, verifiedOn, studio, public, sourceRevision, source
| id | kind | slug | title | topic | topicName | project | status | version | verifiedOn | studio | public | sourceRevision | source | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ede6b9ce-eeed-40c8-9175-9e8116029395 | REFERENCE | public-confidential-client-boundary | Public Client와 Confidential Client 구분 기준 | oauth-oidc-auth-boundary | OAuth/OIDC 인증 경계 | KeyCloak Patterns | 게시 중 | 27 | 2026-08-30 | https://hyeonworks.com/studio/documents/ede6b9ce-eeed-40c8-9175-9e8116029395/edit | https://hyeonworks.com/references/public-confidential-client-boundary | keycloak-patterns-lab@2026-08 |
|
Public Client와 Confidential Client 구분 기준
OAuth 클라이언트 종류는 인증 서버에 대해 장기 자격 증명의 기밀성을 유지하고 신뢰할 수 있는 클라이언트 인증을 수행할 수 있는지로 구분한다.
AP1의 SPA(Single Page Application)는 브라우저 실행 환경에서 이 조건을 충족하기 어려워 public client로 두었다. AP2~AP4는 서버 구성요소가 자격 증명을 보호할 수 있어 confidential client로 구성했고, 이 프로젝트에서는 client_secret_basic을 사용한다.
관계
- SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계 SPA를 public client로 등록한 이유를 실제 구성에서 확인할 수 있다.
- Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출 confidential client로 등록해도 액세스 토큰을 브라우저까지 보낼지는 따로 정한다.
- Authorization Code Flow의 Endpoint와 Credential 이동 기준 public client와 confidential client는 토큰 엔드포인트에서 사용하는 클라이언트 인증 방식이 다르다.
목적
클라이언트 종류가 정하는 범위는 자격 증명 보호와 클라이언트 인증이다. PKCE(Proof Key for Code Exchange)는 authorization code를 교환하는 쪽이 원래 verifier를 가진 주체인지 확인하는 별도 보호 장치라서 클라이언트 인증과 함께 사용할 수 있다.
AP1 SPA는 public client이고 브라우저가 code를 직접 교환한다. AP2~AP4는 서버 구성요소가 confidential client로 code를 교환하며 이 프로젝트에서는 client_secret_basic을 사용한다.
토큰 보관 위치와 API 호출 주체는 클라이언트 종류와 다른 축이다. 같은 confidential client라도 AP2는 액세스 토큰을 브라우저에 돌려주고, AP3 BFF(Backend for Frontend)와 AP4 프록시는 서버 쪽에서 다음 요청을 만든다.
규칙
1. 실행 환경에서 장기 자격 증명을 보호할 수 있는지 구분한다
브라우저 SPA나 사용자 기기에 설치되는 네이티브 앱처럼 배포물을 사용자가 직접 가진 환경에서는 애플리케이션 안에 넣은 장기 자격 증명을 비밀로 유지하기 어렵다. 이런 클라이언트는 public client로 다룬다.
서버 구성요소는 자격 증명을 사용자에게 배포하지 않고 인증 서버에 자신을 인증할 수 있다. 이 프로젝트는 공유 시크릿과 client_secret_basic을 사용한다. Confidential client의 인증 수단은 공유 시크릿 하나로 제한되지 않으며 private key나 mTLS 같은 방식도 가능하다.
2. public client에서 Authorization Code Flow에 PKCE를 함께 쓴다
PKCE는 authorization code가 중간에 탈취되더라도 다른 사람이 그 code를 토큰으로 바꾸기 어렵게 만드는 보호 장치다. 클라이언트 시크릿을 대신해 클라이언트를 인증하는 방식은 아니다.
로그인을 시작할 때 클라이언트는 임의의 code_verifier를 만들고, 이 값을 변환한 code_challenge를 authorization request에 함께 보낸다. 이후 authorization code를 토큰으로 교환할 때 원래의 code_verifier를 제출한다. Authorization Server는 처음 받은 code_challenge와 맞춰 보고 같은 요청에서 시작된 교환인지 확인한다.
변환 방식은 S256을 쓴다. plain은 code_verifier 자체가 code_challenge로 전달되기 때문에 authorization request를 관찰한 사람이 그 값을 그대로 알 수 있다. S256은 code_verifier를 SHA-256으로 변환한 값을 보내므로 authorization request에 원래의 code_verifier가 실리지 않는다.
3. confidential client에도 PKCE를 함께 쓸 수 있다
클라이언트 인증과 PKCE는 보호하는 대상이 다르기 때문에 confidential client에서 둘을 같이 쓸 수 있다.
클라이언트 인증은 토큰 엔드포인트에 요청을 보낸 쪽이 등록된 클라이언트인지 확인한다. PKCE는 authorization code를 받은 쪽이 로그인을 시작할 때 만든 code_verifier를 가지고 있는지 확인한다.
4. public client에서는 implicit flow와 direct access grant를 끈다
implicit flow는 authorization code를 거치지 않고 액세스 토큰을 브라우저의 redirect URI로 바로 전달하기 때문에, 토큰이 지나가는 구간과 노출될 수 있는 범위가 넓어진다.
direct access grant는 애플리케이션이 사용자의 아이디와 비밀번호를 직접 받아 Authorization Server에 전달하는 방식이다. 사용자가 IdP에만 주면 되는 비밀번호를 애플리케이션도 함께 다룬다.
현재 구조는 Authorization Code Flow를 쓰므로 implicit flow와 direct access grant는 비활성화했다.
5. 클라이언트 종류만으로 브라우저가 토큰을 받는지가 정해지지는 않는다
confidential client가 authorization code를 교환해도 액세스 토큰을 브라우저에 다시 전달할 수 있다. AP2 mediator는 브라우저가 Resource Server를 직접 호출하기 때문에 액세스 토큰을 응답으로 내보낸다.
AP3 BFF와 AP4 프록시는 다음 API 요청을 서버 쪽에서 만들기 때문에 브라우저에 액세스 토큰을 줄 필요가 없다. 세 구조가 모두 confidential client라는 사실만으로 이 차이는 설명되지 않는다.
적용 조건
- 새 OAuth 클라이언트를 등록할 때
- SPA와 서버 중 어디가 code를 교환할지 정할 때
- PKCE와 클라이언트 인증을 어디에 걸지 정할 때
- 기존 클라이언트의 종류가 맞는지 다시 볼 때
예외
- 같은 서비스가 브라우저용 public client와 서버용 confidential client를 따로 등록할 수 있다.
- 백엔드가 사용자 없이 자기 자격으로 부르는 흐름은 Client Credentials를 쓰는 별도 클라이언트다.
예시
- SPA용 클라이언트 : public, standard flow만 켜고 implicit flow와 direct grant는 끈다
- mediator용 클라이언트 : confidential, client_secret_basic으로 token endpoint에서 인증한다
- BFF용 클라이언트 : confidential, PKCE S256을 함께 쓴다
- 프록시용 클라이언트 : confidential, oauth2-proxy가 클라이언트 시크릿과 verifier로 code를 교환한다
- confidential client인 mediator를 써도 액세스 토큰이 브라우저 응답에 실려 나갈 수 있다