Cheondi
개발 · AI

Codex AI 하네스 엔지니어링 설계 4 — 권한 통제

AI 작업에서 읽기, 로컬 수정, 외부 반영을 분리하고 중단 조건을 명시한 권한 설계 기록입니다.

  • #ai
  • #codex
  • #permissions
  • #security
  • #guardrails

3편까지는 AI가 어떤 도구로 무엇을 확인할지 정리했다. 도구가 실제 시스템과 연결되기 시작하면 다음 문제는 권한이다. 코드를 읽는 명령과 서버를 재시작하는 명령이 같은 방식으로 실행돼서는 안 된다.

처음에는 위험한 명령만 막으면 된다고 생각했다. 실제로는 명령의 이름보다 대상과 시점이 중요했다. 같은 git push라도 개인 브랜치와 운영 브랜치의 영향이 다르고, 같은 SQL이라도 SELECTUPDATE는 복구 난도가 완전히 다르다.

권한을 세 단계로 나눈 기준

하네스에서는 작업을 영향에 따라 나눴다.

단계 대표 작업 기본 정책
관찰 파일 읽기, 검색, Git 이력, 읽기 전용 로그 목표 범위 안에서 허용
로컬 변경 코드와 문서 수정, 테스트, 로컬 빌드 변경 범위 확인 후 허용
외부 변경 푸시, 배포, 재시작, DB 쓰기, 외부 메시지 대상과 영향에 대한 명시적 승인

이 구조에서 중요한 점은 “AI를 믿는가”가 아니다. 실수했을 때 복구 비용이 큰 행동일수록 더 좁은 계약을 요구하는 것이다. 사람끼리 운영 작업을 할 때 변경 승인과 점검표를 두는 이유와 비슷하다.

명령이 아니라 효과에 대한 승인

“명령 실행을 허용할까요?”만 물으면 사용자는 무엇이 바뀌는지 판단하기 어렵다. 그래서 승인 요청에는 효과를 포함했다.

action: push
repository: example-client
source: feature/example
target: origin/feature/example
commit: abc1234
effect: 공개 원격 저장소에 커밋 1개 추가
rollback: 후속 revert 커밋
excluded:
  - force push
  - 다른 브랜치 변경

DB 작업이라면 대상 테이블, 조건, 예상 행 수, 백업과 검증 쿼리가 필요하다. 배포라면 대상 환경과 산출물 식별자, 재시작 여부가 필요하다. 승인 단위가 구체적이면 AI가 다른 작업까지 권한을 넓혀 해석하기 어렵다.

비밀정보를 컨텍스트에서 제거한 방식

AI에게 실제 로그와 설정을 보여 주면 분석은 쉬워진다. 대신 토큰, 계정, 내부 주소, 고객 데이터가 대화와 결과물에 섞일 수 있다. 그래서 입력 단계에서 구조만 남기고 값은 바꿨다.

{
  "endpoint": "https://api.example.com/v1/orders",
  "accountId": "ACCOUNT_EXAMPLE",
  "accessToken": "<REDACTED>",
  "requestId": "REQ-EXAMPLE-001",
  "amount": 100
}

단순히 별표로 지우는 것보다 의미가 남는 이름으로 바꾸는 편이 분석에 도움이 됐다. ACCOUNT_EXAMPLE은 계정 식별자라는 역할을 보존하고, 실제 값은 노출하지 않는다.

명령 인자에 비밀값을 직접 넣지 않는 것도 중요했다. 셸 기록과 작업 로그에 남기 때문이다. 필요한 경우 이미 승인된 자격 증명 저장소나 프로세스 환경을 이용하고, 결과에는 존재 여부만 남겼다.

쓰기 전에 확인한 작업공간 상태

AI가 코드를 정확히 고쳐도 사용자가 작업 중이던 파일을 덮으면 실패다. 따라서 첫 쓰기 전에는 브랜치와 변경 상태를 확인했다.

git status --short --branch
git diff --name-only

판단 규칙도 단순하게 유지했다.

깨끗한 작업공간
  -> 요청된 변경 시작

이번 작업에서 이미 만든 변경만 존재
  -> 범위를 확인하고 계속

소유자가 불명확한 변경 존재
  -> 수정 중단, 파일 목록 보고

자동으로 stash하거나 임시 커밋하는 방식은 피했다. 복구할 수 있다는 것과 사용자의 의도를 안다는 것은 다른 문제이기 때문이다.

중단 조건도 기능의 일부

하네스 초반에는 성공 조건만 적었다. 하지만 실제로 도움이 된 건 멈춰야 하는 조건이었다.

  • 대상 저장소나 브랜치가 둘 이상으로 해석되는 경우
  • 파일 밖 시스템에 쓰기가 발생하는 경우
  • 실제 고객 데이터가 필요한 경우
  • 테스트 실패가 이번 변경 때문인지 구분되지 않는 경우
  • 배포 산출물과 실행 중인 버전을 연결할 수 없는 경우
  • 동일한 외부 작업의 성공 여부가 불확실한 경우

특히 마지막 조건이 중요했다. 네트워크가 끊겨 응답을 받지 못했다고 같은 요청을 다시 보내면 결제나 배포 같은 작업은 중복될 수 있다. 이때는 실패로 단정하지 않고 UNCERTAIN 상태로 멈춘 뒤 외부 상태를 조회해야 한다.

샌드박스가 대신해 주지 못하는 판단

샌드박스와 승인 기능은 파일과 네트워크 접근을 제한하는 좋은 장치다. 하지만 기술적으로 허용된 명령이 업무적으로도 허용된다는 뜻은 아니다. 샌드박스가 저장소 안의 파일 수정을 허용해도, 사용자 소유 변경을 덮어도 된다는 의미는 아니다.

그래서 시스템 권한과 작업 권한을 분리해서 생각했다.

시스템 권한: 이 명령을 실행할 수 있는가
작업 권한: 이번 요청에서 이 효과가 승인됐는가

둘 다 통과해야 실제 행동으로 이어진다. 이중 경계가 생기자 AI 활용이 느려지기보다 오히려 재작업이 줄었다. 위험한 단계에서만 확인하고, 읽기와 로컬 검증은 끊기지 않고 이어갈 수 있었기 때문이다.


이전 글: Codex AI 하네스 엔지니어링 설계 3 — 도구 계약

다음 글: Codex AI 하네스 엔지니어링 설계 5 — 작업 분할

참고: OpenAI Codex의 샌드박스 안내