토큰 값을 노출하지 않아도 AI 에이전트가 작동하는 경우를 점검하다
요약
본 글은 AI 에이전트가 토큰 값 자체를 노출하지 않았음에도 불구하고, 인증된 명령어(예: publish, push)를 실행할 수 있는 상황을 점검한 기록입니다. 작성자는 절차서상의 분담 경계와 기술적으로 강제되는 경계를 구분하며, 단순히 '보이지 않게 하는 것'과 '사용하지 못하게 하는 것'의 차이를 강조합니다.
핵심 포인트
- 토큰 값 미노출만으로는 에이전트 실행을 막기 어려움.
- 절차서상의 분담은 문서일 뿐, 기술적 강제가 아님.
- 진정한 보안은 사용 자체를 원천적으로 차단하는 기술적 메커니즘 필요.
- 읽기 거부 규칙(Deny Rule)의 효과 범위에 대한 공식 문서를 검토함.
Claude Code의 에이전트에게 토큰 값 자체를 보여주지 않았음에도 불구하고, 인증된 명령어는 실행될 수 있습니다. 분담표로 정한 경계와 기술적으로 강제되는 경계 사이의 차이점, 공식 문서 원문, 그리고 제가 노출하지 않았다고 말할 수 있는 범위를 필자의 게시 환경 메타데이터를 통해 점검했습니다.
토큰을 전달하지 않아도 AI는 공개할 수 있었다
필자의 게시 환경에서는 에이전트에게 토큰 값을 전달하지 않았음에도 불구하고, 에이전트가 기사를 공개할 수 있는 장면이 있었습니다.
분담표상 금지였던 작업을 명시적인 Go로 실행했다
Qiita에 게시하는 환경을 만들었던 날(2026-10-02), 작업 분담표를 절차서에 작성했습니다. 계정 생성/토큰 발급 및 입력, push, 그리고 공개 최종 판단은 제가 직접 수행합니다. 에이전트에게 맡기는 것은 기사 파일 정리나 공개 전 점검입니다. login, publish, pull, push는 시키지 않기로 했습니다. 절차서 시작 부분에는 토큰의 구체적인 값을 절차서와 에이전트와의 대화에서도 쓰지 않는다고 정했습니다.
다음 날인 10월 3일에 기사 공개 과정에서 경계가 무너졌습니다. 제한 공유로 확인을 마친 기사를 전체 공개로 전환하는 작업을, 제가 명시적으로 Go를 통해 지시하자 에이전트가 실행했습니다. 공개 명령어는 인증된 단말기에서 작동했으며, 토큰 값을 전달하지 않아도 통과했습니다. Zenn의 리포지토리에서도 에이전트가 commit과 push를 실행했습니다. Zenn의 공개(published: true의 push) 역시 제가 명시적으로 Go를 한 후에 에이전트가 실행했습니다.
값(Value)을 보이지 않게 하는 경계와 사용하지 못하게 하는 경계는 달랐다
두 가지 경계를 분리해서 생각할 필요가 있습니다. '보이지 않게 하는 경계'는 값을 에이전트의 눈에 닿지 않게 하는 것입니다. '사용하지 못하게 하는 경계'는 인증된 작업을 실행하지 못하게 하는 것을 의미합니다. 절차서 시작 부분의 방침은 전자에 해당했습니다. 후자는 분담표의 문구만으로 지키고 있었습니다.
본고는 사용하지 못하게 하는 경계가 단순히 절차로만 지켜지고 있던 부분을 점검한 기록입니다. .env나 gitleaks 같은 일반적인 비밀 정보 대책은 설명이 많아 다루지 않습니다.
분담표로 정한 경계와 기술적으로 강제되던 경계
절차서에서 정한 경계와 기술적으로 강제되던 경계를 나란히 놓고 점검했습니다.
절차서상 분담은 3가지로 나뉘어 있었다
절차서의 분담표를 세 가지 구분으로 정리합니다.
| 구분 | 내용 |
|---|---|
| 필자가 직접 수행하는 것 | 계정 생성/토큰 발급 및 입력, push, 공개 최종 판단 |
| ... | |
| 공개 전 점검에는 토큰 같은 문자열이 기사에 섞여 있지 않은지 확인하는 것도 포함했습니다. 분담표는 누가 무엇을 할지를 정한 문서일 뿐입니다. 실행할 수 있는지 여부를 결정하는 메커니즘은 아닙니다. |
기술적으로 강제되던 것은 일부에 불과했다
기술적인 강제를 필자의 환경 메타데이터로 확인했습니다(2026년 10월 7일). 인증 정보의 내용은 읽지 않았습니다.
| 항목 | 확인 결과 |
|---|---|
| 인증 정보 파일 | 툴 설정 디렉토리에 있으며, 권한은 소유자만 가짐 |
| ... | |
| 소유자만 갖는 권한은 다른 사용자로부터 보호하는 설정입니다. 에이전트가 필자와 같은 사용자로 실행하는 명령어에는 효력이 없습니다. 보이지 않게 하는 경계는 절차와 운영으로 지킬 수 있어도, 사용하지 못하게 하는 경계는 기술적으로 강제되지 않았습니다. |
공식 문서는 거부 규칙을 경계라고 부르지 않는다
거부 규칙(Deny Rule)을 넣으면 충분한지, 공식 문서 원문으로 확인했습니다.
거부 규칙이 효과가 있는 범위와 그렇지 않은 범위
권한 문서(확인일 2026년 10월 7일)에 따르면, 읽기 거부 규칙은 내장 파일 툴이 대상입니다. cat
・head
・tail
・sed
・tee
같은 읽기 명령어와 리다이렉트의 대상에도 적용됩니다. 반면, 파일 이름을 쓰지 않고 파일을 읽는 grep -r이나 임의의 서브 프로세스에는 효과가 없습니다.
Bash 규칙은 일반적으로 생성되는 형태에 일치할 뿐입니다. 프로그램을 감싸는 보안 경계(security boundary)가 아니라고 공식 문서는 적고 있습니다. 필자의 정리로는, 거부 규칙은 읽게 하지 않는 선을 보완하는 설정일 뿐입니다. 사용하지 못하게 하는 선을 보장하는 설정이라고 할 수는 없습니다.
분류기(Classifier)는 멈출 때도 있지만 보장은 아니다
auto mode에서는 분류기(classifier)가 위험한 행동을 멈춥니다. 멈추는 대상 중 하나가 인증 정보 탐색입니다. 에이전트가 2026년 10월 7일에 대화 기록에서 토큰 값이 있는지 확인하려고 시도하면서, 기록에서 인증 정보 문자열을 찾는 명령을 실행하려 했습니다. 분류기가 막은 것은 실행 직전이었습니다. 에이전트는 회피하지 않고, 확인을 저에게 맡겼습니다.
다만, 분류기는 보장이 아닙니다. Anthropic의 기사에서는 실제 '과도한' 행동 52건 중 누락률이 17%였다고 보고했습니다. auto mode 설정 문서에 따르면, 작업 중인 리포지토리로의 push는 기본 브랜치를 포함하여 기본적으로 허용된 작업입니다. 분류기가 막은 장면은 설계된 방어가 아니라, 멈춘 시점의 관찰에 그칩니다.
사용하지 못하게 하는 선을 긋는 수단은 보여주지 않는 수단과는 달랐다
인증 정보를 지키는 수단은 효과를 보는 선(線)마다 나뉘어 있었습니다.
수단마다 효과가 있는 선이 달랐다
1차 자료에서 확인할 수 있었던 수단을, 보여주지 않는 선과 사용하지 못하게 하는 선 중 어느 쪽에 효과가 있는지로 정리합니다. 효과를 보는 선의 판단은 필자의 추론입니다.
| 수단 | 보여주지 않는 선 | 사용하지 못하게 하는 선 |
|---|---|---|
| OS 키체인 및 Git 인증 헬퍼 | 효과 있음 (값을 설정 파일에 쓰지 않음) | 효과 없음 (인증되어 실행 가능) |
| ... | ||
| 어떤 수단도 한쪽 선에만 효과가 있거나, 효과를 보는 방식에 조건이 붙습니다. 사용하지 못하게 하는 선을 기술적으로 긋기 위해서는 권한을 제한하거나, 인증을 다른 경계에 두는 구성이 필요합니다. 개인의 로컬 환경에서는 후자를 도입하는 데 수고가 따를 것입니다. |
필자의 운영은 사람의 확인 절차로 지키는 선이었다
필자의 운영 방식은 기술적으로 강제하는 선이 아니라, 사람의 확인으로 지키는 선이었습니다. 공개하기 전에 차이점(diff)을 보여주고 명시적인 동의를 얻습니다. 최종 판단은 제가 결정하는 운영입니다. Zenn에서는 공개에 이르기 전에 초안 작성과 AI 리뷰 단계를 거칩니다.
에이전트가 인증된 작업을 실행할 수 있는 상태는 변하지 않았습니다. 바뀐 것은, 실행해도 되는지 여부의 판단을 사람의 확인에 둔 점입니다.
보여주지 않고 있다고 말할 수 있는 범위는 확인한 만큼이었다
보여주지 않는다고 하려면, 경로별(path-by-path) 확인이 필요합니다.
보여주지 않았음을 입증하려면 경로별 확인이 필요하다
토큰을 보여주지 않았다고 말하기에는, 프롬프트에 적지 않은 것만으로는 부족합니다. 값은 환경 변수, 자식 프로세스로의 상속, 로그, 셸 히스토리에도 나타날 가능성이 있습니다. OWASP의 시크릿 관리는 환경 변수가 일반적으로 모든 프로세스에서 보인다고 가정하므로, 다른 방법이 불가능한 경우를 제외하고는 권장하지 않습니다. 로그나 덤프에 포함될 수 있는 점도 언급합니다.
보여주지 않았다고 쓸 수 있는 것은, 경로별 확인이 완료된 후에입니다.
필자가 확인할 수 없었던 범위는 미확인으로 남겼다
필자의 확인 상황을 경로별로 표로 만듭니다.
| 경로 | 상황 |
|---|---|
| 저장소 유형 및 권한 | 확인 완료 (소유자 전용 권한 및 키체인) |
| ... | |
| 확인된 것은, 저장소의 유형과 권한뿐입니다. 본고는 토큰을 보여주지 않았다고 주장하지 않습니다. 값을 채팅이나 기록에 적지 않는 방침으로 운영해 온 범위를 씁니다. |
절차로 지키는 선은 사람의 주의에 의존한다
절차로 지키는 선의 한계를 마지막으로 정리했습니다.
사람의 확인에도 작성 방식에 따른 누락이 있다
사람의 확인을 기술적으로 보완할 방법도 있습니다. 공식 문서의 예시는 permissions.ask에 Bash(git push *)를 넣어, auto mode에서도 반드시 확인을 요청하도록 설정하는 것입니다. 다만, git -C <dir> push와 같은 다른 작성 방식은 멈추지 않는다고 쓰여 있습니다. 기술로 막는 설정에도 허점이 남아 있는 형태입니다.
저의 명시적인 동의(Go)는 차이점을 보는 사람의 주의에 의존합니다. 절차를 정해도, 지켜질 것이라는 보장은 없습니다.
시도한다면 인증된 명령어 목록 작성부터 시작하라
만능한 방법은 아니며, 기술로 강제하기 어려운 선을 사람의 확인으로 보완하는 방법으로 사용하고 있습니다.
시도한다면, 자신의 운영 방식에서 에이전트가 실행할 수 있는 인증된 명령어(push, publish, API 호출)를 1가지 목록화하십시오. 찾은 명령어는, 기술로 막을지, 아니면 사람의 확인 절차로 지킬지 결정합니다. 결정한 선을 실제로 작동하는 설정이나 절차에 적어두면, 점검이 가능합니다.
본고 작성에는 AI(Claude)를 활용했습니다. 기록과의 대조 및 공개 판단은 필자가 담당하고 있습니다.
Discussion

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