C.W.K.
Stream
Lesson 01 of 05 · published

Permission 모드 실전

~14 min · permissions, permission-mode, safety

Level 0Observer
0 XP0/64 lessons0/13 achievements
0/150 XP to next level150 XP to go0% complete

네 모드, 실제로 하는 일

ClaudeAgentOptions의 permission_mode가 네 값 중 하나. 'default'가 side effect 가진 어떤 도구든 user한테 prompt. 'acceptEdits'가 Write/Edit 자동 승인하지만 Bash엔 여전히 prompt. 'bypassPermissions'가 모든 거 승인(trusted CI에만 사용). 'plan'이 에이전트를 dry-run 모드 — 실행 없이 plan만.

반대편에 누가 있는지로 픽

개발자가 키보드에서 매 prompt review 중이면 'acceptEdits'가 자주 옳은 tradeoff(파일 편집 flow, 셸은 여전히 묻기). 에이전트가 server 컨텍스트에 unattended run하면 custom permission handler 가진 'default'가 정책 자세. 'bypassPermissions'는 다른 곳에서 review 통과한 trusted CI runner용.

자기 permission handler 작성

모드 너머로 per-tool 결정하는 callback 공급 가능. Callback이 tool name, input, allow / deny / ask 신호 받음. cwkPippa setup이 chat-from-WebUI path에 custom handler 사용 — 아빠가 CLI TUI 통하지 않고 inline으로 위험 명령 승인.

원칙: Permission 자세는 보안 결정만큼 UX 결정. 실제로 루프에 누가 있는지에 매치.

Code

컨텍스트로 모드 선택·python
from claude_agent_sdk import ClaudeAgentOptions

# 인터랙티브 개발자 페어링 — 편집 silent 수락, 셸 묻기.
dev_options = ClaudeAgentOptions(
    cwd="/Users/me/repo",
    permission_mode="acceptEdits",
)

# 서버-측 자율 worker — 모든 거 묻기, 너 UI로 prompt route.
server_options = ClaudeAgentOptions(
    cwd="/srv/jobs",
    permission_mode="default",
    can_use_tool=permission_handler,  # 너 함수
)

# Sandboxed 컨테이너의 trusted CI — latency keep down 위해 bypass.
ci_options = ClaudeAgentOptions(
    cwd="/workspace",
    permission_mode="bypassPermissions",
    allowed_tools=["Read", "Edit", "Bash"],  # tool 셋 narrow
)

# Dry run 위한 plan-only 모드.
plan_options = ClaudeAgentOptions(
    cwd="/srv",
    permission_mode="plan",
)
Custom permission handler·python
from claude_agent_sdk import ClaudeAgentOptions, PermissionRequest, PermissionResult

DEMANDS_REVIEW = {"Bash", "Write"}

async def permission_handler(req: PermissionRequest) -> PermissionResult:
    if req.tool_name not in DEMANDS_REVIEW:
        return PermissionResult(behavior="allow")
    # 요청을 너 UI로 forward; user가 approve나 deny 클릭.
    decision = await ask_user_in_ui(req.tool_name, req.input)
    if decision == "approve":
        return PermissionResult(behavior="allow")
    return PermissionResult(behavior="deny", message="User denied via UI")

options = ClaudeAgentOptions(
    cwd="/srv",
    permission_mode="default",
    can_use_tool=permission_handler,
)

External links

Exercise

프로젝트의 Agent SDK 호출 하나 audit. 사용 중 permission_mode 식별, 그게 옳은 선택인 caller-fact 하나. 답이 'bypassPermissions copy-paste한 거'면 그게 fix할 버그.
Hint
런타임에 책임 인간이 누구인지 생각. 모드가 '이거 run해야?' 답 가능한 사람과 매치.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.