본문으로 건너뛰기

© 2026 Molayo

GeekNews헤드라인2026. 06. 20. 00:24

CLI 인증, 올바른 방식

요약

SSH, 컨테이너, WSL 등 원격 개발 환경에서 발생하는 CLI OAuth 인증 문제를 해결하기 위한 RFC 8628(Device Authorization Grant) 표준의 필요성을 다룹니다. 기존 localhost 리다이렉트 방식의 한계를 분석하고, 보안과 사용자 경험을 고려한 올바른 인증 구현 방식을 제안합니다.

핵심 포인트

  • 로컬 브라우저 의존성을 없애는 RFC 8628 Device Flow 권장
  • SSH 및 원격 환경에서의 인증 흐름 단절 문제 해결
  • Refresh Token은 OS Keychain에 저장하여 보안 강화
  • 피싱 공격 방지를 위한 기기 코드 교체 및 세션 관리 필요성

많은 CLI는 노트북의 로컬 브라우저에서는 빠르게 끝나는 localhost OAuth 리다이렉트를 기본값으로 쓰지만, SSH·컨테이너·WSL 같은 개발 환경에서는 같은 가정이 깨져 로그인 흐름이 멈춤

현재 방식은 CLI가 127.0.0.1에 임시 HTTP 서버를 열고 브라우저를 인증 URL로 보낸 뒤, 인증 제공자가 authorization code를 로컬 callback으로 돌려주는 구조임

2019년 표준화된 RFC 8628 Device Authorization Grant는 토큰을 요청하는 CLI와 사용자가 인증하는 브라우저 장치를 분리해, 포트 바인딩이나 로컬 브라우저 의존을 없앰

Device flow는 device_code, user_code, verification_uri, interval을 받아 /token을 주기적으로 폴링하고, authorization_pending, slow_down, access_denied, expired_token 같은 표준 상태를 처리함

새 CLI라면 device flow를 기본값으로 두고 .well-known/openid-configuration으로 엔드포인트를 발견하며, refresh token은 ~/.config의 JSON 파일이 아니라 OS keychain에 저장해야 함

localhost 리다이렉트가 전제하는 것

흔한 CLI 로그인은 로컬 HTTP 서버와 시스템 브라우저가 같은 머신에 있다는 가정 위에서 동작함

표현은 좀 대충이지만 흥미로움. 기기 코드/링크를 1분마다 교체하면 피싱에 악용되는 것도 줄일 수 있을 듯함
한 번 사용된 뒤에는 회전을 멈추고 해당 세션을 IP나 브라우저에 묶어두면 됨

이 방식이 글에서 말하는 것만큼 크게 도움이 되지는 않음. 사용자가 들어오면 흐름을 시작하고 곧바로 정상 제공자로 리다이렉트하는 피싱 랜딩 페이지를 만드는 건 꽤 쉬움
Microsoft처럼 사용자가 코드를 직접 입력하게 하는 제공자라면, 랜딩 페이지가 안내문을 띄우고 코드를 클립보드에 복사해 피싱에 더 쉽게 걸리게 만들 수도 있음

좋은 글이고, 모두가 RFC 8628 쪽으로 옮겨가야 한다는 데 동의함
원격 개발 머신에서 CLI OAuth 절차를 너무 자주 겪다 보니, xdg-open을 가로채고 포트를 자동 포워딩해서 나쁜 사용자 경험을 덮어주는 개인 도구를 만들었음: https://github.com/phinze/bankshot

흥미로움. 최근에 마침 “옛” 인증 방식인 RFC 8252를 구현했는데, “새” 방식인 RFC 8268은 모르고 있었음
내 주된 사용 사례가 Google 서버 인증이었기 때문에 지식 공백이 생긴 듯함. 내가 RFC 8268 흐름이라고 생각하는 문서에는 다음처럼 명시돼 있음

Alternatives

If you are writing an app for a platform such as Android, iOS, macOS, Linux, or Windows (including the Universal Windows Platform), that has access to the browser and full input capabilities, use the OAuth 2.0 flow for mobile and desktop applications. (You should use that flow even if your app is a command-line tool without a graphical interface.)
그래서 그대로 RFC 8252 흐름만 읽고 구현했음. 내 도구는 CLI가 맞지만, 사용 사례가 로컬 전용이라 SSH나 컨테이너 환경은 고려하지 않았음
게다가 RFC 8268 흐름에서는 Google이 제한된 OAuth 2.0 범위만 허용하므로, 일부 애플리케이션에는 결정적인 제약이 될 수 있음

사소한 정정: 원문 번호를 다시 확인해 보니 RFC 8628임
Google의 범위 제약은 OIDC가 복잡하게 고개를 드는 부분임. 이상적으로는 Google이 접근 토큰에 뭉개 넣는 대신 ID 토큰을 돌려줘야 하지만, 그건 Google의 OAuth 설정 문제지 8628 자체의 특성은 아님
OAuth의 끝없는 복잡함은 여기서 옴. 표준은 권한 부여 체계를 어떻게 만들고 전달할지의 틀을 잘 정의하지만, 그것이 무엇이어야 하는지에는 의도적으로 침묵함. “대부분”의 제공자가 동의하는 공통 HTTP 엔드포인트 묶음을 얻는 데도 OIDC 발명과 여러 해가 필요했음

두 접근을 결합하면 안 되나? localhost URL로 리다이렉트하고 hello를 되돌려 보내게 한 뒤, 클라이언트가 hello를 못 받으면 CLI에 URL을 출력하는 방식임
동시에 서버가 보낸 hello의 응답을 받지 못하면 브라우저에 코드를 띄우고 “로그인을 시도 중인지 확인하라” 같은 메시지를 보여주면 됨. Google처럼 휴대폰에서 선택할 숫자를 표시하는 식으로 더 쉽게 만들 수도 있음

cli -> server/auth?r=localhost&fallback_choices=10,20,30
server -> localhost/hello
Case 1: hello request received, go to redirect URI on localhost
Case 2: server has not received a hello reply, client has not received a hello request

  • CLI displays a/the webpage url and prompts for selecting a fallback_choice

  • Webpage displays a number say 20 from choices

  • User enters/selects it on the CLI

  • solves the token copy/paste problem if choices

장점은 2번 경우에도 사람들이 링크 클릭은 쉽게 하지만 OTP/코드 공유는 상대적으로 덜 한다는 점이고, 공격자가 해킹 중에 계속 사회공학적으로 개입해야 한다는 점임

로컬 머신에서 잘 동작할 때는 상호작용이 필요 없으니, 기본값은 브라우저 기반 흐름이었으면 좋겠음

이 흐름도 잘 동작하는 경우에는 브라우저 기반으로 작동함. 다만 실패했을 때 더 나은 대체 경로가 있음

AI 자동 생성 콘텐츠

본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0