권한
권한 (Permissions)
어떤 도구가 자동으로 실행되고, 확인이 필요하며, 완전히 차단되는지 제어해요.
출처: 문서
본문
개요 (Overview)
권한은 도구 실행에 대한 세밀한 제어를 제공해요. 어느 도구를 자동 승인(묻지 않고 실행)할지, 어느 것이 사용자 확인을 요구하는지, 어느 것이 완전히 차단되는지 구성할 수 있어요.
Note 평가 순서 (Evaluation Order) 권한은 이 순서로 평가돼요: Deny → Allow → Ask. Deny 패턴이 우선하고, 그다음 allow 패턴, 나머지 다른 모든 것은 세션의 안전 모드(safety mode)로 넘어가요.
안전 모드 (Safety Modes)
모든 세션은 어떤 권한 규칙도 도구 호출과 일치하지 않을 때 무슨 일이 일어날지 결정하는 안전 모드로 실행돼요. 런타임은 각 호출을 safe(안전 목록에 있는 셸 명령 ls 나 git status, 또는 읽기 전용 주석이 있는 도구), destructive(rm -rf 같은 파괴적 셸 명령, 또는 파괴적 주석이 있는 도구), 또는 unknown 으로 라벨하며, 모드가 그 라벨에 따라 게이팅해요:
| Mode | safe | destructive | unknown |
|---|---|---|---|
| strict | ask | ask | ask |
| balanced | allow | ask | ask |
| restricted | allow | deny | deny |
| autonomous | allow | allow | allow |
strict는 읽기 전용 것을 포함해 모든 도구 호출에 프롬프트를 띄워요. 오직allow:규칙만 프롬프트를 침묵시켜요.balanced는 안전한 호출은 조용히 실행하고 다른 모든 것에 대해서는 물어요.restricted는 무인/헤드리스 실행을 위한 fail-closed 프로필이에요: 안전한 호출은 조용히 실행되고 다른 모든 것은 묻지 않고 거부돼요 — 모드의 폴백은 절대 프롬프트하지 않아요. 커스텀 규칙은 여전히 이겨요:allow:규칙이 destructive/unknown 호출을 승인할 수 있고,deny:규칙은 항상 차단하며, 세션 범위의ask:규칙은 여전히 프롬프트해요(preempt_yolo 훅도 마찬가지). Restricted는 원치 않는 도구 호출에 대한 심층 방어이지, 보안 경계는 아니에요 — 진짜 격리는 샌드박스 모드를 사용하세요.autonomous는 레거시--yolo동작이에요: 모든 것이 실행돼요. 오직deny:규칙, 세션 범위ask:규칙, preempt_yolo 훅만 여전히 게이팅해요.
모드는 --safety 플래그(docker-agent run --safety balanced ...), 세션 생성 시 safety_policy 필드(POST /api/sessions) 또는 세션 중(PATCH /api/sessions/:id/safety-policy), 또는 확인 프롬프트에서 직접 상향으로 선택해요(B 는 balanced, A 는 autonomous로 전환; restricted 폴백은 절대 프롬프트하지 않으므로 모드는 플래그/구성/API로만 선택돼요). 모드를 선택하지 않은 세션은 역사적 기본값을 유지해요: 읽기 전용 도구는 자동 승인, 나머지 다른 모든 것은 확인.
선언적 안전 기본값 (Declarative Safety Defaults)
안전 모드는 YAML에서 기본값으로도 선언할 수 있으며, 네 가지 범위에서요:
| Scope | Location | Owner |
|---|---|---|
| Alias | ~/.config/cagent/config.yaml의 aliases.<name>.safety (또는 docker agent alias add ... --safety <mode>) |
User |
| Global settings | ~/.config/cagent/config.yaml의 settings.safety |
User |
| Per-agent | 에이전트 YAML의 agents.<name>.safety |
Agent author |
| Config-wide | 에이전트 YAML의 runtime.safety |
Agent author |
# Agent YAML (author-declared defaults)
runtime:
safety: balanced # config-wide default for new sessions
agents:
root:
safety: strict # overrides runtime.safety for this agent
네 필드 모두 네 가지 표준 모드 — strict, balanced, restricted, autonomous(네, 작성자가 autonomous 를 선언할 수 있어요) — 만 받고, 다른 값은 필드 이름을 짓는 에러와 함께 로딩이 실패해요. 레거시 철자는 autonomous 의 별칭으로 남아 있어요: settings.YOLO, alias의 yolo 옵션, --yolo 플래그. 같은 범위에서 둘 다 설정되면 safety 가 레거시 YOLO / yolo 보다 이겨요.
새 루트 세션에 대해 이 순서의 첫 번째 소스가 이겨요:
- 명시적
--safety플래그 - 명시적
--yolo플래그 - alias
safety/yolo옵션 settings.safety/settings.YOLO(사용자 구성)- 선택된 에이전트의
agents.<name>.safety runtime.safety- 역사적 기본값 (읽기 전용 도구 자동 승인, 나머지 다른 것 확인)
세션 재개는 절대 기본값을 다시 적용하지 않아요: 해당 실행에 명시적 --safety 나 --yolo 플래그를 전달하지 않으면 저장된 모드가 유지돼요. 에이전트 전환, 핸드오프, 위임된 하위 에이전트 세션은 활성 세션의 모드를 리셋하지 않고 상속해요.
API를 통해(POST /api/sessions) safety_policy 없이 만든 세션은 첫 실행이 시작될 때 — 에이전트 구성이 로드되는 가장 이른 시점 — 작성자 선언 기본값(5–6)을 받아요. 첫 실행 전에 서버가 재시작하면 세션은 역사적 미설정 기본값(7)을 유지해요.
Warning 신뢰: 작성자 기본값은 결코 당신보다 우선하지 않아요.
runtime.safety와agents.<name>.safety는 에이전트의 작성자가 씁니다 — URL이나 OCI 레지스트리에서 풀한 구성일 수 있어요. 당신이 선호를 전혀 표현하지 않았을 때만 그 간극을 채워요: 어떤 사용자 소유 소스(CLI 플래그, alias 옵션, 사용자 설정)든 항상 우선하고, 재개된 세션은 저장된 모드를 유지해요. 그래도 작성자 기본값이autonomous라면 새 세션이 모든 도구 호출을 묻지 않고 실행한다는 뜻이에요 — 타사 구성을 실행 전에 검토하거나,settings.safety/--safety로 자신만의 바닥을 고정하세요.
커스텀 규칙은 항상 모드보다 이겨요, 한 가지 비대칭이 있어요: 에이전트 YAML(또는 전역 구성)에 쓰인 ask: 규칙은 에이전트 작성자 권고이고 사용자가 선택한 balanced / restricted / autonomous 모드에 양보하는 반면(restricted 아래에서는 프롬프트를 도입하기보다 모드의 allow-or-deny 판정으로 해결), 세션 레벨에서 부여된 ask: 규칙(대화형 "always ask" 결정, 세션 권한 API)은 항상 프롬프트해요.
권한 수준 (Permission Levels)
권한은 두 수준에서 정의할 수 있어요:
| Level | Location | Scope |
|---|---|---|
| Agent-level | 에이전트 YAML 구성 (permissions: 섹션) |
해당 특정 에이전트 구성에 적용 |
| Global (user-level) | settings.permissions 아래의 ~/.config/cagent/config.yaml |
실행하는 모든 에이전트에 적용 |
훅도 같은 사용자 구성 패턴을 따라요: 에이전트 레벨 훅은 agents.<name>.hooks 아래에 있고, 전역 훅은 settings.hooks 아래에 있어요. Hooks 참고.
두 수준 모두 같은 allow / ask / deny 패턴 구문을 사용해요. 둘 다 있을 때 시작 시 병합돼요 — 두 소스의 패턴이 단일 체커로 결합돼요. 자세한 내용은 Merging Behavior 참고.
에이전트 레벨 구성 (Agent-Level Configuration)
agents:
root:
model: openai/gpt-4o
description: Agent with permission controls
instruction: You are a helpful assistant.
permissions:
# Auto-approve these tools (no confirmation needed)
allow:
- "read_file"
- "read_*" # Glob patterns
- "shell:cmd=ls*" # With argument matching
# Always ask before running these tools, even if an allow pattern would match
ask:
- "shell:cmd=git push*"
- "write_file:path=/home/user/important/*"
# Block these tools entirely
deny:
- "shell:cmd=sudo*"
- "shell:cmd=rm*-rf*"
- "dangerous_tool"
세 목록은 deny → allow → ask 순서로 평가되므로, ask: 항목을 사용하면 그 외에는 허용된 도구 위에 확인 레이어를 추가할 수 있어요.
전역 권한 (Global Permissions)
전역 권한은 어떤 에이전트 구성을 실행하든 모든 에이전트에 걸쳐 규칙을 강제할 수 있게 해줘요. 사용자 구성 파일에 정의해요:
# ~/.config/cagent/config.yaml
settings:
permissions:
deny:
- "shell:cmd=sudo*"
- "shell:cmd=rm*-rf*"
allow:
- "read_*"
- "shell:cmd=ls*"
- "shell:cmd=cat*"
이것은 어디서든 적용되는 개인 안전 가드레일을 설정하는 데 유용해요 — 예를 들어 항상 sudo를 차단하거나, 각 에이전트 구성이 그 규칙을 포함하도록 의존하지 않고 항상 읽기 전용 도구를 자동 승인하는 것.
병합 동작 (Merging Behavior)
전역과 에이전트 레벨 권한이 모두 있을 때, 평가 전에 단일 패턴 집합으로 병합돼요. 병합은 다음과 같이 동작해요:
- 어느 소스의 Deny 패턴이든 도구를 차단해요. 전역 deny는 에이전트 레벨 allow로 재정의될 수 없고, 그 반대도 마찬가지예요.
- 어느 소스의 Allow 패턴이든 도구를 자동 승인해요(deny 패턴이 일치하지 않는 한).
- 어느 소스의 Ask 패턴이든 확인을 강제해요(deny나 allow 패턴이 일치하지 않는 한).
병합 후에도 평가 순서는 동일해요: Deny > Allow > Ask > default Ask.
Tip 예제: 전역 deny + 에이전트 allow 전역 구성이
shell:cmd=sudo*를 deny하고 에이전트 구성이shell:cmd=sudo apt update를 allow해도 deny가 이겨요. Deny 패턴은 소스와 무관하게 항상 우선해요.
패턴 구문 (Pattern Syntax)
권한은 선택적 인자 일치가 있는 glob 스타일 패턴을 지원해요:
단순 패턴 (Simple Patterns)
| Pattern | Matches |
|---|---|
shell |
shell 도구와 정확히 일치 |
read_* |
read_ 로 시작하는 모든 도구 |
github_* |
모든 GitHub MCP 도구 |
* |
모든 도구 |
인자 일치 (Argument Matching)
tool:arg=pattern 구문으로 인자 값을 기반으로 도구를 일치시킬 수 있어요:
permissions:
allow:
# Allow shell only when cmd starts with "ls" or "cat"
- "shell:cmd=ls*"
- "shell:cmd=cat*"
# Allow edit_file only in specific directory
- "edit_file:path=/home/user/safe/*"
deny:
# Block shell with sudo
- "shell:cmd=sudo*"
# Block writes to system directories
- "write_file:path=/etc/*"
- "write_file:path=/usr/*"
Note 인자 값 안의 콜론은 보존돼요. 인자 조건 사이의
:key=토큰 경계만 패턴을 분리해요 — 값 안에 나타나는 콜론은 일반 문자로 취급되고 새 조건을 시작하지 않아요. 인자-일치 패턴을 작성하기 전에 도구의 실제 인자 이름(그리고 문자열을 받는지 리스트를 받는지)을 확인하세요.
여러 인자 조건 (Multiple Argument Conditions)
콜론으로 여러 인자 조건을 연결해요. 모든 조건이 일치해야 해요:
permissions:
allow:
# Allow shell with ls in current directory
- "shell:cmd=ls*:cwd=."
deny:
# Block shell with rm -rf anywhere
- "shell:cmd=rm*:cmd=*-rf*"
Glob 패턴 규칙 (Glob Pattern Rules)
패턴은 일부 확장과 함께 filepath.Match 의미론을 따릅니다:
*— 공백 포함 어떤 문자 시퀀스와도 일치?— 단일 문자와 일치[abc]— 집합의 어떤 문자와도 일치[a-z]— 범위의 어떤 문자와도 일치
일치는 대소문자를 구분하지 않아요.
Tip 후행 와일드카드 (Trailing Wildcards)
sudo*같은 후행 와일드카드는 공백 포함 어떤 문자와도 일치하므로,sudo*는sudo rm -rf /와 일치해요.
결정 유형 (Decision Types)
| Decision | Behavior |
|---|---|
| Allow | 도구가 사용자 확인 없이 즉시 실행 |
| Ask | 도구가 실행되기 전에 사용자 확인 필요 (기본) |
| Deny | 도구가 차단되고 에이전트에 에러 반환 |
예제 (Examples)
읽기 전용 에이전트 (Read-Only Agent)
모든 읽기 작업 허용, 모든 쓰기 차단:
permissions:
allow:
- "read_file"
- "read_multiple_files"
- "list_directory"
- "directory_tree"
- "search_files_content"
deny:
- "write_file"
- "edit_file"
- "shell"
안전한 셸 에이전트 (Safe Shell Agent)
특정 안전 명령 허용, 위험한 명령 차단:
permissions:
allow:
- "shell:cmd=ls*"
- "shell:cmd=cat*"
- "shell:cmd=grep*"
- "shell:cmd=find*"
- "shell:cmd=head*"
- "shell:cmd=tail*"
- "shell:cmd=wc*"
deny:
- "shell:cmd=sudo*"
- "shell:cmd=rm*"
- "shell:cmd=mv*"
- "shell:cmd=chmod*"
- "shell:cmd=chown*"
MCP 도구 권한 (MCP Tool Permissions)
정규화된 이름으로 MCP 도구를 제어해요:
permissions:
allow:
# Allow all GitHub read operations
- "github_get_*"
- "github_list_*"
- "github_search_*"
deny:
# Block destructive GitHub operations
- "github_delete_*"
- "github_close_*"
훅과 결합 (Combining with Hooks)
권한은 훅과 함께 동작해요. 평가 순서는:
- preempt_yolo
pre_tool_use훅 실행 — 어떤 모드나 allow 규칙으로도 우회할 수 없는 보안 중요 검사 - deny 패턴 확인 — 일치하면 도구 차단
- allow 패턴 확인 — 일치하면 도구 자동 승인
- ask 패턴 확인 — 일치하면 기본
pre_tool_use레인을 건너뛰고 사용자에게 직접 프롬프트 - 규칙이 일치하지 않으면 호출의 안전 라벨에 안전 모드를 적용 — 자동 승인(또는
restricted아래에서는 거부)할 수 있음 - 모드가 "ask" 일 때
pre_tool_use훅 실행 — 훅이 allow, deny, ask할 수 있음 - 결정이 없으면 사용자에게 확인 요청
기본 레인 훅은 모드가 "ask"로 라우팅한 호출만 봐요; deny 결정이나 명시적 ask: 규칙을 재정의할 수 없어요.
Warning 보안 참고 (Security Note) 권한은 클라이언트 측에서 강제돼요. 우발적 작업을 막는 데는 도움이 되지만, 신뢰할 수 없는 에이전트에 대한 보안 경계로 의존해서는 안 돼요. 더 강한 격리는 샌드박스 모드를 사용하세요.