Table of contents
Open Table of contents
1. 왜 인증을 먼저 분리했나
요즘은 Claude Code 같은 agentic coding 도구 덕분에 개인 프로젝트에서도 작은 서비스를 훨씬 빨리 만들 수 있다. 기능 하나를 만들어 붙여보고, 아니면 접고, 다시 다른 걸 만들어보는 일이 예전보다 훨씬 가벼워졌다.
그런데 이렇게 서비스를 몇 개 만들기 시작하면, 각 서비스의 기능보다 먼저 반복되는 일이 눈에 들어온다. 내 경우에는 그게 인증이었다.
나는 범용 서비스보다 내가 실제로 쓸 개인화된 서비스들을 만들고 싶었다. 내 맥락에 맞게 동작하고, 내 데이터를 바탕으로 움직이는 작은 서비스들 말이다. 그런데 이런 서비스는 결국 “누가 쓰는가”를 먼저 알아야 한다. 서비스가 하나뿐이면 구글 로그인을 직접 붙여도 충분하다. 하지만 서비스가 여러 개가 되고, 브라우저뿐 아니라 CLI나 MCP처럼 접속 방식까지 달라지기 시작하면 이야기가 달라진다.
물론 혼자 쓰는 서비스라면 비밀번호나 API 키처럼 더 단순한 방식으로 시작할 수도 있었다. 하지만 그 방법은 “들어올 수 있느냐”는 해결해도, “여러 서비스가 이 사람을 같은 사용자로 보느냐”는 해결하지 못한다. 엔지니어로서 내가 만들고 싶었던 것은 임시로 잠그는 장치가 아니라, 이후에 서비스가 늘어나도 흔들리지 않는 사용자 경계였다.
여기서 내가 분리하려는 것은 로그인 버튼이 아니라, 외부 계정 확인과 내부 사용자 식별, 토큰 발급을 맡는 인증 경계다. 그래서 인증을 각 서비스 안에 두기보다, 서비스 바깥의 공통 역할로 따로 빼서 보는 쪽이 맞지 않을까 생각하게 됐다. 아직 이 방향이 정답이라고 말할 수는 없다. 이 글은 왜 내가 지금 이 경계를 먼저 세우려 하는지를 정리한 글이다.
2. 앱별 직접 연동의 한계
앱마다 직접 구글 로그인에 붙이면 어떻게 되는지 정리하면 이렇다.
| 항목 | 앱별 직접 연동 | 인증 서버 경유 |
|---|---|---|
| 외부 IdP 연동 | 앱마다 필요 | 인증 서버 1곳 |
| 사용자 기준 | 앱별로 흩어짐 | 내부 user_id로 통합 |
| 브라우저 외 접속 | 별도 구현 반복 | 공통 흐름으로 수렴 |
| 새 서비스 추가 | 인증도 같이 붙여야 함 | 토큰 검증만 추가 |
| 복잡성 위치 | 앱마다 분산 | 인증 서버로 집중 |
핵심은 계정 연동이 아니라 사용자 기준의 일관성이다. 앱이 늘어날수록 사용자 매핑 기준이 흩어지고, 브라우저 외 접속 방식은 매번 별도 구현이 된다. 결국 “같은 사람”이라는 기준이 앱 경계마다 흐려진다.
3. 왜 인증을 서비스 바깥으로 빼는가
여기서 말하는 인증 서버는 거대한 계정 플랫폼이 아니다. 여러 서비스가 같이 쓸 최소한의 인증 서버다. 인증 서버가 외부 IdP에게 사용자를 확인받고, 그 결과를 내부 user_id에 연결한 뒤, 다른 서비스들이 믿고 쓸 수 있는 토큰을 발급하는 구조다.
브라우저 / CLI / MCP
↓
인증 서버
↓
공통 사용자 식별자
↓
앱 서버 A / 앱 서버 B / 앱 서버 C
중요한 건 어떤 프로토콜을 쓰느냐보다, 인증을 어디서 맡느냐다.
- 앱은 더 이상 외부 로그인 공급자와 직접 붙지 않는다
- 인증 서버가 외부 계정을 내부
user_id에 연결한다 - 앱은 토큰 검증과 자기 기능에 집중한다
- 브라우저, CLI, MCP처럼 방식이 달라도 결국 같은 사용자 기준으로 묶인다
즉, 인증은 서비스 안의 한 기능이 아니라 서비스들 바깥에서 공통으로 처리하는 역할이 된다. 이 글에서 다루는 건 인증과 사용자 식별의 공통화이지, 서비스별 권한 판단의 중앙화는 아니다.
참고: 인증 서버를 거치는 흐름
인증 서버가 중간에 들어가면, 브라우저는 인증 서버에게 토큰을 받고, 인증 서버는 다시 구글에게 사용자를 확인받는다. 얼핏 보면 단계가 하나 더 늘어난 것처럼 보이지만, 실제로는 인증 책임이 앱에서 인증 서버로 옮겨간 구조다.
같은 사용자가 나중에 다른 앱에 들어오면, 인증 서버의 세션을 이용해 다시 구글 로그인까지 가지 않고 바로 토큰을 받을 수 있다. 여기서 SSO가 생긴다.
4. 왜 이 구조가 앞으로 더 맞다고 보는가
인증 서버를 먼저 두는 이유는 로그인 한 번을 예쁘게 만들기 위해서가 아니다. 앞으로 서비스를 더 만들 때, 매번 같은 문제를 처음부터 다시 풀지 않기 위해서다.
반복이 줄어든다. 새 서비스를 만들 때마다 로그인 연동, 세션 처리, 사용자 기준을 다시 잡지 않아도 된다. Agentic coding 도구를 쓸수록 기능 하나를 새로 만드는 부담은 점점 줄어든다. 그럴수록 오히려 같은 인증 문제를 여러 군데에서 반복하는 일이 더 거슬린다.
같은 사용자를 같은 기준으로 다룰 수 있다. 인증 서버가 외부 계정을 내부 user_id에 연결해두면, 모든 서비스가 같은 사용자를 같은 기준으로 볼 수 있다. 브라우저, CLI, MCP처럼 접속 방식이 달라도 결국 하나의 사용자 체계로 이어진다.
새 서비스를 붙이기 쉬워진다. 각 서비스는 자기 기능만 신경 쓰고, “이 사람이 누구인가”라는 공통 문제는 인증 서버에 맡기면 된다. 한 번 로그인한 사용자는 다른 앱에서도 같은 인증 체계를 그대로 쓸 수 있다. 새 서비스는 이 기준 위에 올리면 된다.
역할이 분리돼 있으면 나중에 AI가 수정이나 테스트를 도울 때도 범위를 좁게 잡기 쉬울 거라 보지만, 이건 아직 가설이다.
지금 당장 사용자가 크게 체감하는 변화는 로그인 경험 정도일 수 있다. 다만 앞으로 작은 서비스들이 계속 만들어졌다가 일부는 사라지고, 일부는 살아남는 흐름이 반복된다면 사용자 기준이 하나로 이어져 있다는 사실 자체가 점점 더 중요해질 수 있다. 여러 서비스가 같은 user_id를 공유하고 있다면, 서로 다른 서비스들이 같은 사용자를 기준으로 데이터와 맥락을 연결할 수 있게 된다. 따로 만들어진 서비스들이 사용자 축 위에서 만나면서, 개별 서비스만으로는 만들 수 없던 경험이 생길 가능성이 열리는 것이다.
5. 감수해야 할 것
물론 이 구조가 공짜는 아니다.
인증 서버가 멈추면 로그인 전체가 영향을 받는다. 인증을 한곳에 모은 만큼, 그 한곳이 장애 지점이 될 수 있다.
서비스가 하나뿐이라면 솔직히 과한 구조일 수도 있다. 나중에 반복할 일을 줄이기 위해, 지금 복잡함을 먼저 받아들이는 선택에 가깝다. 세션, 토큰, 리다이렉트, 키 회전 같은 문제를 인증 서버가 떠안게 되고, 각 서비스가 단순해지는 대신 그 복잡함이 중앙으로 모인다.
가장 조심해야 할 건 인증 서버가 자꾸 다른 역할까지 먹기 시작하는 것이다. 만들다 보면 프로필도 넣고 싶고, 조직도 넣고 싶고, 권한도 중앙에서 관리하고 싶어진다. 하지만 그 선을 넘기 시작하면, 공통 기반이 아니라 모든 게 얽히는 중심 서버가 된다.
6. 인증 서버의 역할은 어디까지인가
이 선을 분명히 하지 않으면 인증 서버는 끝없이 커진다.
인증 서버가 해야 할 일은 외부 계정을 내부 user_id에 연결하고, 다른 서비스가 믿고 쓸 수 있는 토큰을 발급하고, 여러 접속 방식을 하나의 사용자 기준으로 묶는 것까지다. 여기까지면 충분하다.
서비스별 권한, 도메인 모델, 프로필 확장 같은 일은 각 서비스가 자기 안에서 관리해야 한다. 인증 서버는 인증을 맡는 서버이자 토큰 발급기이지, 모든 계정 문제를 다 떠안는 중앙 시스템이 아니다.
7. 정리
처음부터 하나의 서비스로 모든 걸 설계할 수도 있었겠지만, 개인적으로는 그렇게 시작하는 방식이 오히려 시도를 어렵게 만든다고 생각한다. 작은 서비스들을 따로 만들고, 붙여보고, 필요 없으면 버리는 흐름 속에서 공통으로 남는 기준이 더 또렷하게 드러난다. 인증을 먼저 분리하게 된 것도 그 과정에서였다.
내가 하려는 건, agentic coding으로 작은 서비스를 빠르게 만들고 붙이고 다시 바꿔가더라도, 사용자 기준만큼은 계속 이어지게 해주는 최소한의 공통 바탕을 먼저 만드는 일에 가깝다. 이렇게 쌓인 서비스들이 나중에 사용자 기준 위에서 다시 연결되기 시작하면, 처음에는 보이지 않던 새로운 가치가 드러날 가능성도 있다고 본다.
이 판단이 정말 맞는지는 결국 해봐야 안다. 다행히 지금은 예전보다 서비스를 만드는 비용이 많이 낮아졌다. 그래서 지금은 길게 확신하기보다, 먼저 이 경계를 세워보고 그 위에 어떤 것들이 실제로 이어질 수 있는지 확인해보려 한다.
레퍼런스
- authgate — 이 글에서 다루는 인증 서버의 실제 구현체