콘텐츠로 이동

채널 자율성 및 승인 정책

Telegram, Discord 등의 채널에서 도구 호출이 "비대화형 채널 승인 정책에 의해 거부됨" 오류를 받는 이유, 도구 승인 게이트와 경로 샌드박스 게이트의 차이점, 그리고 채널에서 에이전트가 워크플로를 생성하고 실행할 수 있도록 허용하는 방법입니다.

채널(Telegram, Discord, Slack 등)에서 Revka를 구동할 때, 도구 호출은 터미널에서보다 더 엄격한 정책 하에 실행됩니다. 에이전트가 다음과 같은 메시지를 보고하는 경우:

❌ Denied by non-interactive channel approval policy.

채널 승인 게이트에 걸린 것입니다. 이 페이지에서는 그 게이트가 무엇인지, 사람들이 가장 자주 혼동하는 두 가지 독립적인 정책 레이어, 하나의 비직관적인 함정(tool_search), 그리고 채널에서 에이전트가 워크플로를 생성하고 실행할 수 있도록 하는 정확한 구성을 설명합니다.

채널이 다른 이유: 대화형 vs 비대화형

섹션 제목: “채널이 다른 이유: 대화형 vs 비대화형”

Revka의 자율성 모델은 감독(supervised) 모드에서 사람이 위험한 도구 호출이 실행되기 전에 승인할 수 있다고 가정합니다.

인터페이스모드승인이 필요한 도구에서 발생하는 일
CLI대화형[Y]es / [N]o / [A]lways 프롬프트가 표시됨
채널 (Telegram, Discord, …)비대화형프롬프트를 확인할 운영자가 없으므로 호출이 자동 거부

따라서 채널에서 “승인 필요”는 사실상 “거부”를 의미합니다. 이는 안전 기본값으로, 무인 봇이 검토를 거쳐야 했을 부작용이 있는 동작을 자동으로 수행하는 것을 방지합니다.

두 가지 게이트 (혼동하지 마세요)

섹션 제목: “두 가지 게이트 (혼동하지 마세요)”

단일 파일 쓰기는 두 가지 독립적인 검사를 통과합니다. 실패 메시지와 수정 방법이 다릅니다:

  1. 도구 승인 게이트이 도구를 호출할 수 있는가? [autonomy] level, auto_approve, always_ask에 의해 구동됩니다. 실패 메시지: “Denied by non-interactive channel approval policy.”

  2. 경로 샌드박스파일 도구가 읽거나 쓸 수 있는 위치는 어디인가? [autonomy] workspace_only, allowed_roots, forbidden_paths에 의해 구동됩니다. 승인 게이트와 독립적으로 도구 내부에서 시행됩니다. 실패 메시지: “Path not allowed by security policy: …” 또는 “Resolved path escapes workspace allowlist: …” 와 같은 경로 오류. 쓰기 도구에 대한 읽기 전용 차단은 “Action blocked: autonomy is read-only” 로 표시됩니다.

중요한 결과: 완전히 허용된 경로에 쓰기를 해도 도구가 승인되지 않았다면 거부될 수 있습니다 — 그리고 승인된 도구도 샌드박스 외부의 경로는 거부될 수 있습니다. 잘못된 레이어를 수정하면 도움이 되지 않습니다.

채널에서 각 도구 호출에 대해 Revka는 순서대로 다음을 평가합니다:

  1. level = "full" → 승인이 필요 없습니다 (모든 것이 허용됨).
  2. level = "read_only" → 부작용이 있는 도구는 다운스트림에서 차단됩니다.
  3. **always_ask**에 "*" 또는 도구 이름이 포함됨 → 항상 승인 필요 → 채널에서 자동 거부 (아래 모든 항목보다 우선 적용).
  4. shell 도구 → 외부 게이트가 아닌 자체 명령 허용 목록 (allowed_commands / block_high_risk_commands)에 의해 관리됩니다.
  5. MCP 네임스페이스 도구 (이름에 __ 포함, 예: revka-operator__run_workflow, kumiho-memory__kumiho_memory_engage) → 채널에서 자동 승인.
  6. **auto_approve**에 "*" 또는 도구 이름이 포함됨 → 허용됨.
  7. 그 외 (supervised 기본값) → 승인 필요 → 채널에서 자동 거부.

핵심 요점: 단순 이름의 내장 도구

섹션 제목: “핵심 요점: 단순 이름의 내장 도구”

이 규칙(5단계 vs 7단계)이 대부분의 채널 문제의 핵심입니다:

  • 내장 도구는 단순 이름을 가집니다file_read, file_write, shell, tool_search, browser 등. 채널에서 자동 승인되지 않습니다. 기본 auto_approve 목록의 읽기 전용 도구들만 기본적으로 작동합니다; 그 외에는 명시적으로 추가해야 합니다.
  • MCP / 운영자 도구는 __로 네임스페이스가 지정됩니다 — 기본적으로 채널에서 자동 승인됩니다.

따라서 채널 워크플로를 활성화하려면 일반적으로 관련된 단순 이름의 내장 도구(tool_search, file_write)만 허용 목록에 추가하면 됩니다. 운영자 워크플로 도구 자체(revka-operator__create_workflow 등)는 이미 __ 규칙에 의해 허용됩니다.

Revka는 기본적으로 지연 도구 로딩을 사용합니다. 컨텍스트 창을 작게 유지하기 위해, 대부분의 운영자 및 MCP 도구는 처음부터 로드되지 않습니다 — 시스템 프롬프트에는 경량 스텁만 나열됩니다. 에이전트가 지연된 도구를 호출하기 전에, 먼저 내장 tool_search 도구를 호출하여 해당 도구의 전체 스키마를 가져와야 합니다.

tool_search단순 이름을 가지므로, 허용 목록에 추가하지 않으면 채널에서 자동 거부됩니다 — 그리고 모든 지연 도구의 게이트웨이이기 때문에, 에이전트가 create_workflowrun_workflow에 도달하기 전에 차단됩니다. 표시되는 거부 메시지는 tool_search에 대한 것이지만, 실제 요청은 워크플로에 관한 것이었습니다.

tool_search는 도구 스키마만 컨텍스트에 로드하며, 부작용이 없습니다. 또한 표시되는 모든 도구는 여전히 개별적으로 게이트됩니다. 자동 승인하는 것이 안전합니다.

레시피: 채널에서 워크플로 생성 및 실행

섹션 제목: “레시피: 채널에서 워크플로 생성 및 실행”

흐름에 필요한 단순 이름의 내장 도구를 [autonomy].auto_approve에 추가한 다음, 데몬을 재시작합니다 (구성은 시작 시 읽힘):

[autonomy]
level = "supervised"
auto_approve = [
# 읽기 전용 기본값 (유지)
"file_read", "web_search_tool", "web_fetch", "calculator",
"glob_search", "content_search", "image_info", "weather",
# 채널 기반 워크플로에 필요:
"tool_search", # 지연된 운영자/MCP 도구 활성화
"file_write", # 워크플로 YAML을 ~/.revka/workflows에 쓰기
# 선택 사항 — 이미 "__" 규칙에 의해 자동 승인되지만, 여기에
# 나열하면 이전 버전도 지원됨:
"create_workflow", "run_workflow", "get_workflow_status",
]
# 내장 기본값은 ~/.revka/workflows만 있습니다. 워크플로가
# workspace 디렉터리 외부에 쓰기가 필요한 경우 아티팩트/워크스페이스
# 루트를 명시적으로 추가하세요.
allowed_roots = ["~/.revka/workflows", "~/.revka/artifacts", "~/.revka/workspace"]
always_ask = [] # "*" 또는 워크플로 도구가 포함되어서는 안 됨

그러면 종단 간 채널 흐름이 완료됩니다:

tool_searchfile_write (YAML을 ~/.revka/workflows/에) → run_workflowget_workflow_status.

워크플로가 쓰는 위치와 경로가 이미 허용된 이유

섹션 제목: “워크플로가 쓰는 위치와 경로가 이미 허용된 이유”

~/.revka/workspaceworkspace_dir이므로, 경로 샌드박스가 자동으로 그곳에 쓰기를 허용합니다. ~/.revka/workflows는 내장 기본 allowed_roots유일한 항목입니다 — workspace_dir 외부에 있지만, allowed_roots에 있기 때문에 파일 도구가 거기에 쓸 수 있습니다. ~/.revka/artifacts는 기본 루트가 아닙니다: 워크플로가 직접 거기에 쓰기가 필요하다면 allowed_roots에 직접 추가하세요. 워크플로 쓰기가 (경로 메시지가 아닌) 승인 메시지로 실패한다면, 경로가 문제가 아닙니다; file_write 도구가 단순히 허용 목록에 추가되지 않은 것입니다.

경로 샌드박스는 level에 관계없이 파일 도구에 적용됩니다 — level = "full"이라도, 쓰기는 여전히 workspace_dir + allowed_roots로 제한되고 forbidden_paths 하에 차단됩니다. 자율성은 도구가 실행될지 여부를 제어하고; 샌드박스는 파일이 어디로 갈 수 있는지를 제어합니다.

실행 위치: 워크플로 실행은 채널 게이트를 받지 않음

섹션 제목: “실행 위치: 워크플로 실행은 채널 게이트를 받지 않음”

run_workflow워크플로 엔진에서 백그라운드 작업으로 실행을 시작하고 즉시 반환합니다. 워크플로의 내부 단계(에이전트 생성, 셸, 파일 단계 등)는 채팅 턴 중 에이전트의 직접 도구 호출을 관리하는 채널 승인 게이트가 아닌 워크플로 엔진에 의해 관리됩니다.

이 예외는 의도적입니다: human_approval 단계를 정의하는 워크플로는 채널에서 승인 요청 메시지에 응답하여 승인하도록 일시 중지합니다. 이것은 자율성 정책이 아닌 워크플로의 기능입니다.

접근 방식구성트레이드오프
표적형 (권장)level = "supervised" + 특정 도구만 허용 목록에 추가최소 권한; 실제로 필요한 경우에만 도구를 추가합니다. 경로 샌드박스가 여전히 모든 파일 쓰기를 제한합니다.
전체형level = "full"모든 채널 도구 호출에 승인 게이트 없음. 가장 간단하지만 가장 넓은 영향 범위. 단일 소유자, 신뢰할 수 있는 봇에게 합리적입니다. 파일 쓰기는 여전히 allowed_roots에 의해 샌드박스됩니다.

자율성 설정은 모든 비대화형 채널에 균일하게 적용됩니다. 현재 채널별 재정의가 없습니다 — 구성으로 Telegram에서는 도구를 자동 승인하면서 Discord에서는 계속 프롬프트를 표시하도록 할 수 없습니다. 채널별 세분성을 위해서는 코드 변경이 필요합니다.

  • “Denied by non-interactive channel approval policy” → 단순 이름의 도구가 허용 목록에 없습니다. 어떤 도구인지 확인하려면, [channels_config] show_tool_calls = true를 설정하고 ❌ <tool>: … 줄을 찾은 다음, <tool>auto_approve에 추가하세요.
  • “Path not allowed by security policy …” / “Resolved path escapes workspace allowlist …” / “Action blocked: autonomy is read-only” → 승인 게이트가 아닌 경로 샌드박스 또는 읽기 전용 게이트입니다. allowed_roots, workspace_only, 그리고 levelread_only가 아닌지 확인하세요.
  • 편집이 무시되는 것 같음 → 데몬을 재시작하세요; config.toml은 시작 시 읽힙니다.
  • always_ask"*"로 설정됨 → 이것은 auto_approve__ 규칙을 재정의하므로, 모든 것이 채널에서 거부됩니다. 제거하세요.
기본값효과
level"supervised"read_only | supervised | full. 채널에서 full은 절대 프롬프트를 표시하지 않고; supervised는 달리 허용되지 않은 모든 것을 자동 거부합니다.
auto_approve읽기 전용 도구 (file_read, web_search_tool, web_fetch, calculator, glob_search, content_search, image_info, weather)승인을 건너뛰는 도구. 사용자 항목은 기본값과 병합됩니다. "*"를 허용합니다.
always_ask[]항상 승인이 필요한 도구; auto_approve__ 규칙을 재정의합니다. 채널에서는 항상 거부됩니다. "*"를 허용합니다.
workspace_onlytrue파일 경로를 workspace_dir + allowed_roots로 제한합니다.
allowed_roots["~/.revka/workflows"]파일 도구가 워크스페이스 외부에서 읽고 쓸 수 있는 추가 루트.
forbidden_paths시스템 및 민감한 디렉터리워크스페이스/허용된 루트 외부의 경로에 대한 거부 목록. allowed_roots 항목 하의 경로는 우선 적용되어 허용됩니다.
allowed_commands선별된 실행 파일 목록shell 도구의 허용 목록.
block_high_risk_commandstruerm -rf, chmod 777, curl | sh와 같은 패턴을 강제 차단합니다.
require_approval_for_medium_risktrue중간 위험 셸 명령에 대한 승인 게이트.
non_cli_excluded_tools[]비CLI 채널에서 완전히 제거되는 도구 (보이지 않으며, 단순히 거부되지 않음).
max_actions_per_hour20정책별 시간당 작업 예산.
max_cost_per_day_cents500정책별 일일 지출 가드레일.