최근 개인 프로젝트의 인증 구조를 NextAuth 중심의 모놀리식 형태에서 별도의 중앙 인증 서버로 분리했다. 처음엔 단순히 로그인 API를 떼어내는 작업이라고 생각했지만, 실제로는 사용자 식별자, 권한 경계, 배포 구조, 운영 환경까지 전부 다시 점검하는 대규모 공사였다.
이 과정에서 AI(Codex)를 단순한 코드 작성 도구로만 쓰지 않고, 깐깐한 코드 리뷰어처럼 활용해 보았다. 결론부터 말하자면, AI 코드 리뷰의 진짜 가치는 코드를 예쁘게 다듬는 것이 아니라 개발자가 놓치기 쉬운 위험한 경계 위반을 날카롭게 짚어내는 데 있었다.
리뷰의 질은 ‘기준’이 결정한다
AI에게 무턱대고 코드를 던져주면 “이 변수명은 어색하네요” 수준의 뻔한 잔소리만 돌아온다. AI 코드 리뷰가 진짜 유용해지려면 먼저 명확한 채점 기준표가 필요했다.
이번 프로젝트에서는 다음 원칙을 문서화하여 AI에게 주입했다.
- 인증 서버(
workspace_auth)만이 유일한 인증 원본이다. - 각 서비스는
authUserId를 장기 식별자로 사용해야 한다. - 클라이언트가 임의로 보낸
userId를 절대 신뢰해서는 안 된다.
이러한 명확한 기준이 생기자, AI는 단순한 스타일 지적을 넘어 시스템 설계 위반을 선명하게 짚어내기 시작했다.

코드보다 ‘경계’가 먼저다
인증 서버를 분리할 때 가장 골치 아팠던 건 JWT 발급 로직이 아니었다. 진짜 난관은 ‘어느 서비스가 무엇을 책임지는가’를 다시 정의하는 일이었다.
workspace_auth: 계정, 비밀번호 해시, OAuth 계정 연결, Refresh Token 관리timetable_db: 시간표, 별명 등 앱 도메인 데이터 관리
문제는 기존 앱이 이메일을 기준으로 사용자를 연결하고 있었고, 일부 API는 클라이언트가 넘긴 userId를 맹신하고 있었다는 점이다. 코드를 고치기 전에 데이터와 권한의 경계부터 확실히 정리해야만 했다.
AI가 찾아낸 3가지 치명적 결함
AI는 내가 작성한 코드에서 생각지도 못한 구멍들을 귀신같이 찾아냈다.
- 클라이언트
userId맹신 (권한 우회 취약점)
가장 먼저 지적받은 건 시간표 API가 요청 바디나 쿼리스트링으로 들어온userId를 그대로 믿고 처리한다는 점이었다. 이는 단순한 버그가 아니라, 악의적인 사용자가 다른 사람의 시간표를 마음대로 읽고 쓸 수 있는 심각한 권한 우회 취약점이다. 리팩토링의 늪에 빠져 흐름을 놓치기 쉬웠는데, AI가 “설계 기준 위반”이라며 정확히 브레이크를 걸어주었다. 결국 서버가 항상 인증된 토큰을 기준으로 로컬 사용자를 식별하도록 수정했다. authUserId전환 중 발생한 동시성 문제 (경쟁 상태)
이메일 중심 연결을authUserId중심 구조로 바꾸면서 기존의upsert로직을 풀어썼다. 언뜻 보기엔 문제가 없었지만, AI는 이 로직이 동시에 여러 요청을 받을 경우 치명적일 수 있다고 경고했다. 두 요청이 동시에 “아직 사용자가 없네?”라고 판단하고 각각create를 시도하다가 고유 키(unique) 충돌이나 500 에러를 뿜어낼 수 있는 구조였다. AI의 지적 덕분에 해당 부분을 트랜잭션과 재시도 로직으로 안전하게 감쌀 수 있었다.- 장애를 인증 실패로 퉁치는 안일한 에러 처리
또 하나 뼈아팠던 지적은/auth/verify호출이 실패했을 때 무조건 “잘못된 토큰”으로 처리하던 로직이었다. 만약 인증 서버가 죽었거나 일시적인 네트워크 장애로 500 에러가 발생해도, 사용자 앱은 “내 토큰이 만료됐나?”라고 오해하고 불필요하게 로그아웃을 시도하게 된다. 이는 운영 단계에서 디버깅을 지옥으로 만드는 원인이 된다. 리뷰를 반영하여INVALID_ACCESS_TOKEN과AUTH_SERVER_UNAVAILABLE을 명확히 분리해, 사용자의 인증 문제와 서버 장애를 구분하도록 개선했다.
AI 코드 리뷰 사용 경험
이번 경험을 통해 느낀 AI 코드 리뷰의 장단점은 명확했다.
- 강점 (설계와 보안의 수호자): 문법이나 포맷 교정보다는 설계 문서와 금지 규칙을 기반으로 보안 경계와 회귀 위험을 빠르게 찾는 데 탁월했다. “이 책임이 정말 여기 있어도 되는가?”, “이 에러 처리가 운영에 어떤 오해를 만들 수 있는가?” 같은 본질적인 질문을 던져주는 훌륭한 러닝 메이트였다.
- 한계 (운영 환경의 맹점): 반대로, 코드를 벗어난 운영 환경의 문제는 전혀 예측하지 못했다. CORS 설정, 인증서 발급, Docker 내부망 문제(
host.docker.internal), GitHub Actions 시크릿 포맷(따옴표 문제) 같은 인프라 이슈는 결국 직접 브라우저 에러 로그를 뒤지며 몸으로 때워야 했다. AI는 강력한 보조 수단일 뿐, 운영 진단까지 대신해주진 않는다.