본문으로 건너뛰기
AICosmus

Where tech meets the everyday — AI, fintech, swimming, and cars.

AICosmus

Where tech meets the everyday — AI, fintech, swimming, and cars.

  • 홈
  • IT기술
    • RAG
    • GRPC
    • Kotlin
    • LLM
    • 금융 IT
    • 에이전트
    • 제로Trust
    • 자동화
  • About
    • Contact
    • Terms of Service
    • Disclaimer
    • Privacy – Policy
  • 홈
  • IT기술
    • RAG
    • GRPC
    • Kotlin
    • LLM
    • 금융 IT
    • 에이전트
    • 제로Trust
    • 자동화
  • About
    • Contact
    • Terms of Service
    • Disclaimer
    • Privacy – Policy
닫기

검색

opencode 권한 3단계 제어 패널 일러스트
IT기술

[opencode 시즌 2 심화 — 나만의 도메인 특화 에이전트 만들기] 4/12화: opencode 권한 설계 3단계 — allow·ask·deny로 에이전트 안전하게 만들기 (2026)

By AICosmus
2026년 08월 04일 13 Min Read
1

이 글은 「opencode 시즌 2 심화 — 나만의 도메인 특화 에이전트 만들기」 4일차로, opencode 권한 시스템의 핵심인 allow·ask·deny 3단계를 실전 중심으로 다룹니다.

시즌 1 8일차에서 opencode의 권한 승인 팝업을 처음 만났던 기억이 나시나요? 그때는 “Allow”를 누르면 되는구나, 정도로 넘어갔을 겁니다. 오늘은 그 권한 시스템을 직접 설계하는 법을 다룹니다.

어제 3일차에서 시스템 프롬프트로 에이전트의 정체성을 빚었습니다. 하지만 아무리 프롬프트를 정교하게 써도, 에이전트가 rm -rf /를 실행할 수 있다면 의미가 없죠. opencode 권한 설정은 에이전트의 행동 반경을 물리적으로 제한하는 울타리입니다. 프롬프트가 에이전트의 ‘성격’이라면, 권한은 에이전트의 ‘행동 한계’입니다.

오늘의 핵심 3가지

  • permission 3단계 — allow, ask, deny의 정확한 의미와 툴별 매트릭스 설계법
  • bash 패턴 기반 세분화 — "pnpm test*": "allow"처럼 명령어 패턴 단위로 권한을 조이는 실전 기법
  • 역할별 권한 프로파일 — read-only 리뷰어 vs write 구현 에이전트, 신뢰 환경 vs 규제 환경의 전략 차이
opencode 권한 allow ask deny 흐름도

opencode 권한 시스템 완전 해부

opencode의 권한 시스템은 단순하지만 강력합니다. 모든 툴 호출에 대해 세 가지 중 하나를 지정할 수 있고, 이 설정은 에이전트 단위로 독립 적용됩니다. opencode 공식 문서에서도 권한 설정을 에이전트 정의의 핵심 요소로 다루고 있습니다.

opencode 권한 3단계 — allow, ask, deny 완전 정리

opencode의 모든 툴 호출은 다음 세 가지 권한 레벨 중 하나로 제어됩니다.

  • allow — 사용자 확인 없이 자동 실행. 에이전트가 판단해서 바로 실행합니다. 속도가 빠르지만 위험한 명령도 그대로 통과합니다.
  • ask — 매번 사용자에게 확인을 요청. “이 명령을 실행해도 될까요?” 팝업이 뜹니다. 안전하지만 워크플로가 중단됩니다.
  • deny — 완전 차단. 에이전트가 해당 툴을 호출하려 해도 실행되지 않습니다. 존재 자체를 모르게 할 수 있습니다.

기본값은 ask입니다. 아무 설정도 하지 않으면 모든 툴 호출에 사용자 확인이 뜹니다. 이건 안전한 기본값이지만, 실무에서는 매번 “Allow”를 누르느라 흐름이 끊기죠.

핵심은 어디를 열고 어디를 잠글 것인가의 판단입니다. 이걸 체계적으로 하는 게 오늘의 주제입니다.

툴별 권한 매트릭스 설계

opencode가 제공하는 주요 내장 툴은 다음과 같습니다. 각 툴의 위험도를 이해해야 권한을 올바르게 설정할 수 있습니다.

툴 이름 기능 위험도 권장 기본값
read 파일 읽기 낮음 allow
glob 파일 패턴 검색 낮음 allow
grep 내용 검색 낮음 allow
write 파일 쓰기/생성 중간 ask
edit 파일 수정 중간 ask
bash 셸 명령 실행 높음 ask
fetch HTTP 요청 중간 ask

읽기 계열(read, glob, grep)은 시스템 상태를 변경하지 않으므로 거의 항상 allow로 두는 게 합리적입니다. 문제는 write, edit, bash입니다. 특히 bash는 사실상 무한한 행동 범위를 가지므로 가장 신중하게 다뤄야 합니다.

opencode.json에서 권한을 설정하는 기본 구조는 이렇습니다.

{
  "permission": {
    "allow": [
      "read",
      "glob",
      "grep"
    ],
    "deny": [
      "fetch"
    ]
  }
}

allow 배열에 넣은 툴은 자동 실행, deny에 넣은 툴은 완전 차단, 어디에도 넣지 않은 툴은 기본값 ask가 적용됩니다. 명시하지 않은 것은 ask — 이 규칙을 기억하세요.

bash 패턴 기반 세분화 — 명령어 단위로 잠그기

opencode 권한 설정에서 가장 강력한 기능은 bash 툴에 대한 패턴 기반 세분화입니다. bash를 통째로 allow하거나 deny하는 대신, 특정 명령어 패턴만 선택적으로 허용할 수 있습니다.

{
  "permission": {
    "allow": [
      "read",
      "glob",
      "grep",
      "bash(pnpm test*)",
      "bash(pnpm lint*)",
      "bash(pnpm build*)",
      "bash(git status)",
      "bash(git diff*)",
      "bash(git log*)"
    ],
    "deny": [
      "bash(rm *)",
      "bash(sudo *)",
      "bash(curl *)",
      "bash(wget *)",
      "bash(chmod *)",
      "bash(chown *)"
    ]
  }
}

패턴 문법은 글로브(glob) 패턴입니다. *는 와일드카드로, bash(pnpm test*)는 pnpm test, pnpm test:unit, pnpm test --coverage 등을 모두 매칭합니다.

패턴 우선순위 규칙

allow와 deny에 같은 도구가 있으면 어떻게 될까요? opencode는 더 구체적인 패턴이 우선합니다.

  • "bash(git *)"이 allow에 있고 "bash(git push --force*)"가 deny에 있으면 → git push --force만 차단, 나머지 git 명령은 허용
  • 패턴이 겹치지 않는 경우, deny가 allow보다 우선합니다 (안전 우선 원칙)
  • 어떤 패턴에도 매칭되지 않는 bash 명령은 ask로 폴백

이 우선순위를 활용하면 “기본적으로 물어보되, 안전한 명령은 자동 실행, 위험한 명령은 완전 차단”이라는 3단 방어를 구현할 수 있습니다.

bash 패턴 기반 권한 매칭 우선순위

실전 패턴 레시피

프로젝트 유형별로 자주 쓰는 bash 패턴 조합을 정리했습니다.

Node.js/TypeScript 프로젝트

"allow": [
  "bash(pnpm test*)",
  "bash(pnpm lint*)",
  "bash(pnpm build*)",
  "bash(pnpm typecheck*)",
  "bash(npx tsc --noEmit*)",
  "bash(git status)",
  "bash(git diff*)",
  "bash(git log*)",
  "bash(cat *)",
  "bash(ls *)",
  "bash(find *)"
]

Python 프로젝트

"allow": [
  "bash(pytest*)",
  "bash(ruff check*)",
  "bash(ruff format*)",
  "bash(mypy *)",
  "bash(python -m pytest*)",
  "bash(pip list*)",
  "bash(git status)",
  "bash(git diff*)",
  "bash(git log*)"
]

공통 deny 리스트 (모든 프로젝트에 권장)

"deny": [
  "bash(rm -rf *)",
  "bash(sudo *)",
  "bash(chmod 777*)",
  "bash(curl * | bash*)",
  "bash(wget * | bash*)",
  "bash(eval *)",
  "bash(git push --force*)",
  "bash(git reset --hard*)",
  "bash(DROP TABLE*)",
  "bash(DROP DATABASE*)"
]

이 deny 리스트는 안전 가드레일입니다. 에이전트가 실수로라도 위험한 명령을 실행하지 못하게 물리적으로 차단합니다. 프롬프트에 “rm -rf를 쓰지 마”라고 쓰는 것과는 차원이 다른 보호입니다.

에이전트 역할별 opencode 권한 프로파일 설계

3일차에서 시스템 프롬프트로 에이전트의 정체성을 정의했습니다. 이제 그 정체성에 맞는 권한 프로파일을 씌워야 합니다. 같은 코드베이스에서 일하더라도, 리뷰어와 구현자의 권한은 달라야 합니다.

read-only 리뷰어 에이전트

코드를 읽고 분석하고 피드백을 주지만, 직접 수정하지는 않는 에이전트입니다. 코드 리뷰, 보안 감사, 아키텍처 검토 등의 역할에 적합합니다.

.opencode/agents/reviewer.md 파일로 정의합니다.

---
name: Reviewer
description: 코드를 읽고 분석하여 리뷰 의견을 제시합니다. 코드를 직접 수정하지 않습니다.
model: anthropic/claude-sonnet-4-1
permission:
  allow:
    - read
    - glob
    - grep
    - bash(git log*)
    - bash(git diff*)
    - bash(git show*)
    - bash(git blame*)
    - bash(wc *)
    - bash(cat *)
  deny:
    - write
    - edit
    - bash(git commit*)
    - bash(git push*)
    - bash(git checkout*)
    - bash(rm *)
    - bash(mv *)
    - bash(cp *)
    - fetch
---

당신은 시니어 코드 리뷰어입니다.

## 역할
- 코드를 읽고, 분석하고, 개선점을 제안합니다.
- 직접 코드를 수정하지 않습니다. 수정이 필요하면 구체적인 제안을 텍스트로 전달합니다.

## 리뷰 체크리스트
1. 네이밍이 의도를 명확히 전달하는가?
2. 함수 길이가 30줄을 넘지 않는가?
3. 에러 핸들링이 누락된 경계가 있는가?
4. 테스트 커버리지가 충분한가?
5. 보안 취약점(인젝션, 하드코딩된 시크릿)이 있는가?

## 출력 형식
각 파일에 대해:
- ✅ 좋은 점
- ⚠️ 개선 제안 (우선순위: 높음/중간/낮음)
- 🔒 보안 이슈 (있을 경우)

핵심은 write와 edit를 deny로 설정한 것입니다. 이 에이전트는 아무리 노력해도 파일을 수정할 수 없습니다. 프롬프트에 “수정하지 마”라고 쓰는 것보다 훨씬 확실합니다.

또한 bash도 git log, git diff, git show, git blame 같은 읽기 전용 git 명령만 허용했습니다. git commit이나 git push는 deny입니다.

write 가능 구현 에이전트

실제로 코드를 작성하고 수정하는 에이전트입니다. 더 넓은 권한이 필요하지만, 여전히 위험한 작업은 제한합니다.

.opencode/agents/implementer.md

---
name: Implementer
description: 코드를 작성하고 수정합니다. 테스트를 실행하고 린트를 통과시킵니다.
model: anthropic/claude-opus-4-7
permission:
  allow:
    - read
    - glob
    - grep
    - write
    - edit
    - bash(pnpm test*)
    - bash(pnpm lint*)
    - bash(pnpm build*)
    - bash(pnpm typecheck*)
    - bash(git status)
    - bash(git diff*)
    - bash(git log*)
    - bash(git add *)
    - bash(git commit *)
    - bash(ls *)
    - bash(cat *)
    - bash(find *)
    - bash(mkdir *)
  deny:
    - bash(rm -rf *)
    - bash(sudo *)
    - bash(git push --force*)
    - bash(git reset --hard*)
    - bash(curl * | bash*)
    - bash(chmod 777*)
    - fetch
---

당신은 시니어 소프트웨어 엔지니어입니다.

## 역할
- 요구사항에 맞는 코드를 작성하고 수정합니다.
- 작성한 코드가 테스트와 린트를 통과하는지 직접 확인합니다.

## 코딩 원칙
1. 타입 안전성을 최우선으로 합니다.
2. 함수는 하나의 책임만 갖습니다.
3. 매직 넘버와 하드코딩을 피합니다.
4. 에러 메시지는 디버깅에 도움이 되도록 구체적으로 작성합니다.

## 작업 흐름
1. 관련 코드를 먼저 읽고 구조를 파악합니다.
2. 변경 사항을 구현합니다.
3. 테스트를 실행하여 회귀를 확인합니다.
4. 린트/타입체크를 통과시킵니다.
5. 변경 사항을 커밋합니다.

구현 에이전트는 write, edit이 allow이고, git add, git commit도 허용됩니다. 하지만 git push --force, rm -rf, sudo는 여전히 deny입니다. 생산적이면서도 안전한 균형점을 잡는 게 핵심입니다.

보안 감사 전용 에이전트

리뷰어보다 더 제한적인, 보안 감사 전용 에이전트도 만들 수 있습니다.

.opencode/agents/security-auditor.md

---
name: SecurityAuditor
description: 보안 취약점을 탐지하고 보고합니다. 코드 수정 권한이 없습니다.
model: anthropic/claude-opus-4-7
permission:
  allow:
    - read
    - glob
    - grep
    - bash(git log --all --oneline*)
    - bash(git diff*)
    - bash(cat *)
    - bash(find * -name "*.env*")
    - bash(find * -name "*.key*")
    - bash(find * -name "*.pem*")
  deny:
    - write
    - edit
    - bash(git commit*)
    - bash(git push*)
    - bash(rm *)
    - bash(mv *)
    - bash(cp *)
    - bash(curl *)
    - bash(wget *)
    - fetch
---

당신은 보안 감사 전문가입니다.

## 점검 항목
1. 하드코딩된 시크릿 (API 키, 비밀번호, 토큰)
2. SQL 인젝션 취약점
3. XSS / CSRF 취약점
4. 안전하지 않은 역직렬화
5. 과도한 권한의 IAM / 접근 제어
6. 의존성 취약점 (알려진 CVE)
7. 로그에 민감 정보 노출
8. 평문 통신 (HTTP, 미암호화 DB 연결)

## 보고 형식
- 🔴 Critical: 즉시 수정 필요
- 🟠 High: 릴리스 전 수정 필요
- 🟡 Medium: 계획적 수정 권장
- 🟢 Low: 개선 사항

이 에이전트는 .env, .key, .pem 파일을 찾을 수 있지만(find 허용), 그 파일을 수정하거나 외부로 전송할 수는 없습니다(write, fetch, curl 모두 deny). 탐지는 가능하되 유출은 불가능한 설계입니다.

역할별 opencode 권한 매트릭스 한눈에 보기

opencode 에이전트 역할별 권한 비교표
툴 / 명령 Reviewer Implementer SecurityAuditor
read ✅ allow ✅ allow ✅ allow
glob ✅ allow ✅ allow ✅ allow
grep ✅ allow ✅ allow ✅ allow
write 🚫 deny ✅ allow 🚫 deny
edit 🚫 deny ✅ allow 🚫 deny
bash(git diff*) ✅ allow ✅ allow ✅ allow
bash(git commit*) 🚫 deny ✅ allow 🚫 deny
bash(git push*) 🚫 deny 🤔 ask 🚫 deny
bash(pnpm test*) 🤔 ask ✅ allow 🚫 deny
bash(rm*) 🚫 deny 🚫 deny 🚫 deny
fetch 🚫 deny 🚫 deny 🚫 deny

이 매트릭스에서 주목할 점이 있습니다. fetch는 세 에이전트 모두 deny입니다. 에이전트가 외부 HTTP 요청을 보낼 수 있으면, 코드나 데이터를 외부로 유출할 잠재적 경로가 열립니다. MCP 서버를 통해 필요한 외부 통신을 통제된 방식으로 제공하는 게 더 안전합니다(이건 10일차에서 깊이 다룹니다).

신뢰 환경 vs 규제 환경 — 권한 전략이 달라진다

같은 opencode 에이전트라도, 어떤 환경에서 쓰느냐에 따라 권한 전략이 완전히 달라져야 합니다.

개인 프로젝트 / 스타트업 (신뢰 환경)

빠른 반복이 중요하고, 코드베이스에 민감 데이터가 적은 환경입니다.

{
  "permission": {
    "allow": [
      "read",
      "glob",
      "grep",
      "write",
      "edit",
      "bash(npm *)",
      "bash(pnpm *)",
      "bash(git *)",
      "bash(ls *)",
      "bash(cat *)",
      "bash(find *)",
      "bash(mkdir *)",
      "bash(python *)",
      "bash(node *)"
    ],
    "deny": [
      "bash(rm -rf /)",
      "bash(sudo rm *)",
      "bash(curl * | bash*)"
    ]
  }
}

신뢰 환경에서는 넓은 allow + 최소 deny 전략을 씁니다. 에이전트가 자유롭게 움직이되, 시스템을 파괴할 수 있는 극단적 명령만 차단합니다. 생산성이 최우선입니다.

이 환경의 특징:

  • 대부분의 bash 명령을 allow로 열어둠
  • write/edit도 자유롭게 허용
  • git push도 허용 가능 (본인 저장소이므로)
  • deny 목록은 ‘복구 불가능한 파괴’ 방지에만 집중

금융IT / 의료 / 공공 (규제 환경)

감사 추적이 필수이고, 데이터 유출이 법적 제재로 이어지는 환경입니다. OWASP Top 10 같은 보안 표준을 준수해야 하고, 모든 변경에 대한 로그가 남아야 합니다.

{
  "permission": {
    "allow": [
      "read",
      "glob",
      "grep"
    ],
    "deny": [
      "fetch",
      "bash(curl *)",
      "bash(wget *)",
      "bash(ssh *)",
      "bash(scp *)",
      "bash(nc *)",
      "bash(ncat *)",
      "bash(git push*)",
      "bash(git remote *)",
      "bash(npm publish*)",
      "bash(docker push*)",
      "bash(pip install *)",
      "bash(npm install *)",
      "bash(eval *)",
      "bash(base64 *)",
      "bash(openssl *)"
    ]
  }
}

규제 환경에서는 최소 allow + 광범위 deny 전략을 씁니다. 읽기만 자동 허용하고, 나머지는 모두 ask 또는 deny입니다.

특히 주의할 deny 항목들:

  • 네트워크 통신 전체 차단: fetch, curl, wget, ssh, scp, nc — 데이터가 외부로 나가는 모든 경로를 막습니다.
  • 패키지 설치 차단: pip install, npm install — 알 수 없는 패키지가 실행 환경에 들어오는 것을 방지합니다. 망분리 환경에서는 어차피 안 되지만, 이중 방어입니다.
  • 인코딩/암호화 도구 차단: base64, openssl — 데이터를 인코딩해서 우회 전송하는 것을 방지합니다.
  • 배포 차단: git push, npm publish, docker push — 코드가 승인 없이 외부 저장소에 올라가는 것을 막습니다.

규제 환경에서는 write와 edit도 deny가 아닌 ask(기본값)로 두는 게 좋습니다. 완전히 차단하면 에이전트가 아무것도 못 하고, 매번 확인을 받으면 감사 로그와 동일한 효과를 얻습니다. 사람이 매 변경을 승인한 기록이 남으니까요.

두 전략 비교 요약

항목 신뢰 환경 규제 환경
기본 철학 허용 후 예외 차단 차단 후 예외 허용
allow 범위 넓음 (읽기+쓰기+실행) 좁음 (읽기만)
deny 범위 좁음 (파괴적 명령만) 넓음 (네트워크+설치+배포)
ask 활용 최소 (흐름 우선) 적극 (감사 추적)
fetch 허용 ask로 허용 가능 deny 필수
git push allow 가능 deny 필수
패키지 설치 allow 가능 deny 필수
최적화 목표 생산성 통제와 추적

금융IT 실무 적용 — A 금융사의 에이전트 권한 설계

어떤 금융사에서 내부 코드 리뷰 자동화에 AI 에이전트를 도입한 사례가 있습니다. 규제 환경에서 에이전트 권한을 어떻게 설계했는지, 익명화하여 공유합니다.

상황: 개발팀 20명, 하루 PR 15~20건. 리뷰 병목이 릴리스 주기를 늦추고 있었습니다. AI 에이전트로 1차 리뷰를 자동화하되, 금융 감독원의 IT 감사 기준을 충족해야 했습니다.

핵심 요구사항:

  • 에이전트는 코드를 읽기만 할 수 있어야 한다 (수정 불가)
  • 에이전트가 외부 네트워크에 접촉하면 안 된다 (망분리 의무)
  • 모든 에이전트의 행동이 로그로 남아야 한다 (감사 대응)
  • 에이전트가 고객 데이터에 접근하면 안 된다 (개인정보보호)

설계 결과:

// .opencode/agents/compliance-reviewer.md의 핵심 권한 설정
---
name: ComplianceReviewer
description: 금융 규제 준수 여부를 검토하는 코드 리뷰어
model: anthropic/claude-sonnet-4-1
permission:
  allow:
    - read
    - glob
    - grep
    - bash(git log*)
    - bash(git diff*)
    - bash(git show*)
    - bash(wc *)
  deny:
    - write
    - edit
    - fetch
    - bash(curl *)
    - bash(wget *)
    - bash(ssh *)
    - bash(git push*)
    - bash(git commit*)
    - bash(pip *)
    - bash(npm *)
    - bash(cat *secret*)
    - bash(cat *credential*)
    - bash(cat *password*)
    - bash(cat *.env)
    - bash(cat *.key)
    - bash(cat *.pem)
    - bash(find * -name *.env*)
    - bash(grep -r password*)
    - bash(grep -r secret*)
    - bash(grep -r api_key*)
---

주목할 부분이 있습니다. cat *.env, cat *.key 같은 패턴을 deny에 넣었습니다. 보안 감사 에이전트는 이런 파일의 존재 여부를 찾을 수 있어야 하지만, 금융 규제 리뷰어는 내용 자체를 볼 필요가 없습니다. 역할에 따라 같은 파일 유형에 대한 접근이 달라지는 것이죠.

또한 grep -r password*, grep -r secret*도 deny입니다. 리뷰어가 “비밀번호가 하드코딩되어 있는지” 검색하면 그 과정에서 실제 비밀번호 값이 출력에 노출될 수 있기 때문입니다. 이 검사는 보안 감사 에이전트의 역할이며, 그 에이전트는 별도의 격리된 환경에서 동작합니다.

운영 결과:

  • 1차 리뷰 시간 60% 단축
  • 감사 시 “에이전트가 수정 권한이 없음”을 deny 설정으로 입증
  • 6개월 운영 중 데이터 유출 사고 0건

이 사례에서 가장 중요한 교훈은 “권한 설정이 곧 감사 증거”라는 점입니다. “프롬프트에 하지 말라고 썼습니다”는 감사관을 설득할 수 없지만, “시스템 레벨에서 차단되어 있어 물리적으로 불가능합니다”는 설득력이 있습니다.

에이전트 간 권한 격리 — opencode.json의 agent별 permission

opencode.json에서 에이전트별로 독립된 권한을 설정하는 전체 구조를 봅시다.

{
  "agent": {
    "primary": {
      "model": "anthropic/claude-sonnet-4-1",
      "permission": {
        "allow": ["read", "glob", "grep", "write", "edit"],
        "deny": ["fetch", "bash(rm -rf *)"]
      }
    }
  },
  "permission": {
    "allow": [
      "read",
      "glob",
      "grep",
      "bash(git status)",
      "bash(git diff*)"
    ],
    "deny": [
      "fetch",
      "bash(sudo *)",
      "bash(rm -rf *)"
    ]
  }
}

여기서 두 가지 레벨의 permission이 있습니다:

  • 최상위 permission: 모든 에이전트에 적용되는 기본 권한. Markdown으로 정의한 커스텀 에이전트가 자체 permission을 명시하지 않으면 이 기본값을 상속합니다.
  • agent.primary.permission: Primary 에이전트에만 적용되는 권한. 기본값을 덮어씁니다.

Markdown 에이전트(.opencode/agents/*.md)의 frontmatter에 있는 permission은 해당 에이전트 전용이며, 최상위 permission보다 우선합니다.

폴백 순서 정리

에이전트 자체 permission (가장 높은 우선순위)
  ↓ (없으면)
opencode.json 최상위 permission
  ↓ (없으면)
opencode 내장 기본값 (모든 툴 = ask)

이 구조 덕분에 “기본은 엄격하게, 특정 에이전트만 유연하게”라는 전략을 구현할 수 있습니다. 최상위 permission을 규제 환경 수준으로 빡빡하게 잠그고, 신뢰할 수 있는 Implementer 에이전트에만 write/edit을 여는 식입니다.

완성된 설정 파일 — 규제 환경용 opencode 프로젝트 구조

오늘 배운 내용을 모두 결합한 완성된 설정입니다. 규제 환경의 프로젝트에 바로 적용할 수 있습니다.

// opencode.json
{
  "default_agent": "reviewer",
  "agent": {
    "primary": {
      "model": "anthropic/claude-sonnet-4-1",
      "system_prompt": "{file:.opencode/prompts/primary.md}",
      "permission": {
        "allow": [
          "read", "glob", "grep",
          "write", "edit",
          "bash(pnpm test*)",
          "bash(pnpm lint*)",
          "bash(pnpm build*)",
          "bash(git status)",
          "bash(git diff*)",
          "bash(git log*)",
          "bash(git add *)",
          "bash(git commit *)"
        ],
        "deny": [
          "fetch",
          "bash(rm -rf *)",
          "bash(sudo *)",
          "bash(git push --force*)",
          "bash(git reset --hard*)",
          "bash(curl *)",
          "bash(wget *)",
          "bash(pip install *)",
          "bash(npm install *)",
          "bash(eval *)"
        ]
      }
    }
  },
  "permission": {
    "allow": [
      "read",
      "glob",
      "grep"
    ],
    "deny": [
      "fetch",
      "bash(curl *)",
      "bash(wget *)",
      "bash(ssh *)",
      "bash(sudo *)",
      "bash(rm -rf *)",
      "bash(eval *)",
      "bash(base64 *)",
      "bash(git push*)",
      "bash(npm publish*)",
      "bash(docker push*)"
    ]
  }
}

이 설정의 설계 의도:

  1. 기본 권한(최상위 permission)은 읽기만 allow, 네트워크·배포·파괴적 명령 전면 deny. 새로 추가되는 커스텀 에이전트는 자동으로 이 엄격한 기본값을 상속합니다.
  2. Primary 에이전트만 write/edit + 테스트/린트/커밋 권한을 갖습니다. 그래도 push는 ask(명시적으로 allow/deny 어디에도 없으므로 ask 폴백)이고, force push는 deny입니다.
  3. default_agent가 reviewer입니다. 팀원이 일반적인 대화를 시작하면 read-only 리뷰어가 응대합니다. 코드 수정이 필요할 때만 의식적으로 Primary나 Implementer로 전환해야 합니다. 안전한 기본값입니다.

이와 함께 .opencode/agents/ 디렉토리에 앞서 정의한 reviewer.md, implementer.md, security-auditor.md를 넣으면 됩니다. 각 에이전트의 frontmatter permission이 최상위 permission보다 우선하므로, 역할별 격리가 보장됩니다.

프로젝트 로컬 vs 글로벌 — 권한의 스코프

2일차에서 글로벌(~/.config/opencode/)과 프로젝트 로컬(.opencode/)의 스코프를 다뤘습니다. 권한도 같은 스코프 규칙을 따릅니다.

  • 글로벌 설정: 모든 프로젝트에 공통으로 적용하고 싶은 deny 리스트를 넣습니다. sudo, rm -rf /, curl | bash 같은 절대 금지 항목.
  • 프로젝트 로컬 설정: 해당 프로젝트의 기술 스택에 맞는 allow 리스트를 넣습니다. Python 프로젝트면 pytest, Node 프로젝트면 pnpm test.

폴백 순서: 프로젝트 로컬 > 글로벌 > 내장 기본값. 프로젝트 로컬이 있으면 글로벌을 덮어씁니다.

실무 권장 패턴:

// ~/.config/opencode/opencode.json (글로벌)
{
  "permission": {
    "deny": [
      "bash(sudo *)",
      "bash(rm -rf /)",
      "bash(curl * | bash*)",
      "bash(eval *)"
    ]
  }
}

// 프로젝트/.opencode/opencode.json (로컬)
{
  "permission": {
    "allow": [
      "read", "glob", "grep",
      "bash(pytest*)",
      "bash(ruff *)",
      "bash(mypy *)"
    ],
    "deny": [
      "fetch",
      "bash(pip install *)"
    ]
  }
}

글로벌 deny는 “어느 프로젝트에서든 절대 실행되면 안 되는 것”, 로컬 allow는 “이 프로젝트에서는 안전한 것”으로 분리하면 관리가 편합니다.

권한 변경의 투명성 — 팀 운영 관점

opencode의 권한 설정이 코드 파일(opencode.json, .opencode/agents/*.md)로 관리된다는 것은 큰 장점입니다. 이 파일들을 Git에 커밋하면:

  • 변경 추적: 누가 언제 어떤 권한을 열었는지 git log로 확인할 수 있습니다.
  • 코드 리뷰: 권한 변경을 PR로 올리면 팀이 리뷰할 수 있습니다. “bash(rm *)를 allow에 넣는 거 괜찮아?” 같은 논의가 가능합니다.
  • 롤백: 문제가 생기면 이전 커밋으로 권한을 되돌릴 수 있습니다.
  • 감사 증거: 규제 환경에서 “에이전트 권한을 어떻게 관리하고 있습니까?”에 대한 답이 Git 히스토리 자체입니다.

이것이 Infrastructure as Code의 에이전트 버전입니다. 권한을 UI에서 클릭으로 바꾸는 게 아니라, 코드로 선언하고 버전 관리하는 것. 팀 규모가 커질수록 이 방식의 가치는 기하급수적으로 올라갑니다.

Gotcha 미니 코너: bash 패턴의 함정

⚠️ bash 패턴에 공백이 포함된 명령어를 주의하세요.

다음 두 패턴은 비슷해 보이지만 다르게 동작합니다.

// 의도: git push만 차단
"deny": ["bash(git push*)"]

// 실수: git push 차단을 우회할 수 있음
// 에이전트가 "git  push" (공백 2개)를 시도하면 패턴에 매칭 안 됨

글로브 패턴은 문자열 매칭입니다. 셸이 명령어를 해석하는 방식과 다릅니다. 셸에서는 git push(공백 2개)와 git push(공백 1개)가 같은 결과를 내지만, 패턴 매칭에서는 별개의 문자열입니다.

더 안전한 방법:

// 여러 변형을 모두 deny에 넣기
"deny": [
  "bash(git push*)",
  "bash(git  push*)",
  "bash(*git push*)"    // 파이프나 세미콜론 앞에 오는 경우도 차단
]

또는 더 근본적으로, 정말 위험한 명령은 bash 자체를 deny하고 안전한 패턴만 allow하는 화이트리스트 방식이 낫습니다. 블랙리스트(deny)는 항상 우회 가능성이 있지만, 화이트리스트(allow)는 명시적으로 허용한 것만 통과합니다.

// 화이트리스트 방식 (더 안전)
"allow": [
  "bash(git status)",
  "bash(git diff*)",
  "bash(git log*)"
],
"deny": [
  "bash"    // 위 allow에 매칭되지 않는 모든 bash 명령 차단
]

규제 환경에서는 화이트리스트 방식을 강력히 권장합니다.

권한 설계 체크리스트

새 프로젝트에서 opencode 권한을 설정할 때 순서대로 따라가면 좋은 체크리스트입니다.

  1. 환경 분류: 이 프로젝트는 신뢰 환경인가, 규제 환경인가?
  2. 역할 정의: 몇 종류의 에이전트가 필요한가? (리뷰어, 구현자, 감사자…)
  3. 기본 권한 설정: 최상위 permission으로 가장 엄격한 기준선을 깔기
  4. 역할별 완화: 각 에이전트의 frontmatter에서 필요한 만큼만 allow 추가
  5. deny 리스트 점검: 파괴적·유출 가능 명령이 모두 차단되었는가?
  6. 패턴 검증: allow 패턴이 의도치 않은 명령까지 허용하지 않는가?
  7. Git 커밋: 설정 파일을 버전 관리에 포함
  8. 팀 리뷰: 권한 설정 PR을 팀이 한 번 검토

마무리 — 오늘 만든 것, 내일 추가할 것

오늘은 에이전트의 행동 한계를 물리적으로 설정했습니다. allow/ask/deny 3단계, bash 패턴 세분화, 역할별 권한 프로파일, 그리고 환경에 따른 전략 차이까지. 프롬프트가 에이전트의 “마음”이라면, 권한은 에이전트의 “울타리”입니다.

하지만 아직 한 가지가 빠져 있습니다. 세 에이전트가 모두 같은 모델을 쓸 필요는 없겠죠? 리뷰어는 빠르고 저렴한 모델로, 구현자는 가장 강력한 모델로 — 내일 5일차에서는 에이전트별 모델 라우팅으로 비용·속도·품질의 최적 균형을 잡는 법을 다룹니다.


📚 시리즈: opencode 시즌 2 심화 — 나만의 도메인 특화 에이전트 만들기 (총 12화 중 4화)
◀ 이전 3화  (다음 차수는 아직 게시되지 않았습니다)

자주 묻는 질문

opencode 권한 설정에서 allow, ask, deny의 차이점은 무엇인가요?

allow는 사용자 확인 없이 에이전트가 자동으로 실행하는 권한이고, ask는 매번 사용자에게 확인 팝업을 띄워 승인을 받는 권한이며, deny는 해당 툴 호출을 완전히 차단합니다. 아무 설정도 하지 않으면 기본값은 ask가 적용되어 모든 툴 호출에 사용자 확인이 필요합니다.

opencode에서 bash 명령어를 패턴별로 권한을 다르게 설정할 수 있나요?

네, bash 툴을 통째로 허용하거나 차단하는 대신 특정 명령어 패턴만 선택적으로 허용할 수 있습니다. 예를 들어 “bash(pnpm test*)”처럼 패턴을 지정하면 pnpm test로 시작하는 명령만 자동 실행을 허용하고 나머지 bash 명령은 ask나 deny로 제어할 수 있습니다.

opencode 에이전트의 read, glob, grep 같은 읽기 툴은 어떤 권한으로 설정하는 게 좋나요?

read, glob, grep 같은 읽기 계열 툴은 시스템 상태를 변경하지 않으므로 거의 항상 allow로 설정하는 것이 합리적입니다. 반면 write, edit, bash처럼 시스템을 변경할 수 있는 툴은 위험도에 따라 ask나 deny로 설정하는 것이 권장됩니다.



참고 자료

  • Principle of least privilege — Wikipedia — 에이전트 권한 설계의 이론적 토대인 최소 권한 원칙을 설명하는 문서
  • opencode Permissions Configuration — opencode 공식 문서 — allow·ask·deny 설정 방법과 툴별 권한 구성을 다루는 공식 레퍼런스

Tags:

AI 에이전트 권한 설계opencode permissionopencode 권한opencode 시즌 2 심화 — 나만의 도메인 특화 에이전트 만들기-4화금융IT 에이전트에이전트 보안연재:opencode 시즌 2 심화 — 나만의 도메인 특화 에이전트 만들기
작성자

AICosmus

Follow Me
다른 기사
AI 에이전트 상호운용 네트워크 일러스트
Previous

A2A 프로토콜 핵심 5가지, 에이전트 상호운용 실전 가이드

AI 작업 지시서와 프롬프트의 차이를 보여주는 일러스트
Next

[Claude 활용 24회 — AI에게 일을 위임하는 법] 4/24화: AI 작업 지시서 4요소 — 프롬프트 한 줄이 3시간을 태우는 이유

댓글 1개
  1. [opencode 시즌 2 심화 — 나만의 도메인 특화 에이전트 만들기] 5/12화: opencode 모델 라우팅 4단계 실전 가이드 2026 - AICosmus 댓글:
    2026년 08월 06일, 12:17 오전

    […] 시즌 2 심화 — 나만의 도메인 특화 에이전트 만들기 (총 12화 중 5화)◀ 이전 4화  (다음 차수는 아직 게시되지 […]

    답글

답글 남기기 응답 취소

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

최신 글

  • 디지털자산 뉴스 4선 — 2026년 9월 12일, 입법과 인프라가 동시에 다음 단계로 넘어가다
  • AI 트렌드 뉴스 5선 — 2026년 9월 11일, 자본과 규제가 같은 속도로 달린다
  • 디지털자산 뉴스 4선 — 2026년 9월 10일, 은행과 빅테크가 같은 날 스테이블코인 인프라를 가동하다
  • AI 트렌드 뉴스 4선 — 2026년 9월 둘째 주, 수학 난제부터 반도체 현장까지 AI가 증명을 시작했다
  • 디지털자산 뉴스 4선 — 2026년 9월 8일, $320M 해킹과 CBDC 실거래가 같은 주에 터지다

최신 댓글

  1. 디지털자산 뉴스 4선 — 2026년 9월 10일, 은행과 빅테크가 같은 날 스테이블코인 인프라를 가동하다의 디지털자산 뉴스 4선 — 2026년 9월 12일, 입법과 인프라가 동시에 다음 단계로 넘어가다 - AICosmus
  2. AI 트렌드 뉴스 5선 — 2026년 9월 11일, 자본과 규제가 같은 속도로 달린다의 디지털자산 뉴스 4선 — 2026년 9월 12일, 입법과 인프라가 동시에 다음 단계로 넘어가다 - AICosmus
  3. AI 트렌드 뉴스 4선 — 2026년 9월 둘째 주, 수학 난제부터 반도체 현장까지 AI가 증명을 시작했다의 AI 트렌드 뉴스 5선 — 2026년 9월 11일, 자본과 규제가 같은 속도로 달린다 - AICosmus
  4. 디지털자산 뉴스 4선 — 2026년 9월 8일, $320M 해킹과 CBDC 실거래가 같은 주에 터지다의 디지털자산 뉴스 4선 — 2026년 9월 10일, 은행과 빅테크가 같은 날 스테이블코인 인프라를 가동하다 - AICosmus
  5. 디지털자산 뉴스 4선 — 2026년 9월 10일, 은행과 빅테크가 같은 날 스테이블코인 인프라를 가동하다의 AI 트렌드 뉴스 5선 — 2026년 9월 11일, 자본과 규제가 같은 속도로 달린다 - AICosmus
  • About
  • Contact
  • Disclaimer
  • Privacy - Policy
  • Terms of Service
Copyright 2026 — AICosmus. All rights reserved. Blogsy WordPress Theme