AI 에이전트의 Skill은 코드입니다. 문서처럼 검토하지 마세요.
요약
AI 코딩 에이전트의 'Skill(Markdown 파일)'이 단순 문서가 아닌 실행 가능한 코드로서 갖는 보안 위험성을 경고합니다. 기존의 diff 방식이나 해시 고정 방식의 한계를 지적하며, 에이전트의 역량 변화를 직관적으로 보여주는 '역량 델타(capability delta)' 검토 방식의 필요성을 제안합니다.
핵심 포인트
- Skill은 문서가 아닌 실행 가능한 코드처럼 취급되어야 함
- 기존 PR diff 방식은 Skill의 권한 변경을 식별하기 어려움
- 해시 고정은 변경 여부만 알려줄 뿐 변경 내용을 설명하지 못함
- 셸 명령어, 네트워크 호스트 등 역량 변화를 요약한 '역량 델타'가 필요함
AI 코딩 에이전트(AI coding agents) — Claude Code, Codex — 는 "Skill"을 삽입할 수 있게 해줍니다. Skill이란 에이전트에게 작업 수행 방법을 알려주는 Markdown 파일입니다. 에이전트는 이 Skill을 읽고 그에 따라 행동합니다. 기술된 셸 명령(shell commands)을 실행하고, 언급된 URL을 가져오며, 참조된 파일을 읽고 씁니다. 기능적으로 Skill은 에이전트가 당신을 대신하여 실행하는 코드입니다.
하지만 검토(review)할 때 그것은 코드처럼 보이지 않습니다. 문서(documentation)처럼 보입니다. 그리고 바로 그 불일치가 모든 문제입니다.
눈앞에 숨어 있는 괴리
여기 릴리스 노트(release notes) 작성을 돕는 Skill이 있습니다. 무해해 보입니다:
---
name: release-notes
allowed-tools: [Bash, Read]
...
이제 "improve release-notes formatting"이라는 제목의 풀 리퀘스트(pull request) 이후의 동일한 Skill을 보겠습니다:
---
name: release-notes
allowed-tools: [Bash, Read]
...
두 번째 PR은 90%가 실제 포맷팅 개선이며 단 한 줄이 추가되었습니다. GitHub의 diff(차이점) 내에서 그것은 코드 블록(fenced code block) 안에 위치하며, 주변의 산문(prose)과 동일한 색상으로 표시됩니다. 바쁜 PR을 훑어보는 검토자는 "포맷팅 도우미"라는 문구를 보고 승인합니다. 하지만 이제 이 Skill은 실행될 때마다 원격 스크립트를 셸(shell)로 파이프(pipe)합니다.
git diff는 자신의 역할을 다했습니다. 텍스트가 변경되었음을 보여주었으니까요. 다만 그것은 _역량 범위(capability surface)_가 변경되었다는 사실은 알려주지 못합니다. 즉, Skill이 "git 히스토리를 읽는 것"에서 "git 히스토리를 읽고 임의의 원격 코드를 실행하는 것"으로 변했다는 사실 말입니다.
해시 고정(Hash-pinning)은 _무언가_가 변했다는 것은 알려주지만, 무엇이 변했는지는 알려주지 않습니다
Skill 변조에 대한 일반적인 해결책은 해시(hash)를 고정(pin)하는 것입니다. 이는 변경 사항을 포착하지만, 해시는 이진적(binary)입니다. sha256:abc → sha256:def는 "이제 다르다"는 것을 의미할 뿐입니다. 이 "다름"이 오타를 수정한 것인지, 아니면 새로운 curl | bash 명령인지 알기 위해서는 여전히 보안 관점에서 전체 diff를 읽어야 합니다. 해시 고정은 업무를 옮길 뿐, 업무를 대신 해주지는 않습니다.
검토에 실제로 필요한 것: 역량 델타(capability delta)
검토를 위한 유용한 단위는 텍스트도 아니고 해시도 아닙니다. 그것은 Skill이 _할 수 있는 것_의 차이(delta)입니다:
- Shell commands (셸 명령어) —
curl,rm,bash가 나타났는가? - Network hosts (네트워크 호스트) — 도달 가능한 새로운 도메인이 있는가?
- File reads/writes (파일 읽기/쓰기) — 이제
.env파일을 건드리는가? 자신의 영역 밖의 파일을 쓰는가? - Granted tools (부여된 도구) — 작성자가
allowed-tools에 무엇을 추가했는가?
이를 사람이 5초 안에 읽을 수 있는 몇 줄의 텍스트로 렌더링하십시오 — 예: added shell_command: curl, added network_host: rn-helper.example.net — 그러면 묻혀 있던 라인이 더 이상 묻혀 있지 않게 됩니다.
익숙한 형태
우리는 이미 종속성(dependencies)에 대해 이 문제의 한 버전을 해결했습니다. package-lock.json은 당신이 승인한 것을 고정(pin)합니다. Dependabot은 변경 사항이 발생할 때 그 차이(delta)를 보여줍니다. PR(Pull Request) 리뷰는 사람이 이를 수락하거나 거절하는 단계입니다.
에이전트 행동에 이를 적용하면 다음과 같습니다: 승인된 능력 범위(capability surface)를 커밋하고, 모든 PR에서 (산문이 아닌) 능력의 차이(diff)를 비교하며, 새로운 능력을 수락하기 위해 기록된 사람의 승인을 요구하십시오. 승인은 리뷰어와 이유를 포함하여 git에 남아야 합니다 — 즉, 느낌(vibe)이 아닌 감사 추적(audit trail)이어야 합니다.
시도해 보세요
저는 이를 작은 오픈 소스 도구로 만들었습니다: 커밋된 skills.lock에 능력 범위를 기록하고, 능력의 차이(delta)를 PR 댓글로 게시하며, 누군가 승인할 때까지 드리프트(drift)를 차단하는 CLI + GitHub Action입니다 (GitHub Code Scanning을 위한 선택적 SARIF 출력 포함). Apache 2.0 라이선스입니다:
- 도구: https://github.com/skills-lock/skil-lock
- 실제 드리프트로 인해 차단된 라이브 PR: https://github.com/skills-lock/example-claude-code-skills/pull/1
만약 당신이 다른 사람들이 PR을 보낼 수 있는 저장소에 Claude Code나 Codex Skills를 배포한다면, 저는 진심으로 알고 싶습니다: 당신은 그것들을 코드로 리뷰하고 있습니까, 아니면 문서로 리뷰하고 있습니까?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기