
브라우저를 통해 휴대폰에서 클라우드 코딩 에이전트를 제어하는 방법
요약
Cloud Run 기반의 코딩 에이전트를 Google Identity-Aware Proxy(IAP)를 통해 모바일 브라우저에서 안전하게 제어하는 방법을 소개합니다. IAP를 활용하면 인스턴스 비용을 최적화하면서도 외부에서 터미널 세션에 쉽게 접속할 수 있습니다.
핵심 포인트
- IAP를 사용하여 Google 계정 기반의 안전한 모바일 접속 환경 구축
- Tailscale 사용 시 발생하는 Cloud Run 인스턴스 조기 회수 문제 해결
- WebSocket 요청을 통한 인스턴스 활성 상태 유지 및 비용 최적화
- 컨테이너화된 개발 환경을 모바일에서도 유연하게 활용 가능
요약 (tl;dr): 웹 터미널에서 코딩 에이전트를 실행하는 Cloud Run 서비스 앞에 Google의 Identity-Aware Proxy (IAP)를 배치했습니다. 이제 휴대폰에서 URL을 열고 Google 계정으로 로그인하면 에이전트와 대화할 수 있습니다.
출처: github.com/ykdojo/antigravity-cloud-run
이것은 저의 컨테이너화된 개발 환경 설정 (containerized dev environments setup)을 기반으로 합니다. 에이전트는 Cloud Run 위의 컨테이너 내부에서 --dangerously-skip-permissions 옵션과 함께 실행되며, 웹 터미널을 통해 접속할 수 있습니다. 부족했던 부분은 노트북이 아닌 곳에서 이를 사용하는 것이었습니다.
이 특정 설정은 Antigravity CLI를 위해 수행되었지만, 거의 모든 다른 CLI 코딩 에이전트에서도 작동할 것입니다.
휴대폰에서 세션에 접속하는 두 가지 방법, 그리고 내가 IAP를 선택한 이유
제 세션은 이미 저의 Tailscale 네트워크에 연결되어 있으므로, 당연한 경로는 휴대폰의 Tailscale 앱을 사용하는 것이었습니다. 작동은 하지만 한 가지 문제가 있습니다. tailnet 트래픽은 Cloud Run의 프런트엔드를 완전히 우회하기 때문에, 오토스케일러 (autoscaler)가 서비스를 유휴 상태로 판단하여 사용 중인 약 15분 후에 인스턴스를 회수해 버립니다. 유일한 해결책은 min-instances=1로 인스턴스를 고정하는 것인데, 이는 사용 여부와 관계없이 계속 비용이 발생합니다.
IAP는 이 상황을 반전시킵니다. Identity-Aware Proxy는 Google Cloud의 관리형 로그인 게이트웨이입니다. 서비스 앞에 IAP를 배치하면 허용 목록(allowlist)에 등록된 Google 계정만 통과할 수 있습니다. 서비스의 일반적인 run.app URL을 열고 로그인하면 바로 터미널에 접속하게 됩니다. 터미널의 WebSocket은 실제 인그레스 (ingress) 요청이므로, 탭을 여는 것만으로 인스턴스를 깨우고 연결되어 있는 동안에는 활성 상태를 유지하며, 탭을 닫으면 다시 0으로 스케일 인 (scale back to zero)할 수 있게 해줍니다.
인스턴스가 절대 종료되지 않기를 원한다면, min-instances=1로 배포하여 0으로 스케일 인 (scale down)되지 않도록 설정할 수 있습니다.
스택, 레이어별 분석
- IAP는 누가 들어올지를 결정합니다. 허용 목록 (allowlist)에 추가된 Google 계정만 액세스할 수 있습니다.
- ttyd는 브라우저를 터미널로 변환합니다. 에이전트는 TUI (Text User Interface)이고 브라우저는 HTTP/WebSocket을 사용하는데, ttyd가 이 둘을 연결(bridge)합니다.
- tmux는 연결이 끊겨도 세션을 유지하며, 여러 장치에서 동일한 세션에 다시 연결 (attach)할 수 있게 합니다.
- agy가 실제 작업을 수행합니다.
설정 방법
서비스 자체에 IAP를 활성화하는 것은 세 개의 명령어로 가능합니다:
gcloud run services update SERVICE --region REGION --iap
gcloud run services add-iam-policy-binding SERVICE --region REGION \
...
만약 프로젝트가 Google Cloud 조직 (organization) 내에 있다면 작업이 끝났을 수도 있습니다. 제 프로젝트는 조직에 속해 있지 않아서 먼 길을 돌아가야 했습니다. 혹시 같은 과정을 거쳐야 하는 분들을 위해, 제가 겪은 과정을 정리해 드립니다.
502 우회로: 조직 없음, 자동 OAuth 클라이언트 없음
IAP를 활성화한 후, 모든 요청이 다음과 같은 본문과 함께 502 오류를 반환했습니다:
Empty Google Account OAuth client ID(s)/secret(s).
이유는 다음과 같습니다: IAP의 Google 관리형 OAuth 클라이언트는 조직 내부의 사용자만 인증합니다. 개인 프로젝트에는 조직이 없으므로 클라이언트가 아예 존재하지 않으며, 이것이
- 테스트 사용자 (Test users) (Audience 페이지): 동의 화면 (consent screen)이 테스트 (Testing) 모드인 동안에는 목록에 등록된 테스트 사용자만 로그인할 수 있습니다. 액세서 (accessor) 역할을 부여한 모든 계정을 추가하세요. 테스트 모드에서는 약 7일 후에 로그인이 만료됩니다. 매주 다시 로그인하는 것이 번거롭다면 앱을 게시 (publishing)하여 이 문제를 해결할 수 있습니다.
- 사용자 정의 OAuth 클라이언트 (Custom OAuth client) (Clients 페이지): 유형을 웹 애플리케이션 (Web application)으로 선택합니다. 새로운 클라이언트 ID를 사용하여 다음의 승인된 리디렉션 URI (authorized redirect URI)를 추가하세요:
https://iap.googleapis.com/v1/oauth/clientIds/CLIENT_ID:handleRedirect. Google은 이제 생성 시점에만 비밀 키 (secret)를 보여주므로, 생성할 때 반드시 따로 저장해 두어야 합니다. - IAP에 클라이언트 전달: 프로젝트 내의 모든 IAP 서비스가 이를 상속받을 수 있도록 프로젝트 레벨에서 설정합니다:
# iap_settings.yaml
access_settings:
oauth_settings:
...
gcloud iap settings set iap_settings.yaml --project PROJECT
설정 후에는 yaml 파일을 삭제하세요. IAP는 비밀 키를 해시 (hash) 형태로 저장합니다.
변경 사항은 몇 초 내에 적용됩니다. 502 오류가 사라지고, 서비스 URL이 Google 로그인 화면으로 리디렉션됩니다. 휴대폰에서 서비스 URL을 열고, Google 계정을 선택하면 터미널이 로드됩니다.
IAP로 인해 작동하지 않는 것
한 가지 기능이 작동하지 않게 됩니다: gcloud run services proxy입니다. 이는 제 대시보드가 노트북 로컬 환경에 클라우드 터미널을 임베딩 (embed)하는 방식입니다. IAP는 프록시 (proxy)의 토큰을 거부하며, 조직이 없는 프로젝트에서는 이를 우회할 깔끔한 방법이 없습니다.
따라서 이는 세션별 선택 사항이며, 저는 이를 플래그 (flag)로 만들었습니다. 제 배포 스크립트는 -i 옵션을 통해 IAP를 사용하는 세션을 생성하며, 대시보드는 해당 세션들을 임베딩된 터미널 대신 "브라우저에서 열기" 링크로 표시합니다. 기본값은 IAP를 사용하지 않는 것입니다.
다음은 IAP를 사용하는 phone 세션과 사용하지 않는 laptop 세션의 비교입니다. IAP를 사용하는 세션은 브라우저 탭에서 열리며, 다른 세션은 로컬 프록시를 통해 연결되어 대시보드에 임베딩됩니다:
세션을 생성할 때도 체크박스가 있으며, 기본적으로는 비활성화되어 있습니다:

제한 사항 (Limitations)
기본 기능은 작동합니다: 휴대폰에서 세션을 열고, 작업을 입력한 다음, 실행되는 것을 볼 수 있습니다. 나중에 해결하기를 바라는 몇 가지 미흡한 부분이 있습니다.
스크롤이 좋지 않습니다. 브라우저 탭 안에 있는 터미널이기 때문에, 터치스크린에서 출력 내용을 위로 스크롤하는 것이 생각보다 까다롭습니다.
글꼴 크기가 또 다른 문제입니다. 휴대폰에서 제대로 설정할 수가 없습니다. 제가 시도해 본 다른 모든 브라우저에서는 작동했기 때문에, 아직 무엇이 다른지 확실하지 않습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기
