AI 에이전트 워크플로 해킹 시도: GitHub 이슈를 제어 수단으로.
Source: Dev.to
나는 작은 공개 실험을 만들었다.
GitHub Issue를 열고 AI‑agent 워크플로에 내 웹사이트에 정적 페이지를 만들도록 요청할 수 있다.
요청이 규칙에 맞으면 워크플로가 페이지를 발행한다.
요청이 규칙에 맞지 않으면 에이전트가 이를 거부하고 이유를 설명한다.
그리고 실험을 더 흥미롭게 만들고 싶다면, 단순히 유효한 요청만 제출하지 말고 경계를 우회해 보라. 에이전트가 발행해서는 안 되는 무언가를 발행하도록 시도해 보고, 그 후 이슈 댓글, 라벨, 풀 리퀘스트, 최종 결과를 살펴보라.
이것이 게임이다.
하지만 그 게임 뒤에는 더 심각한 질문이 있다.
외부 사용자의 의도가 실제 제품 저장소에 들어가서 제품 소유권을 포기하지 않고도 제한되고 검토 가능한 제품 변경이 될 수 있는가?
그것을 탐구하고자 한다.
공개 놀이터는 여기다: Demo Pages
표면 규칙은 간단하다.
작은 정적 데모 페이지를 요청하는 GitHub Issue를 만든다.
워크플로는 이 이슈를 읽고, 요청이 허용된 영역에 속하는지 판단한 뒤, 필요한 에이전트 단계를 실행하고, 페이지를 생성·업데이트하고, 결과를 검증한 뒤, 프로세스가 성공하면만 발행한다.
하지만 이것은 공개 CMS가 아니다.
호스팅 서비스도 아니고, 웹사이트 빌더도 아니다.
외부 사용자가 내 홈페이지, 전역 레이아웃, 스타일, 스크립트, 제품 페이지, 사이트 구조 등을 바꿀 수 있는 곳도 아니다.
허용된 결과는 의도적으로 좁다: Demo Pages 섹션 아래에 있는 제한된 정적 페이지 하나.
따라서 도전 과제는 두 가지 측면을 가진다.
1. 정상 경로 시도
작은 데모 페이지 요청을 만들어 워크플로가 이를 발행된 정적 아티팩트로 바꿀 수 있는지 확인한다.
2. 적대적 경로 시도
경계 밖의 무언가를 요청하고 워크플로가 이를 차단하는지 확인한다.
예를 들어, 홈페이지 변경을 요청하거나, 이슈 본문에 명령을 삽입하거나, 전역 스타일 수정을 요구하거나, 금지된 동작을 생성된 콘텐츠에 몰래 넣어볼 수 있다.
주의: 도전은 의도된 경계 안에서만 진행한다. 이것은 워크플로와 프롬프트 경계 실험이지 인프라 공격이 아니다. 서버, 자격 증명, 네트워크, GitHub 자체, 가용성 등을 공격하지 말고, 오직 이슈 텍스트와 공개 저장소 워크플로만을 대상으로 한다.
흥미로운 질문은 서버가 깨지는가가 아니다.
흥미로운 질문은 AI 에이전트 체인이 제품 경계를 방어하면서도 유용한 위임 작업을 허용할 수 있는가이다.
워크플로는 증거를 남길 만큼 충분히 공개적으로 설계되었다.
요청은 사적인 챗봇으로 사라지지 않는다.
유용한 결과는 눈에 보이는 흔적을 남긴다:
- 원본 이슈
- 상태 전이를 설명하는 라벨
- 에이전트가 작성한 댓글
- 변경이 발생했을 때 생성되는 풀 리퀘스트
- 검증 증거
- 변경이 수락되면 발행되는 정적 페이지
페이지 자체는 주요 아티팩트가 아니다.
주요 아티팩트는 **추적(trace)**이다.
정적 페이지는 프로세스의 가시적인 끝일 뿐이며, 더 중요한 부분은 외부 요청이 통제된 제품 변경으로 이어지는 경로다.
워크플로가 요청을 수락하면 무슨 일이 일어났는지 살펴볼 수 있다.
워크플로가 요청을 거부하면 왜 거부했는지 확인할 수 있다.
성공적인 거부도 유용한 결과다.
일반 자동화에서는 거부가 실패처럼 보이지만, AI‑agent 워크플로에서는 올바른 거부가 프로세스에 경계가 있음을 증명한다. 이는 에이전트가 사용자의 명령을 무조건 수행하지 않고, 이슈를 신호(signal) 로서 다루었음을 의미한다.
그 차이는 중요하다.
AI 코딩 에이전트는 점점 더 좋은 코드를 생성한다.
하지만 코드 생성이 실제 제품에 에이전트를 적용할 때 가장 어려운 부분은 아니다.
더 어려운 문제는 제어(control) 이다.
- 누가 에이전트에게 작업을 허용했는가?
- 어떤 요청이 안전하다고 판단되었는가?
- 에이전트가 변경할 수 있는 파일은 무엇인가?
- 어떤 검증이 요구되었는가?
- 어떤 증거가 기록되었는가?
- 언제 에이전트가 멈추고 인간의 결정을 요구해야 하는가?
이 질문들에 답이 없으면 “자율 에이전트 개발”은 쉽게 통제되지 않은 프롬프트 놀이터가 된다.
데모용으로는 흥미로울 수 있지만, 나는 에이전트가 실제 제품에 개입하는 방식을 원하지 않는다.
제품 환경에서는 소유자가 통제를 잃어서는 안 된다.
사용자는 의도를 표현하고, 에이전트는 위임된 작업을 수행한다.
하지만 제품 소유자는 자율 작업이 허용되는 경로, 멈춰야 할 경계, 결과가 제품에 들어가기 전에 필요한 증거를 정의해야 한다.
이 실험은 정적 데모 페이지를 사용한다. 이는 안전하고, 가시적이며, 이해하기 쉬운 형태이기 때문이다.
하지만 진짜 주제는 정적 페이지 생성이 아니라 통제된 제품 진화다.
사용자가 이슈를 열면 워크플로는 요청이 승인된 경로에 속하는지 확인한다.
속한다면 에이전트가 처리하고, 속하지 않으면 요청을 거부·차단하거나 인간 검토로 라우팅한다.
이것이 내가 공개적으로 테스트하고 싶은 모델이다.
현재 실험은 GitHub Issue를 진입점으로 사용한다.
GitHub Issue는 친숙한 개발 아티팩트다. 요청을 설명하고, 토론을 모으며, 라벨을 받고, 이벤트를 트리거하고, 히스토리를 보존한다. 따라서 에이전트 기반 작업을 위한 실용적인 제어 표면이 된다.
간소화된 흐름은 다음과 같다:
- 이슈 생성 – 사용자가 요청을 남긴다.
- 신호 처리 – 워크플로는 이슈를 직접 발행 요청으로 보지 않는다. 대신 개발 신호로 간주한다.
- 규칙 적용 – 신호는 규칙을 통과해야 한다.
Demo Pages 실험에서는 허용 영역을 의도적으로 작게 잡았다. 에이전트는 문서화된 demo-page 경계 안에서만 작업할 수 있다. 독자 요청을 임의의 사이트 변경으로 전환해서는 안 된다.
이때 워크플로가 생성된 페이지보다 더 중요한 역할을 한다.
단일 프롬프트와 스크립트만으로 페이지를 만들 수 있는 간단한 데모는 여기서 목적이 아니다.
목적은 요청 수락 → 에이전트 실행 → 검증 → 풀 리퀘스트 생성 → 머지 → 발행이라는 관찰 가능한 단계들을 분리해서 보여주는 것이다.
경계는 모델에게 “제발 행동해 주세요”라고 말하는 것으로 보호되지 않는다. 그것만으로는 충분하지 않다. 워크플로는 여러 종류의 제어가 필요하다.
제어 요소
-
문서화된 범위
에이전트는 어떤 종류의 요청이 허용되는지, 저장소의 어느 부분을 변경할 수 있는지, 무엇은 건드리지 말아야 하는지를 알아야 한다. -
입학(Admission)
구현이 시작되기 전에 요청을 분류한다. 홈페이지, 전역 레이아웃, 스크립트, 스타일, 제품 콘텐츠 등을 목표로 하는 요청은 유효한 데모 페이지 요청으로 취급되지 않는다. -
제한된 실행
에이전트는 제한된 환경에서 동작하고, 직접 프로덕션을 변형하는 것이 아니라 저장소 변경을 통해 작업한다. -
검증
결과가 발행된 아티팩트가 되기 전에 반드시 검증한다. -
증거
라벨, 댓글, 풀 리퀘스트, 로그 등은 프로세스를 검사 가능하게 만든다. 증거가 없으면 자율성을 신뢰하기 어렵다.
이 때문에 나는 유효한 요청뿐 아니라 경계를 넘는 요청도 제출해 보길 권한다.
깨끗한 예시만 성공하는 워크플로는 별로 흥미롭지 않다.
워크플로가 “아니요, 이 요청은 승인된 경로 밖이며, 이유는 다음과 같습니다.”라고 말할 수 있을 때 비로소 유용해진다. 그 답변 자체가 제품 제어 모델의 일부가 된다.
이 실험은 아티팩트가 작아 보이기 때문에 작게 보인다. 정적 페이지는 큰 기능이 아니다. 하지만 패턴은 아티팩트보다 크다.
많은 팀이 이미 GitHub Issue, 풀 리퀘스트, CI 체크, 리뷰, 배포 파이프라인을 사용한다. AI 에이전트가 이 환경에 들어올 수 있지만, 단순 작업 프롬프트만으로는 부족하다. 프로세스 경계가 필요하다.
제품 팀은 코드 작성이 가능한 에이전트만 필요한 것이 아니다. 다음 질문에 답할 수 있는 방법이 필요하다.
- 어떤 요청을 위임할 수 있는가?
- 어떤 요청이 인간 검토를 필요로 하는가?