Gmail과 드라이브를 에이전트에 맡기는 명령줄 gws, 연결 전에 볼 권한과 한계
Tools16분 읽기

Gmail과 드라이브를 에이전트에 맡기는 명령줄 gws, 연결 전에 볼 권한과 한계

gws에 로그인할 때 --readonly 옵션 하나가 쓰기·삭제를 구글 쪽에서 막는다. 로그인 옵션별 요청 범위를 직접 찍어 보고, 읽기 토큰으로도 남는 위험과 권한 규칙의 한계를 정리했다.

gws를 에이전트에 붙일 때 가장 먼저 정할 것은 설치 방법이 아니라 로그인 명령의 옵션 하나입니다. gws auth login --readonly -s gmail,drive로 들어가면 토큰이 gmail.readonly와 drive.readonly 범위만 받기 때문에, 에이전트가 어떤 gws 명령을 치든 메일을 보내거나 파일을 지우는 요청은 구글이 거절합니다. --readonly 없이 -s gmail,drive만 쓰면 같은 로그인이 gmail.modify와 drive 전체 범위를 받아 갑니다. 한 단어 차이로 에이전트가 건드릴 수 있는 것이 읽기에서 읽기·보내기·삭제로 넓어집니다.

gws는 저장소 googleworkspace/cli가 사람과 AI 에이전트를 위한 Google Workspace 전체용 명령줄이라고 소개하는 Rust 도구로, Gmail·드라이브·캘린더·시트 같은 API를 명령어 하나로 부르고 응답을 JSON으로 돌려줍니다. 구글이 지원하는 제품은 아니라고 README가 밝히고, 1.0까지는 깨지는 변경이 있을 수 있다고 적어 두었습니다. 10월 27일 기준 별은 3만 1,900개, 포크는 2,000개, 열린 이슈는 134건이고 라이선스는 Apache-2.0입니다. 마지막 릴리스는 3월 31일의 v0.22.5(npm 패키지의 최신 버전도 0.22.5)이고 main 브랜치의 마지막 커밋도 같은 날이라, 지금 받는 버전은 7개월째 그대로입니다. 이 글의 명령 결과는 모두 0.22.5를 Docker에 설치해 편집부가 직접 돌린 것입니다. 자격 증명은 가짜 값으로 두고 로그인 직전에 출력되는 인증 URL의 scope= 부분만 읽었으니, 어떤 계정에도 로그인하지 않았습니다.

명령 한 줄이 지나는 곳, 네 군데에서 열리는 틈

gws는 명령 목록을 내장하지 않습니다. 실행할 때 구글의 Discovery 서비스에서 해당 서비스의 문서를 받아 명령 체계를 만듭니다. 서비스 이름을 읽고, Discovery 문서를 받아 24시간 캐시하고, 명령 트리를 만들고, 나머지 인자를 다시 해석한 뒤, 인증을 붙여 API를 부르는 5단계입니다. 그래서 Workspace에 새 API 메서드가 생기면 도구를 고치지 않아도 따라옵니다. 저장소 개발 지침(AGENTS.md)은 이 도구가 에이전트에게 자주 호출된다는 전제로 모든 입력을 적대적일 수 있다고 보고 경로 조작과 제어 문자를 거르도록 정해 두었습니다.

아래 그림은 명령 하나가 에이전트에서 구글까지 가는 길에 사람이 점검할 자리를 A부터 D까지 표시한 것입니다. 왼쪽 붉은 영역의 글이 에이전트에 들어오는 길(A)부터, 에이전트가 치는 명령(B), 토큰이 놓인 자리(C), 구글이 응답하는 범위(D) 순서로 보면 됩니다.

외부 발신자의 글이 에이전트로 들어오고, 에이전트가 gws를 실행하고, gws가 토큰을 붙여 구글 API를 부르는 경로와 네 군데의 틈 그림 1. 한 번의 호출이 지나는 세 영역과 네 개의 틈(A 외부 글, B 에이전트 명령, C 토큰 보관, D 구글의 범위 검사)

네 틈은 막는 주체가 다릅니다. A와 B는 에이전트와 그 권한 규칙의 몫이고, C는 운영체제 사용자 계정과 gws의 저장 방식이 나눠 맡으며, D만이 구글이 직접 집행하는 경계입니다. 에이전트가 무슨 명령을 쳐도 D에서 거절되게 만들어 두면 A와 B에서 무슨 일이 일어나도 피해의 상한이 정해집니다. 이 글의 나머지는 D를 어떻게 좁히고, 좁혀도 남는 틈을 어떻게 메우는가입니다.

헬퍼 명령(+triage, +send처럼 +가 붙은 것)만 있는 것이 아니라는 점도 짚어 둘 필요가 있습니다. Discovery에서 만들어지는 명령은 API 메서드 전부입니다. gws schema로 메서드를 들여다보면 삭제 호출이 어떤 범위를 받는지 바로 보입니다.

$ gws schema drive.files.delete | jq -r '.httpMethod, .scopes[]'
DELETE
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.appdata
https://www.googleapis.com/auth/drive.file

메서드 설명에는 휴지통으로 옮기지 않고 영구 삭제한다고 적혀 있고, 허용 범위 목록에 drive.readonly는 없습니다. 같은 방식으로 메일 보내기(gmail.users.messages.send)는 mail.google.com, gmail.compose, gmail.modify, gmail.send를, 영구 삭제(gmail.users.messages.delete)는 mail.google.com 하나만, 드라이브의 공유 권한 추가(drive.permissions.create)는 drive와 drive.file만 받습니다. 편집부가 살펴본 쓰기 메서드 가운데 읽기 범위를 받는 것은 하나도 없었습니다.

로그인 옵션이 요청하는 범위를 직접 찍어 보니

README가 안내하는 로그인 옵션은 서비스를 고르는 -s(--services) 하나뿐입니다. gws auth login --help에는 두 가지가 더 있습니다. --readonly는 읽기 범위만 요청하고, --full은 기본 범위에 pubsub과 cloud-platform까지 얹습니다. 옵션마다 인증 URL에 실리는 범위를 뽑아 보면 이렇습니다.

gws auth login의 옵션별로 요청되는 OAuth 범위 이름: -s gmail,drive는 gmail.modify와 drive, –readonly는 gmail.readonly와 drive.readonly, 옵션 없음은 7개, –full은 pubsub과 cloud-platform 추가, -s script는 mail.google.com 포함 17개 그림 2. 로그인 옵션별 요청 범위. gws 0.22.5, 터미널 화면 없이 실행해 인증 URL의 scope= 부분을 읽은 결과

같은 서비스를 골라도 노란색 줄(쓰기 가능)과 초록색 줄(읽기만)이 갈립니다. 눈에 띄는 것은 세 가지입니다. 첫째, -s gmail의 기본값이 gmail.modify라서 에이전트가 메일을 읽고 초안을 만들고 보낼 수 있습니다. 구글 문서의 설명은 메일 읽기·작성·전송이 되고 휴지통을 거치지 않는 영구 삭제만 빠진다는 것입니다. 둘째, -s drive의 기본값은 drive로, 모든 드라이브 파일을 보고 관리하는 범위입니다. 셋째, -s script는 전체 메일함의 영구 삭제까지 가능한 mail.google.com을 포함해 17개를 한꺼번에 요청합니다. Apps Script가 다른 서비스를 부르는 코드를 돌릴 수 있기 때문이겠지만, 에이전트용으로 고를 이유가 없는 조합입니다.

옵션 없이 gws auth login만 칠 때는 터미널이 화면을 받을 수 있는지에 따라 달랐습니다. 화면이 있으면 범위를 고르는 전체 화면 선택기가 열리고(README는 이 선택기의 recommended 프리셋이 85개 이상이라고 경고합니다), 화면이 없는 환경에서는 드라이브·시트·Gmail(modify)·캘린더·문서·슬라이드·태스크 7개가 기본으로 요청됐습니다. 에이전트가 터미널 없이 로그인을 시도하게 두면 쓰기 범위 7개가 그대로 붙는 셈입니다.

범위 이름이 무엇을 뜻하는지는 구글 문서에서 가져온 아래 표로 읽으면 됩니다.

범위 구글 문서의 설명 분류
gmail.readonly 메일과 설정 보기 제한(restricted)
gmail.modify 메일 읽기·작성·전송. 휴지통을 거치지 않는 영구 삭제는 제외 제한
gmail.compose 초안 관리와 메일 전송 제한
gmail.send 사용자를 대신해 메일 전송 민감(sensitive)
mail.google.com 읽기·작성·전송과 영구 삭제 제한
drive.readonly 모든 드라이브 파일 보기와 내려받기 제한
drive 모든 드라이브 파일 보기와 관리 제한
drive.file 앱으로 열었거나 공유받은 파일만 만들고 고침 비민감

표에서 두 가지를 더 읽을 수 있습니다. gmail.readonly조차 제한 분류라서 이 범위로 앱을 일반 공개하려면 구글의 검증 절차가 필요합니다. 또 gmail.modify로 로그인하면 메일 필터를 만드는 호출(gmail.settings.basic 필요)과 전달 주소를 추가하는 호출(gmail.settings.sharing 필요)은 범위에 없어 거절됩니다. 필터로 몰래 자동 전달을 걸어 두는 고전적인 수법이 이 로그인으로는 막힙니다.

서비스별 범위 개수, 채팅·클래스룸·스크립트가 넓다

범위 개수도 서비스마다 크게 다릅니다. Gmail이나 드라이브는 서비스 하나가 범위 하나로 대응되지만, 채팅과 클래스룸은 기능별로 잘게 쪼개져 있어 한꺼번에 수십 개가 됩니다. 아래 막대는 서비스 하나만 골라 로그인했을 때의 개수(신원 범위 openid·이메일·프로필 제외)를 기본과 --readonly로 견준 것입니다. 점선은 README가 말하는 검증 전 앱의 한도 약 25개입니다.

서비스별 요청 범위 개수의 묶음 막대. 채팅 29개 대 11개, 클래스룸 24개 대 11개, 이벤트 19개 대 9개, 스크립트 17개 대 2개, 연락처 10개 대 3개, 폼 6개 대 3개, 옵션 없음 7개 대 7개, Gmail 1개 대 1개 그림 3. 로그인 한 번에 요청되는 범위 개수(기본 대 –readonly). 편집부가 gws 0.22.5로 센 값

채팅은 기본으로 29개를 요청해 점선을 넘고, --readonly로 11개까지 줄어듭니다. 스크립트는 17개에서 2개(script.projects.readonly, script.deployments.readonly)로 줄어 전체 메일 범위가 사라집니다. 반대로 Gmail과 드라이브, 캘린더, 시트는 1개라서 옵션을 붙여도 개수가 그대로이고 범위의 종류만 바뀝니다. 개수가 아니라 이름을 봐야 하는 서비스라는 뜻입니다.

예외도 있습니다. -s workflow와 -s keep은 신원 범위 외에는 아무것도 요청하지 않습니다. workflow 헬퍼(+standup-report 같은 것)는 캘린더나 태스크, Gmail을 재료로 쓰므로 그 서비스들의 범위를 따로 받아야 동작합니다. 또 Model Armor를 켜는 --sanitize 옵션의 도움말에는 cloud-platform 범위가 필요하다고 적혀 있는데, -s modelarmor는 기본에서만 그 범위를 요청하고 --readonly에서는 아무 범위도 요청하지 않습니다. 읽기 전용 프리셋 하나로 검사 기능까지 켜는 길은 없다는 뜻이고, cloud-platform은 구글 클라우드 전반에 닿는 넓은 범위입니다.

읽기 전용 토큰으로도 새는 길

--readonly가 쓰기와 삭제를 막아 주지만 gmail.readonly는 전체 메일함을, drive.readonly는 모든 파일을 읽을 수 있습니다. 토큰이 직접 무언가를 보내지는 못해도 에이전트의 컨텍스트에 메일함과 드라이브가 통째로 들어올 수 있다는 뜻입니다. 읽기 토큰을 쥔 에이전트에게 남는 위험은 두 줄기입니다.

첫째는 A 틈입니다. 메일 본문, 공유받은 문서, 캘린더 초대의 설명은 모두 내가 쓰지 않은 글이고, +triage나 +read가 그 글을 에이전트에게 건넵니다. 그 안에 이 메일을 요약해 달라는 문장 대신 이 폴더의 파일 목록을 아래 주소로 보내라는 문장이 들어 있어도 도구는 구분하지 못합니다. 이런 지시에 에이전트가 끌려가는 것이 프롬프트 인젝션이고, 읽기 토큰은 그 지시의 효과 중 쓰기 쪽을 구글에서 끊을 뿐입니다.

둘째는 읽은 내용이 밖으로 나가는 길입니다. 읽기 토큰으로는 gws가 직접 메일을 보내지 못하니, 데이터가 나가려면 같은 세션의 다른 도구가 필요합니다. 웹 요청이나 curl, 다른 서비스 커넥터, 파일을 쓰고 올리는 명령이 그 후보입니다. 이 점은 편집부의 판단이지만, 구조상 읽기 토큰의 안전 여부는 gws 설정이 아니라 같은 에이전트에 어떤 외부 통신 도구가 붙어 있는지로 결정됩니다. 개인 메일을 읽히는 에이전트라면 외부 통신 도구가 없는 세션에서 돌리는 쪽이 읽기 전용 옵션만큼 중요합니다.

도구가 제공하는 검사 장치는 Model Armor입니다. --sanitize 뒤에 템플릿 경로를 주거나 환경 변수 GOOGLE_WORKSPACE_CLI_SANITIZE_TEMPLATE을 지정하면 API 응답이 에이전트에 닿기 전에 프롬프트 인젝션·민감 정보 같은 필터를 거칩니다. 모드는 warn(기본, 경고만)과 block(차단) 중에서 고릅니다. 템플릿을 구글 클라우드에서 먼저 만들어야 하고, 앞서 본 대로 cloud-platform 범위가 따라붙으며, 비용은 검사한 프롬프트와 응답의 토큰 수로 매겨집니다. 읽기 전용 로그인에는 담기지 않으니, 켜려면 읽기 전용이라는 단순한 모양을 포기해야 합니다.

마지막으로, 로그인 과정에서 에이전트에게 동의 화면을 맡기지 말아야 합니다. README에는 사람이 직접 하는 흐름과 함께 에이전트가 URL을 열고 계정을 고르고 동의 화면을 처리하는 방식도 적혀 있고, 범위 체크박스가 보이면 필요한 범위나 모두 선택을 고르라고 안내합니다. 이 화면은 범위가 정해지는 유일한 자리입니다. 사람이 읽고 누르는 쪽이 안전합니다.

쓰는 헬퍼 열두 개와 확인 문구가 빠진 세 개

저장소의 스킬 인덱스(docs/skills.md)에는 SKILL.md가 95개 올라 있고, 서비스 19개·헬퍼 25개·페르소나 10개·레시피 41개로 나뉩니다. README는 100개 이상이라고 쓰지만 인덱스와 편집부가 센 값은 95개입니다. 위험 지도에서 따져 볼 것은 이 중 헬퍼 25개, 즉 에이전트가 가장 자주 칠 한 줄 명령들입니다. 25개를 모두 열어 편집부가 하는 일로 나누면 읽기 7개, 보내기·쓰기 12개, 구독·자원 생성 4개, 검사 2개입니다.

헬퍼 25개의 도넛. 읽기 전용 7개, 보내기·쓰기 12개, 구독·자원 생성 4개, 검사 2개와 각 구분에 속한 명령 이름 그림 4. 헬퍼 25개의 성격. 저장소 skills 폴더의 SKILL.md 25개를 편집부가 분류

절반 가까운 12개가 쓰는 쪽이라서 --readonly 로그인 하나로 막히는 범위가 그만큼 넓습니다. 구독·자원 생성 4개에는 눈에 덜 띄는 비용이 있습니다. gmail +watch와 events +subscribe는 구글 클라우드 프로젝트에 Pub/Sub 자원을 만들고, --cleanup을 주지 않으면 그 자원이 남으며, Gmail의 watch는 7일이 지나면 만료되어 다시 실행해야 합니다.

스킬 파일에 들어 있는 쓰기 전에 확인하라는 문구는 25개 중 11개에만 있습니다. 쓰기 헬퍼 12개 중에서는 +send, calendar +insert, sheets +append, docs +write, chat +send, drive +upload, +email-to-task, +file-announce, script +push의 9개에 문구가 있고, 메일을 내보내는 +reply, +reply-all, +forward 3개에는 없습니다. 이 셋의 팁 항목에는 --draft로 초안만 저장하는 방법이 적혀 있을 뿐입니다. 25개 스킬 모두 첫머리에 공통 규칙 스킬 gws-shared를 읽으라는 줄이 있고 그 규칙에 쓰기·삭제 명령은 실행 전에 사용자에게 확인하라는 항목이 들어 있으니 아주 비어 있지는 않습니다. 그래도 전달(+forward)은 0.20.0부터 원본 첨부파일을 기본으로 함께 보내는 명령이라, 문구가 없는 자리가 하필 가장 민감한 자리입니다.

미리 보기 옵션 --dry-run도 한계를 알고 써야 합니다. 몇 가지를 직접 돌려 보면 무엇이 보이고 무엇이 안 보이는지 갈립니다.

명령 --dry-run이 보여 주는 것
drive files delete 메서드 DELETE와 대상 경로
drive permissions create(type: anyone) 본문의 role과 type까지
calendar +insert 제목·시작·종료 시각
gmail +send 본문 null, 주소는 보내기 엔드포인트
gmail +send --draft 본문 {"message": {}}
gmail +triage 인증 오류(자격 증명이 없는 환경)

삭제와 링크가 있는 누구나 공유는 무엇이 나갈지 정확히 보이지만, 메일은 받는 사람과 본문이 안 보입니다. 아래는 +send의 실제 출력입니다.

$ gws gmail +send --to a@example.com --subject hi --body hello --dry-run
{
  "body": null,
  "dry_run": true,
  "is_multipart_upload": true,
  "method": "POST",
  "query_params": [],
  "url": "https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send"
}

호출이 메일 보내기라는 것까지만 알 수 있으니, 메일은 --draft로 초안함에 저장하고 사람이 열어 보는 쪽이 확인 수단으로 더 낫습니다.

지시문은 문턱이고 권한 규칙은 벽, 그 벽도 완전하진 않다

SKILL.md의 확인 문구는 모델에게 주는 글이라서 도구가 강제하는 차단이 아닙니다. 모델이 따르면 문턱이 되고, A 틈으로 들어온 글이 다른 지시를 끼워 넣으면 흔들릴 수 있습니다. 그 아래에는 에이전트 프로그램의 권한 규칙이 있습니다. Claude Code를 예로 들면, 규칙은 거부(deny), 확인(ask), 허용(allow) 순서로 평가되고 먼저 맞은 쪽이 이깁니다. 넓은 확인 규칙 Bash(gws *)를 두면 더 좁은 허용 규칙이 있어도 매번 묻게 되므로, 읽기 명령을 자동 허용하려면 확인 규칙을 넓게 두지 말고 허용 목록만 좁게 만들어야 합니다. 목록에 없는 명령은 기본 모드에서 알아서 묻습니다.

Discovery 명령에서는 접두사를 어디서 끊는지가 중요합니다. gws drive files list와 gws drive files delete는 gws drive files까지 똑같습니다. Claude Code 문서의 원칙대로 *는 하위 명령 뒤에 놓아야 하고, Bash(gws drive files *)를 허용하면 삭제까지 열립니다. 읽기 명령은 Bash(gws drive files list *)처럼 끝까지 적어 하나씩 허용합니다.

이 규칙이 보안 경계가 아니라는 점은 문서가 스스로 밝힙니다. 규칙은 에이전트가 보통 쓰는 모양의 명령을 잡을 뿐이라, 같은 프로그램을 절대 경로나 sh -c '…' 안에 넣어 부르면 거부·확인 규칙을 비껴갈 수 있고, 인자를 제한하는 패턴도 깨지기 쉽다고 합니다. 그래서 순서는 이렇습니다. 구글이 집행하는 범위(--readonly)가 마지막 벽이고, 에이전트의 권한 규칙은 실수와 거친 요청을 걸러 주는 앞쪽 울타리이며, SKILL.md는 그 앞의 안내입니다.

규칙에 꼭 넣을 거부 대상이 하나 있습니다. gws auth export --unmasked는 복호화한 자격 증명을 표준 출력에 찍습니다. 같은 사용자 계정으로 도는 에이전트가 셸을 쓸 수 있다면 이 한 줄로 리프레시 토큰과 클라이언트 비밀 값을 대화에 올릴 수 있습니다. gws auth 전체를 거부하고 로그인과 로그아웃은 사람이 직접 하도록 두는 편이 단순합니다.

README에는 에이전트와 잇는 길도 둘 적혀 있습니다. Gemini CLI 확장(gemini extensions install https://github.com/googleworkspace/cli)과 OpenClaw용 스킬 폴더 링크입니다. Gemini CLI는 6월 18일부터 개인 무료 계정과 AI Pro·Ultra 구독 계정의 요청을 처리하지 않아, 이 길은 유료 API 키나 회사 라이선스로 쓰는 경우에만 남아 있습니다.

자격 증명이 놓이는 자리와 일주일 만료

C 틈, 즉 토큰이 어디에 있는지를 보겠습니다. gws는 토큰을 네 군데에서 찾고 우선순위가 정해져 있습니다.

우선순위 출처 설정
1 액세스 토큰 GOOGLE_WORKSPACE_CLI_TOKEN
2 자격 증명 파일(서비스 계정 키 포함) GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE
3 암호화된 로그인 자격 증명 gws auth login
4 평문 자격 증명 ~/.config/gws/credentials.json

위쪽이 아래쪽을 덮어씁니다. 그래서 읽기 전용으로 다시 로그인했는데도 셸 환경에 예전 액세스 토큰이 남아 있으면 그 토큰이 먼저 쓰입니다. 환경 변수는 .env 파일에도 둘 수 있으니, 에이전트가 읽는 작업 폴더에 토큰이 들어 있지 않은지도 확인할 일입니다. 쓰기 범위로 받은 로그인 자격 증명이 이미 저장되어 있다면 gws auth logout으로 지우고 --readonly로 새로 로그인합니다.

로그인으로 만들어지는 자격 증명은 AES-256-GCM으로 암호화되어 ~/.config/gws/credentials.enc에 저장되고, 키는 운영체제 키링에 보관됩니다. 0.22.3부터 macOS와 Windows는 키체인만 쓰고 대체 파일을 만들지 않으며, Linux는 파일 방식으로 돌아갈 수 있습니다(GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file, 키 파일 ~/.config/gws/.encryption_key). 다만 암호화는 디스크에 놓인 파일을 위한 것입니다. gws가 같은 사용자 권한으로 키를 꺼내 복호화하므로, 같은 계정에서 도는 프로세스도 gws auth export로 같은 값을 받을 수 있습니다. OAuth 클라이언트 정보(client_secret.json)는 평문 파일로 같은 폴더에 둡니다. 브라우저가 없는 서버에는 다른 컴퓨터에서 로그인해 gws auth export --unmasked > credentials.json으로 옮기라고 안내하는데, 이 파일에는 비밀 값이 암호화되지 않은 채 담깁니다. 서비스 계정 키에 도메인 전체 위임까지 걸려 있다면 한 사용자가 아니라 조직 전체를 대신할 수 있으므로, 개인 시험용 연결에서는 쓰지 않는 쪽이 낫습니다.

토큰이 얼마나 오래 사느냐도 위험의 크기를 정합니다. gws는 사용자 Cloud 프로젝트의 OAuth 클라이언트로 로그인하므로 앱의 게시 상태가 곧 토큰의 수명입니다. 구글 문서에 따르면 게시 상태가 테스트인 외부 앱의 리프레시 토큰은 7일 뒤 만료되고(이름·이메일·프로필 범위만 쓰는 앱은 예외), 테스트 사용자는 최대 100명입니다. Gmail 범위를 가진 토큰은 구글 비밀번호를 바꾸면 무효가 되고, 계정당 클라이언트 하나에 리프레시 토큰이 100개까지만 유지됩니다. 앱을 프로덕션으로 게시하면 7일 제한은 풀리지만 Gmail과 드라이브 범위는 제한 분류라 검증이 필요합니다. 개인 한 명이 쓰는 용도라면 일주일에 한 번 다시 로그인하는 쪽이 간단하고, 편집부 해석으로는 설령 토큰이 새어도 일주일 안에 죽는다는 이점이 있습니다. 테스트 모드로 쓰려면 Cloud 콘솔에서 내 계정을 테스트 사용자로 넣어야 하는데, 빼먹으면 로그인이 Access blocked 오류로 끝납니다.

구글 MCP 서버와 gog는 이 틈을 어떻게 다루나

같은 일을 하는 다른 길이 두 가지 있습니다. 구글이 내놓은 Workspace용 원격 MCP 서버와 서드파티 명령줄 gog입니다. gws에도 한때 MCP 서버 모드(gws mcp)가 있었지만 0.3.0에서 들어왔다가 0.8.0에서 빠져 지금은 명령줄과 스킬이 유일한 연결 방식입니다.

gws

  • 범위를 로그인 옵션이 정한다(-s, –readonly)
  • 명령 허용 목록은 도구에 없고 에이전트의 권한 규칙이 맡는다
  • 서버 없이 스킬을 읽고 셸에서 실행한다
  • 비공식, 1.0 이전, 릴리스는 3월 31일이 마지막

구글 Workspace MCP 서버

  • 서버가 노출하는 도구가 정해져 있다(Gmail은 프로필·검색·초안·읽기·쓰기)
  • 요청 범위가 서버별로 읽기와 쓰기로 나뉜다
  • 개발자 미리보기 프로그램을 전제로 하고, 서버별 엔드포인트와 OAuth 설정이 따른다
  • 사용자 권한과 데이터 거버넌스를 그대로 물려받는다

구글 MCP 서버는 5월 1일 공개 개발자 미리보기로 열렸고(Cloud Next ’26에서 발표) 지금도 미리보기 단계입니다. Gmail·드라이브·문서·시트·슬라이드·캘린더·채팅·피플·클래스룸 아홉 서버가 각각 /mcp/v1 엔드포인트를 갖고, 쓰기 범위는 Gmail이 gmail.compose, 드라이브가 drive.file입니다. 앞의 표에서 본 대로 gmail.compose는 초안 관리와 메일 전송이라 초안 전용 범위가 아닙니다. OAuth 클라이언트는 AI 에이전트용으로 사용하는 설정을 켜야 하고, 관리자는 보안 조사 도구에서 OAuth 로그 이벤트를 볼 수 있습니다. 세 방법을 같은 잣대로 놓으면 이렇습니다.

gws 구글 MCP 서버 gog
읽기 전용 로그인 --readonly 서버별 읽기 범위(gmail.readonly, drive.readonly) --readonly
보내기만 막기 옵션 없음. gmail.readonly로 내려야 막힌다 쓰기 범위 gmail.compose가 전송을 포함 --gmail-no-send
명령 허용 목록 없음 서버가 내놓는 도구가 곧 범위 --enable-commands-exact
상태 비공식, 1.0 이전 개발자 미리보기 서드파티(MIT), 저장소는 openclaw로 이동, 별 약 8,500개

gog는 Go로 쓰인 명령줄로 Gmail·캘린더·드라이브·문서 등을 다루고, gog mcp는 읽기 전용이 기본인 MCP 모드입니다. 안전장치를 도구 안에 많이 넣은 쪽은 gog이고, gws는 서비스 단위 범위 선택과 읽기 전용 프리셋까지만 도구가 맡습니다. 어느 쪽이든 마지막 경계는 로그인 때 받은 범위라는 점은 같습니다.

맡기기 전에 지울 틈 목록

아래는 A부터 D까지의 틈마다 연결 전에 한 번씩 확인할 항목입니다.

  • 토큰이 읽기 범위인지 확인한다. 이전에 받은 쓰기 범위 자격 증명이 있으면 gws auth logout 후 --readonly로 다시 로그인한다
  • 동의 화면은 에이전트가 아니라 사람이 직접 읽고 누른다
  • 셸 환경과 .env에 GOOGLE_WORKSPACE_CLI_TOKEN이나 GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE이 남아 있지 않은지 본다
  • 회사 계정이나 관리자 권한 계정이 아니라 별도 계정에서 서비스 하나부터 시험한다
  • gws auth는 거부 규칙에 넣고, 읽기 헬퍼만 하나씩 허용한다
  • 같은 세션에 읽은 내용을 밖으로 내보낼 웹 요청이나 다른 커넥터가 붙어 있지 않은지 본다
  • 쓰기가 필요해지면 --draft로 초안만 만들게 하고 보내는 일은 사람이 한다
  • 0.22.5를 고정해 쓰고, 올리기 전에 변경 기록에서 동작이 바뀐 항목을 훑는다

읽기 토큰과 권한 규칙을 함께 거는 설정

쓰기 범위를 모두 막은 읽기 로그인부터 시작합니다. 서비스는 쓸 것만 고르고, 동의 화면의 범위 목록이 아래 두 줄의 결과와 같은지 사람이 확인합니다.

gws auth logout
gws auth login --readonly -s gmail,calendar,drive

다음은 Claude Code 프로젝트 설정(.claude/settings.json)의 예시입니다. 허용은 읽기 명령만 끝까지 적고, 거부에는 자격 증명을 꺼내는 gws auth와 삭제·공유 같은 Discovery 명령, 토큰이 놓이는 파일 읽기를 넣었습니다. 앞에서 본 대로 이 규칙은 울타리이고, 쓰기를 막는 마지막 벽은 위의 --readonly 로그인입니다. 쓰기 헬퍼를 열어야 할 때는 허용에 넣지 말고 그대로 두면 실행 전에 묻습니다.

{
  "permissions": {
    "allow": [
      "Bash(gws gmail +triage *)",
      "Bash(gws gmail +read *)",
      "Bash(gws calendar +agenda *)",
      "Bash(gws sheets +read *)",
      "Bash(gws workflow +standup-report *)",
      "Bash(gws drive files list *)",
      "Bash(gws schema *)"
    ],
    "deny": [
      "Bash(gws auth *)",
      "Bash(gws drive files delete *)",
      "Bash(gws drive permissions *)",
      "Read(./.env)",
      "Read(~/.config/gws/**)"
    ]
  }
}
#gws#Google Workspace#CLI#AI 에이전트#Agent Skills