승인 팝업을 0으로 만들기까지 — 허용 목록을 넓히는 건 답이 아니었다

한 줄 요약 — 자동화가 자꾸 멈추는 이유가 "허용을 안 해줘서"인 줄 알았는데, 사실은 내가 명령을 감싸고 있어서였다.

이런 분께 도움 — 클로드 코드로 반복 작업을 자동화하는데 승인 팝업 때문에 자리를 못 뜨는 분.


Before — "자동화"인데 내가 계속 앉아 있어야 했다

회사 정보를 찾아 구글시트에 채우는 에이전트를 만들었다. 그런데 회사 한 곳을 조사할 때마다 이런 팝업이 여러 번 떴다.

이 명령을 실행하도록 허용하시겠습니까?

회사가 5곳이면 팝업도 그만큼 늘었다. 결국 화면 앞에 앉아 계속 "허용"을 눌러줘야 했다. 이건 자동화가 아니라 그냥 클릭 노동이었다.

📸 여기에 승인 팝업 화면 스크린샷을 넣으면 좋아요

목표를 이렇게 정했다.

"회사 N개 조사해줘"라고 했을 때 허용 요청이 아예 없을 것.


시도 ① — 허용 목록에 명령을 추가했다 (부분 성공)

제일 먼저 떠오른 방법이다. 설정 파일에 "이 명령은 물어보지 말고 그냥 해"라고 적어두는 것.

.claude/settings.json

{

"permissions": {

"allow": [

"Bash(node agent/opendart-lookup.mjs *)",

"Bash(gws sheets spreadsheets values get *)"

]

}

}

조회는 조용해졌다. 그런데 팝업은 계속 떴다.

한참 헤맸다. 분명 허용해뒀는데 왜 또 물어보지? 이때는 원인을 몰라서 "허용 목록을 더 넓게 적어야 하나" 쪽으로 생각이 흘렀다. 그게 함정이었다.


시도 ② — 팝업이 뜨는 자리를 스크립트로 대체했다 ★ 진짜 전환점

원인을 추적해보니, 팝업은 명령 자체가 아니라 명령을 부르는 방식 때문에 떴다.

  • 홈페이지를 볼 때 쓰는 브라우저 도구는 사이트마다 승인을 요구한다 → 회사가 늘면 승인도 비례해서 는다

  • 시트 목록을 볼 때 출력이 길어서 | head를 붙였다 → 파이프를 붙이는 순간 막힌다

  • 시트에 쓸 때 지저분한 안내 문구를 | grep -v로 걸러냈다 → 역시 막힌다

세 개 다 "내가 뭘 덧붙였기 때문에" 막힌 거였다. 그래서 덧붙일 필요가 없게 만들었다.

팝업이 뜨던 자리

왜 떴나

어떻게 바꿨나

홈페이지 확인

브라우저 도구는 사이트마다 승인

fetch-site.mjs를 만듦 — 규칙 한 줄로 허용되고, 회사가 몇 곳이든 승인이 안 늘어남

시트 현황 보기

출력이 길어 | head를 붙임

sheet-list.mjs를 만듦 — 출력을 스크립트 안에서 이미 정리해서 파이프가 필요 없음

시트에 쓰기

안내 문구를 | grep -v로 걸러냄

sheet-write.mjs그 문구를 스크립트 안에서 삼키게 고침

핵심은 허용 범위를 넓힌 게 아니라, 감쌀 이유를 없앤 것이다. 파이프를 붙이고 싶어지는 자리를 전부 스크립트 안으로 옮겼다.

그리고 새로 만든 스크립트를 허용 목록에 넣었다.

"Bash(node agent/fetch-site.mjs *)",

"Bash(node agent/sheet-write.mjs *)",

"Bash(node agent/sheet-list.mjs)",

"Bash(node agent/sheet-list.mjs *)"

⚠️ 문법 함정Bash(X *)뒤에 인자가 붙어야 매칭된다. node agent/sheet-list.mjs처럼 인자 없이 부르는 명령은 따로 한 줄을 더 넣어야 한다. 위에 비슷해 보이는 두 줄이 나란히 있는 게 그 이유다.


시도 ③ — 그런데 또 떴다 (내 습관이 문제였다)

②를 다 해놓고도 팝업이 또 떴다. 회사 5곳을 한 번에 처리하면서 이렇게 묶었기 때문이다.

for f in curexo kctech ...; do node agent/sheet-write.mjs --append $S/$f-values.json; done

승인창에 낯선 문구가 떴다 — Contains simple_expansion.

금지 대상이 파이프만이 아니었다. 세 가지 전부였다.

쓰면 막히는 것

예시

파이프

명령 | head, 명령 | grep

반복문

for f in ...; do ... done

셸 변수

$S/$f-values.json

그래서 규칙을 이렇게 바꿨다.

회사가 10곳이면 명령을 10줄로 따로 부른다. 경로는 변수 없이 전체 경로를 그대로 적는다.

5줄, 10줄이 지저분해 보여도 그게 승인 0회를 지키는 유일한 방법이었다.

부끄러운 기록도 하나 남는다. 오전에 이 교훈을 메모까지 해놓고, 오후에 같은 실수를 또 했다. 심지어 "승인 0회 달성"이라고 잘못 보고했다가 스크린샷으로 정정당했다. 습관은 메모 한 줄로 안 바뀐다.


시도 ④ — 조용한데 뚫려 있던 구멍

팝업이 안 뜨게 된 뒤 전수 점검을 하다가 이걸 발견했다.

"Bash(gws sheets *)"     // 모든 시트 명령이 무승인 통과 — 다른 시트에 쓰는 것까지

승인은 안 떴다. 하지만 "우리 시트에만 쓴다"는 울타리가 이미 뚫려 있었다. 전용 스크립트를 만들어 시트를 제한해뒀는데, 이 규칙 한 줄이 그 옆으로 지나가는 샛길이었다.

"Bash(gws sheets +read *)"   // 읽기만 허용. 쓰기·삭제·생성은 전부 차단

로 좁혔다. 이제 시트에 쓰는 길은 전용 스크립트 하나뿐이다.

승인이 안 뜬다고 안전한 게 아니다. 조용한 것과 안전한 것은 다르다.


After — 승인 0회

회사 4곳(자이언트스텝·엘오티베큠·효성중공업·HD현대일렉트릭)을 조사해서 시트에 기록하는 전 과정에서 팝업이 한 번도 안 떴다. 직접 확인했다.

Before

After

회사 1곳당 승인

여러 번

0회

회사가 늘어나면

승인도 비례해서 늘어남

안 늘어남

사람이 있어야 하나

계속 앉아 있어야 함

자리를 떠도 됨

마지막 줄이 제일 중요하다. 이게 되니까 매일 정오에 알아서 회사 10곳을 조사하는 예약 실행을 걸 수 있었다. 승인이 한 번이라도 뜨면 거기서 멈춰버리니까, 0이 아니면 애초에 불가능한 일이었다.


가져가서 쓸 체크리스트

자동화가 자꾸 멈춘다면 이 순서로 점검해보세요.

  • 미완료명령에 파이프(|)를 붙이고 있지 않은가? → 출력이 지저분하면 파이프 말고 스크립트 안에서 정리하게 고치기

  • 미완료반복문(for ... done)으로 묶고 있지 않은가? → 개수만큼 명령을 따로 부르기

  • 미완료셸 변수($경로)를 쓰고 있지 않은가? → 전체 경로를 그대로 적기

  • 미완료사이트·파일마다 승인이 필요한 도구를 쓰고 있지 않은가? → 규칙 한 줄로 허용되는 전용 스크립트로 대체

  • 미완료인자 없이 부르는 명령이 있는가?Bash(명령) 규칙을 따로 한 줄 추가

  • 미완료넓게 허용해둔 규칙이 남아 있지 않은가? → 조용해도 뚫려 있을 수 있으니 좁히기


배운 것

허용 목록을 넓히는 건 답이 아니었다. 넓힐수록 팝업은 줄지 몰라도 울타리가 사라진다. 실제로 통한 건 반대 방향이었다 — 승인이 필요할 일 자체를 없애는 것.

그리고 순서가 있었다. 시도 ②가 8할, ③이 나머지다. 좋은 스크립트를 만들어놔도 그걸 for로 묶는 순간 원점이라, 도구를 고치는 것과 습관을 고치는 것이 둘 다 필요했다.

시도 ①만으로는 절대 0이 안 됐다는 게 이 이야기의 핵심이다. 처음 떠오른 방법이 가장 그럴듯했는데, 가장 오래 헤매게 만든 길이기도 했다.

밀어주고 끌어주는

온·오프라인 AI 스터디

AI로 어디까지 할 수 있는지
직접 확인하실 분만 신청하세요.